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

发布于 2024-08-17 08:02:34 字数 828 浏览 4 评论 0原文

我正在尝试使用从 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 或类似的东西,那就太好了,但生活并不那么简单(而且我不会使用 unsafe代码)。我笨拙地尝试强迫编组器通过 Marshal.PtrToStructure() 给我一些东西,但我知道这从一开始就注定是注定的,因为 C 数组不是一个结构,而我试图使用的结构make 显然不是 blittable 的。

现在,我们让原始调用继续执行,然后进行额外的 WinAPI 调用来获取数组、格式化它,然后在状态栏重新绘制之前重新发送它。这运作良好,但还不够好。

有什么想法吗?

谢谢!

Tom

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

I'm trying to subclass an unmanaged statusbar window from my managed COM server using a class inherited from NativeWindow, and am running into a wall trying to make sense of how to properly marshal the contents of an lParam.

http://msdn.microsoft.com/en-us/library/bb760757%28VS.85%29.aspx says that the contents of this lParam is of type (LPARAM)(LPINT) aWidths, and that the contents of this variable is actually a "pointer to an integer array."

I can't figure out a way to marshal this correctly. The goal is to read the lParam, add our value to the array, and then send the new message via base.wndProc(ref m).

It'd be nice if I could just int[] array = (int[])m.*lParam or somesuch, but life isn't so simple (and I don't get to use unsafe code). I've clumsily tried to force the marshaller to give me something via Marshal.PtrToStructure() but knew this was doomed from the start as the C-array isn't a struct and the struct I tried to make is obviously not blittable.

Right now we are letting the original call go through and then making additional WinAPI calls to get the array, format it, and then resend it before the statusbar can repaint. This is working well, but not well enough.

Any ideas?

Thanks!

Tom

PS- I've had a lot of trouble grokking how lParams are used in C#, the documentation is quite confusing :-/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

云雾 2024-08-24 08:02:34

在“dtb”的评论之后,您可以从此SO条目借用一些代码。

您必须提供的 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);

Following the "dtb"'s comment, you can borrow some code from this SO entry.

The LPARAM you must supply is a pointer to the first element of the array. Then all you have to do is:

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文