在用户单击鼠标按钮后发布消息

时间:2010-12-14 08:48:49

标签: c# c++ api winapi

我使用SetWindowsHookEx监视另一个应用程序。当用户在程序中单击鼠标时,我使用PostMessage向程序发送消息。

我遇到的问题是,有时我的消息在 WM_LBUTTONUP之前到达。如何确保我的邮件> WM_LBUTTONUP后 >

我使用Gma.UserActivityMonitor监控并跟踪代码以发送消息:

HookManager.MouseUp += HookManagerMouseUp;

void HookManagerMouseUp(object sender, MouseEventArgs e)
{
   uint ret;
   uint attachedThredId = GetCurrentThreadId();
   uint attachedProcessId = GetWindowThreadProcessId(ActiveWindow, out ret);
   AttachThreadInputSafe(attachedThredId, attachedProcessId, true);


   PostMessage(ActiveControlInWindow, Message.KeyDown, 'A', 0x1);
   PostMessage(ActiveControlInWindow, Message.KeyUp,   'A', 0xC0010001);

   AttachThreadInputSafe(attachedThredId, attachedProcessId, false);
}

我使用PostMessage发送击键是因为即使主机应用程序未处于活动状态我也想这样做。

Gma.UserActivityMonitor中的钩子如下:

s_MouseDelegate = MouseHookProc;
s_MouseHookHandle = SetWindowsHookEx(
  WH_MOUSE_LL,
  s_MouseDelegate,
  Marshal.GetHINSTANCE(
    Assembly.GetExecutingAssembly().GetModules()[0]),
    0);

我使用Spy ++来监控到达应用程序的消息。当消息以正确的顺序到达时,我得到以下结果:

S   WM_MOUSEACTIVATE hwndTopLevel:00030A46 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
R   WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
S   WM_KILLFOCUS hwndGetFocus:00020A32
R   WM_KILLFOCUS
S   WM_IME_SETCONTEXT fSet:1 iShow:C000000F
R   WM_IME_SETCONTEXT
S   WM_SETFOCUS hwndLoseFocus:00030A46
R   WM_SETFOCUS
P   WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:278 yPos:73
S   WM_ERASEBKGND hdc:0E010DEE
R   WM_ERASEBKGND fErased:True
P   WM_LBUTTONUP fwKeys:0000 xPos:278 yPos:73
S   WM_CAPTURECHANGED hwndNewCapture:00000000
R   WM_CAPTURECHANGED
P   WM_KEYDOWN nVirtKey:VK_OEM_5 cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:VK_OEM_5 cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_CHAR chCharCode:'167' (167) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYDOWN nVirtKey:'2' cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:'2' cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_KEYDOWN nVirtKey:'2' cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:'2' cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_CHAR chCharCode:'50' (50) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_CHAR chCharCode:'50' (50) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
S   WM_KILLFOCUS hwndGetFocus:(null)
R   WM_KILLFOCUS
S   WM_IME_SETCONTEXT fSet:0 iShow:C000000F
R   WM_IME_SETCONTEXT

当消息以错误的顺序到达时,我得到以下结果(注意WM_LBUTTONUP在 WM_CHAR处理完毕后到达):

S   WM_MOUSEACTIVATE hwndTopLevel:00030A46 nHittest:HTCLIENT uMsg:WM_LBUTTONDOWN
R   WM_MOUSEACTIVATE fuActivate:MA_ACTIVATE
S   WM_KILLFOCUS hwndGetFocus:00020A32
R   WM_KILLFOCUS
S   WM_IME_SETCONTEXT fSet:1 iShow:C000000F
R   WM_IME_SETCONTEXT
S   WM_SETFOCUS hwndLoseFocus:00030A46
R   WM_SETFOCUS
P   WM_LBUTTONDOWN fwKeys:MK_LBUTTON xPos:329 yPos:166
S   WM_ERASEBKGND hdc:1E0117FD
R   WM_ERASEBKGND fErased:True
P   WM_KEYDOWN nVirtKey:VK_OEM_5 cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:VK_OEM_5 cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_KEYDOWN nVirtKey:'2' cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:'2' cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_KEYDOWN nVirtKey:'2' cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_KEYUP nVirtKey:'2' cRepeat:1 ScanCode:01 fExtended:0 fAltDown:0 fRepeat:1 fUp:1
P   WM_CHAR chCharCode:'167' (167) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_CHAR chCharCode:'50' (50) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_CHAR chCharCode:'50' (50) cRepeat:1 ScanCode:00 fExtended:0 fAltDown:0 fRepeat:0 fUp:0
P   WM_LBUTTONUP fwKeys:0000 xPos:329 yPos:166
S   WM_CAPTURECHANGED hwndNewCapture:00000000
R   WM_CAPTURECHANGED
S   WM_KILLFOCUS hwndGetFocus:(null)
R   WM_KILLFOCUS
S   WM_IME_SETCONTEXT fSet:0 iShow:C000000F
R   WM_IME_SETCONTEXT

当一个或另一个发生时,我可以看到它是随机的。如果我在发布消息之前添加延迟,它会起作用。但我不想使用延迟。

2 个答案:

答案 0 :(得分:1)

您看到此行为(其他挂钩,系统模态循环)有很多原因,但最明显的原因是在将WM_nBUTTONUP消息发布到线程之前,您的挂钩会得到通知。

您可以获得所需行为的唯一可靠方法是使用全局钩子,以便您在获取消息的过程中执行。您可能需要使用WH_CALLWNDPROCRET挂钩,以便在处理消息后,您的挂钩被称为

答案 1 :(得分:-1)

使用MOUSE_LL挂钩,并在收到WM_*BUTTONUP时发布消息。

http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx