1

我正在编写一个 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)?

谢谢!

4

3 回答 3

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++ 代码即可使其正常工作。

于 2011-07-07T08:16:35.967 回答
0

发布我自己问题的答案,因为有人发表了可能无法做到的评论。

我不确定为什么它在 C# 中不起作用,可能是打字/转换问题,可能是它处理 lparam 的方式的问题。在任何情况下,我在 C++ 中编写了相同的代码并将其设为 dll,所以现在我使用控制处理程序和输入从 dll 调用函数,并将输入发送到适当的控件。直接通过 c++ 使用 windows api 工作正常。

谢谢您的帮助。

于 2011-07-07T08:10:29.903 回答
0

我一直在尝试使用 PostMessage/SendMessage 注入鼠标输入,原因与 emist 相同。这里遗漏的一个重要问题是 C# 应用程序(或者可能只是 WPF 应用程序)需要在其应用程序清单中设置uiAccess=true标志。否则,消息永远不会真正发送。此外,还有一个Authenticode障碍需要通过,Visual Studio 将拒绝运行调试,但您可以将调试器附加到正在运行的进程。希望这可以帮助任何通过这个线程来的人。

于 2012-02-20T20:04:13.043 回答