C# PostMessage和SendMessage WM_SETCURSOR、WM_LBBUTTONDOWN/UP等都发送xPox0、yPos0

C# PostMessage和SendMessage WM_SETCURSOR、WM_LBBUTTONDOWN/UP等都发送xPox0、yPos0,c#,objective-c,winapi,postmessage,C#,Objective C,Winapi,Postmessage,我正在编写一个C#程序,将点击从一个窗口发送到另一个窗口。我正在使用winapi中的SendMessage和PostMessage。SendMessage适用于键盘事件,但当我尝试使用它发送鼠标事件时,它总是发送鼠标坐标0,0。我可以用spy++验证应用程序是否正在接收事件,但x和y位于(0,0),并且应用程序认为鼠标在屏幕外NCHITTEST=NOTCLIENT 代码如下: PostMessage(appWin, (int)WMessages.WM_MOUSEMOVE, 0, MakeDwor

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


谢谢

发布我自己问题的答案,因为有评论认为这可能是不可能的

我不知道为什么它不能在C#中工作,可能是键入/转换问题,可能是它处理LPRAM的方式问题。在任何情况下,我都用C++编写了相同的代码,并使之成为DLL,所以现在我从DLL中调用具有控制处理程序和输入的函数,并将输入发送到适当的控件。使用Windows API直接通过C++工作很好。p>
谢谢你的帮助。

发布我自己问题的答案,因为有评论认为这可能是不可能的

我不知道为什么它不能在C#中工作,可能是键入/转换问题,可能是它处理LPRAM的方式问题。在任何情况下,我都用C++编写了相同的代码,并使之成为DLL,所以现在我从DLL中调用具有控制处理程序和输入的函数,并将输入发送到适当的控件。使用Windows API直接通过C++工作很好。p>
谢谢你的帮助。

我想我终于可以看出你的代码有什么问题了

[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] 
static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
问题是C#中的
long
是64位宽。在32位进程中,这是不正确的,因为这些参数应为32位宽。我希望您在通过调试器运行时看到堆栈不平衡警告

正确的声明是:

static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);

你当然不需要切换到本机C++代码来工作。

< P>我想我终于可以看到你的代码有什么问题了。
[DllImport("user32.dll", EntryPoint = "PostMessageA", SetLastError = true)] 
static extern bool PostMessage(IntPtr hwnd, uint Msg, long wParam, long lParam);
问题是C#中的
long
是64位宽。在32位进程中,这是不正确的,因为这些参数应为32位宽。我希望您在通过调试器运行时看到堆栈不平衡警告

正确的声明是:

static extern bool PostMessage(IntPtr hwnd, uint Msg, IntPtr wParam, IntPtr lParam);

您绝对不需要切换到本地C++代码来执行这个操作。

< P>我一直试图用PasMe/SeN消息来注入鼠标输入,原因与EMIST相同。这里遗漏的一个重要问题是,C#应用程序(或者可能只是WPF应用程序)需要在其应用程序清单中设置标志。否则,消息永远不会真正发送。此外,允许这样做还有一个障碍,VisualStudio将拒绝运行调试,但您可以将调试器附加到正在运行的进程。希望这能帮助任何通过此线程访问的人。

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

伪造输入并不容易。有时,您可以让它与SendMessage/PostMessage一起使用,但通常会失败。您要做的是调用
SendInput()
,或者更易于使用的
mouse\u event()
。感谢您的回答,但是SendInput()和mouse\u event()都通过将事件注入设备队列来控制真正的鼠标。我需要真正的老鼠不受影响。你还有其他想法吗?没有,我没有更多的想法。你准备好了吗?如果你说我有没有考虑过不可能做到的可能性,那么答案是否定的。如果你是说我有没有考虑过我没有正确的技能来解决这个问题的可能性,然后我不得不说,我仍然乐观地看到注入键盘输入正在发挥作用,我认为这里的问题对于有经验的人来说很容易发现/解决。我希望这里有这样的人能帮我一把。我想如果没有
SendInput
,这可能是不可能的。目标应用程序是什么?你想用伪造的输入做什么?也许还有另一种方法来实现你的目标。我不认为你的最终目标是伪造输入。你可能有一个更平淡无奇的目标!伪造输入并不容易。有时,您可以让它与SendMessage/PostMessage一起使用,但通常会失败。您要做的是调用
SendInput()
,或者更易于使用的
mouse\u event()
。感谢您的回答,但是SendInput()和mouse\u event()都通过将事件注入设备队列来控制真正的鼠标。我需要真正的老鼠不受影响。你还有其他想法吗?没有我没有