我正在编写一个C#程序,用于将点击从一个窗口发送到另一个窗口。我正在使用winapi中的SendMessage和PostMessage。 SendMessage适用于键盘事件,但当我尝试使用它发送鼠标事件时,它总是发送鼠标坐标0,0。我可以用spy ++验证应用程序正在接收事件但x和y是(0,0)并且app认为鼠标是屏幕外的NCHITTEST = NOTCLIENT。
代码如下:
PostMessage(appWin, (int)WMessages.WM_MOUSEMOVE, 0, MakeDword(300, 200));
将PostMessage声明为:
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
protected static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
appWin是窗口的句柄(用spy ++验证它接收事件)。 窗口根本没有控件。 我也尝试了多个宏MakeLParam,MakeDword,手工完成等等。 我正在使用Windows7。
我昨晚/今天早上大部分时间都在试图找到问题,但我无法做到。虽然在线有很多关于Post / SendMessage的帖子,但我只能找到一个类似问题出现并且没有答案的帖子。
总结问题: 有谁知道为什么SendMessage会向应用程序窗口发送正确的消息,而不是传递它的x和y坐标给定它总是通过(0,0)?
谢谢!
答案 0 :(得分:3)
我想我终于可以看到你的代码出了什么问题。
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
问题是long
在C#中是64位宽。在32位进程中,这是不正确的,因为这些参数应该是32位宽。我希望你在调试器运行时看到堆栈不平衡警告。
正确的声明是:
static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);
您绝对不需要切换到本机C ++代码即可使用它。
答案 1 :(得分:1)
我一直在尝试使用PostMessage / SendMessage注入鼠标输入,原因与emist相同。这里遗漏的一个重要问题是C#应用程序(或者只是WPF应用程序)需要在其应用程序清单中设置uiAccess=true标志。否则,永远不会真正发送消息。此外,还有Authenticode个障碍要允许这样做,而visual studio将拒绝运行调试,但您可以将调试器附加到正在运行的进程中。希望这可以帮助任何来这个线程的人。
答案 2 :(得分:0)
发布我自己的问题的答案,因为有人发表评论说可能无法做到这一点。
我不确定为什么它在C#中不起作用,可能是输入/转换问题,也许是它处理lparam的方式的问题。在任何情况下,我在c ++中编写相同的代码并使其成为一个DLL,所以现在我使用控制处理程序和输入从dll调用该函数,并将输入发送到适当的控件。通过c ++直接使用windows api可以正常工作。
感谢您的帮助。