1

我对各种声明 SendMessage 感到困惑。我怎么知道哪一个是正确的?

在我的 c# winforms 应用程序(Windows 7)中,我使用以下内容;

public class NativeMethods
{
    [DllImport("user32.dll")]
    // Currently uses 
    public static extern int SendMessage(IntPtr hWnd, uint wMsg, int wParam, int lParam);
    // Think I should probably be using 
    // public static extern int SendMessage(IntPtr hWnd, uint wMsg, UIntPtr wParam, IntPtr lParam);
}

但调用 SendMessage 的代码是

 NativeMethods.SendMessage(this.tv.Handle, 277, 1, 0);

如何确定要使用哪些参数以便切换到另一个声明?

4

2 回答 2

8

查看头文件或 MSDN 文档,然后您需要进行一些推断。

在您的情况下,实际的 C 原型是:

LRESULT WINAPI SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);

相关的 typedef 是:

typedef unsigned int UINT;
typedef LONG_PTR LPARAM;
typedef UINT_PTR WPARAM;
typedef LONG_PTR LRESULT;

所以正确的 C# 声明应该是:

[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, uint wMsg, 
                                UIntPtr wParam, IntPtr lParam);

IntPtrand具有采用普通整数的UIntPtr构造函数,因此直接调用它没有问题:

NativeMethods.SendMessage(this.tv.Handle, 277, new UIntPtr(1), IntPtr.Zero);

实际上,只要您尊重每个参数的大小,一切都可以正常工作,但是如果您希望您的代码在 32 位和 64 位之间可移植,则必须小心。

于 2013-04-29T01:33:50.797 回答
1

克尔斯滕,这是一个互操作问题。大多数 C++ 示例为 SendMessage 的参数指定 int 或 uint;C# 解释值的方式并不重要,只要

  • 您传递的位模式是正确的
  • 尺寸正确
  • 编组是适当的

实际上这里有很多东西需要处理,对于堆栈溢出答案来说太多了。谷歌需要的词是“互操作”和“编组”。

您还应该注意,除非发件人具有提升的权限,否则您可能会在跨进程发送消息时遇到问题。并且 SendMessage 是同步的。你确定你不想要 PostMessage 吗?

于 2013-04-29T01:35:46.720 回答