开发者

Post a message AFTER the user click the mouse button

I use SetWindowsHookEx to monitor another application. When the user click the mouse in the program I use PostMessage to send a message to the program.

The problem I have is that sometimes my message arrive before WM_LBUTTONUP. How do I ensure that my message will arrive after WM_LBUTTONUP?

I use Gma.UserActivityMonitor for monitoring and following code to send messages:

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);
}

I am using PostMessage to send keystrokes is because I want to do it even if host application is not active.

The hook in Gma.UserActivityMonitor is as follows:

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

I use Spy++ to monitor the messages that arrives to the application. When the messages arrives in the right order I get following result:

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

When the messages arrives in the wrong order I get following result (Note that WM_LBUTTONUP arrive after WM_CHAR have been handled):

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 c开发者_StackOverflowRepeat: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

What I can see it is random when one or the other occurs. If I add a delay before I post the messages, it works. But I don't want to use a delay.


There are a number of reasons that your seeing this behavior (other hooks, system modal loops), but the most obvious one is that your hook gets notified before the WM_nBUTTONUP message is posted to the thread.

The only sure-fire way you can get the desired behavior is with a global hook so that you are executing in the process that will get the message. It is likely you will need to use a WH_CALLWNDPROCRET hook so that your hook gets called after the message is processed.


Use a MOUSE_LL hook, and post the message when you receive the WM_*BUTTONUP.

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜