2010-12-14 4 views
0

Я использую 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 

Что я вижу, это случайный случай, когда происходит то или другое. Если я добавлю задержку до публикации сообщений, она будет работать. Но я не хочу использовать задержку.

+0

Почему бы вам не разместить здесь соответствующий код, чтобы мы могли видеть, как вы это делаете? – Nawaz

+0

@Nawaz Я добавил упрощенный код того, что я пытаюсь сделать – magol

ответ

1

Есть целый ряд причин, по которым вашему видящих этого поведения (другие крючков, системы модальных петли), но наиболее очевидным является то, что ваш крючок получает уведомление, прежде чем сообщение WM_nBUTTONUP размещено на резьбу.

Единственный надежный способ, которым вы можете получить желаемое поведение, - это глобальный крючок, чтобы вы выполняли процесс, который получит сообщение. Вероятно, вам нужно будет использовать крюк WH_CALLWNDPROCRET, чтобы ваш крючок вызывался после сообщение обрабатывалось.

-1

Используйте крючок MOUSE_LL и отправьте сообщение, когда вы получите WM_*BUTTONUP.

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

+0

Только то, что я сделал, но он работает только, к сожалению. – magol

+0

У вас есть какие-то лучшие критерии, чем «часть времени»? (например, окно должно быть активным, ...) Выполняется ли запись PostMessage? Прерывается ли какой-либо из методов? С каким кодом? Является ли ActiveControlInWindow правильным дескриптором окна? – peterchen

+0

Что я вижу, это случайный случай, когда происходит то или другое. Я редактирую вопрос, чтобы показать результат в spy +++. И KEYUP и KEYDOWN поступают в приложение, как вы можете. Поэтому в этом не может быть никакой ошибки. – magol

Смежные вопросы