C#:从SendMessage()lParam编组“指向int数组的指针”

时间:2010-01-08 08:11:24

标签: c# api pinvoke marshalling subclassing

我正在尝试使用从NativeWindow继承的类从我的托管COM服务器子类化一个非托管状态栏窗口,并且正在试图弄清楚如何正确封送lParam的内容。

http://msdn.microsoft.com/en-us/library/bb760757%28VS.85%29.aspx表示此lParam的内容类型为(LPARAM)(LPINT) aWidths,并且此变量的内容实际上是“指向整数数组的指针。”

我无法想出一种正确编组的方法。目标是读取lParam,将我们的值添加到数组,然后通过base.wndProc(ref m)发送新消息。

如果我可以int[] array = (int[])m.*lParam或者某些人,那就太好了,但生活并不那么简单(而且我不会使用不安全的代码)。我笨拙地试图强迫marshaller通过Marshal.PtrToStructure()给我一些东西,但是知道这从一开始就注定了,因为C数组不是一个结构体,而我试图制作的结构显然不是blittable。 / p>

现在我们让原始调用通过,然后进行额外的WinAPI调用以获取数组,格式化它,然后在状态栏重绘之前重新发送它。这很好用,但还不够好。

有什么想法吗?

谢谢!

汤姆

PS-我在C#中如何使用lParams时遇到了很多麻烦,文档很混乱: - /

1 个答案:

答案 0 :(得分:2)

根据“dtb”的评论,您可以借用此SO entry中的一些代码。

您必须提供的LPARAM是指向数组第一个元素的指针。然后你所要做的就是:

int[] parts = new int[]{ 1, 2, 3, 4 };
int nParts = parts.Length;
IntPtr pointer = Marshal.AllocHGlobal(nParts * Marshal.SizeOf(typeof(int)));
for (int i = 0; i < nParts; i++) {
    Marshal.WriteInt32(pointer, i * Marshal.SizeOf(typeof(int), parts[i]));
}
// Call SendMessage with WPARAM = nParts and LPARAM = Pointer
Marshal.FreeHGlobal(pointer);
相关问题