PostMessage 和 SendMessage WM_SETCURSOR、WM_LBBUTTONDOWN/UP 等均发送 xPox0、yPos0
我正在编写一个 C# 程序来将点击从一个窗口发送到另一个窗口。我正在使用 winapi 中的 SendMessage 和 PostMessage。 SendMessage 对于键盘事件工作得很好,但是当我尝试使用它发送鼠标事件时,它总是发送鼠标坐标 0,0。我可以使用spy++ 验证应用程序正在接收事件,但 x 和 y 位于 (0,0) 并且应用程序认为鼠标位于屏幕外 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))?
谢谢!
I'm writing a C# program to send clicks from a window to another. I'm using SendMessage and PostMessage from the winapi. SendMessage works fine for keyboard events but when I try using it to send mouse events its always sending mouse coordinates 0,0. I can verify with spy++ that the application is receiving the events but the x and y are at (0,0) and the app thinks the mouse is offscreen NCHITTEST=NOTCLIENT.
The code is as follows:
PostMessage(appWin, (int)WMessages.WM_MOUSEMOVE, 0, MakeDword(300, 200));
Where PostMessage is declared as:
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)]
protected static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
Where appWin is the handle to the window(verified with spy++ that its receiving the events).
The window has no controls at all.
I've also tried multiple macros MakeLParam, MakeDword, done it by hand, etc.
I'm using Windows7.
I spent most of last night/this morning away trying to find the problem but I have not been able to. While there are many posts online regarding Post/SendMessage, I was only able to find one where the similar problem came up and there were no answers.
To summarize the problem:
Does anyone know why SendMessage would be sending the proper message to the application window but instead of passing it the x and y coordinates given its always passing (0,0)?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我一直在尝试使用 PostMessage/SendMessage 注入鼠标输入,原因与 emist 相同。这里遗漏的一个重要问题是 C# 应用程序(或者可能只是 WPF 应用程序)需要 uiAccess=true 标志在其应用程序清单中设置。否则,消息永远不会真正发送。此外,还有一个 Authenticode 要实现这一点需要克服一些障碍,Visual Studio 将拒绝运行调试,但您可以将调试器附加到正在运行的进程。希望这对通过该线程前来的任何人都有帮助。
I've been trying to inject mouse input with PostMessage/SendMessage, for the same reasons as emist. One important gotcha that has been left out here is that C# applications (or maybe just WPF ones) require the uiAccess=true flag to be set in it's application manifest. Otherwise, messages are never really sent. Also, there are a Authenticode hurdles to go through to allow this, and visual studio will refuse to run the debug, but you can attach the debugger to a running process. Hope this helps anyone who come's by this thread.
我想我终于可以看到你的代码有什么问题了。
问题是 C# 中的
long
是 64 位宽。在 32 位进程中,这是不正确的,因为这些参数应该是 32 位宽。我本以为您在运行调试器时会看到堆栈不平衡警告。正确的声明是:
您绝对不需要切换到本机 C++ 代码来使其工作。
I think I can finally see what's wrong with your code.
The issue is that
long
is 64 bits wide in C#. In a 32 bit process this is incorrect since those parameters should be 32 bits wide. I would have expected you to have seen a stack imbalance warning when run through the debugger.The correct declaration is:
You most definitely don't need to switch to native C++ code to get this to work.
发布我自己问题的答案,因为有人评论说这可能是不可能做到的。
我不确定为什么它在 C# 中不起作用,可能是打字/转换问题,也可能是处理 lparam 的方式问题。无论如何,我用 c++ 编写了相同的代码并将其制作为 dll,因此现在我使用控件处理程序和输入从 dll 调用该函数,并将输入发送到正确的控件。直接通过 c++ 使用 windows api 效果很好。
感谢您的帮助。
Posting the answer to my own question because there were comments made to the effect that it might be impossible to do.
Im not sure why it doesn't work in C#, maybe a typing/casting issue, maybe an issue with the way it handles the lparam. In any case, I wrote the same code in c++ and made it a dll so now I call the function from the dll with the control handler and the input and it sends the input to the proper controls. Using the windows api directly through c++ works fine.
Thanks for the help.