2009-02-08 11 views
5

Próbuję napisać aplikację, która odpowiada po naciśnięciu klawisza Shift, bez względu na to, która aplikacja jest aktualnie aktywna.Odpowiadasz na klawiaturę, gdy nie ma ostrości? (C#, Vista)

Próbowałem tego z SetWindowsHookEx() i GetKeyboardState(), ale oba te działają tylko wtedy, gdy okno aplikacji jest aktywne. Potrzebuję go do działania na całym świecie.

Jak to zrobić?

Odpowiedz

5

Żadna z podanych odpowiedzi nie pomogła mi rozwiązać mojego problemu, ale sam znalazłem odpowiedź. Oto jest.

Używanie SetWindowsHookEx() z WH_KEYBOARD_LL było prawidłowym podejściem. Jednak pozostałe parametry do SetWindowsHookEx() są nieintuicyjne:

  • Ostatnim parametrem, dwThreadId, musi być 0.
  • przedostatnią parametr, hMod, musi wskazywać na jakiś DLL. Użyłem User32, która jest biblioteką DLL, która jest zawsze wczytywana i jest używana przez wszystkie procesy z GUI. Mam pomysł od a CodeProject post about this.

Zatem kod wygląda trochę tak:

instance = LoadLibrary("User32"); 
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookFunction, instance, 0); 

Dokumentacja jest jasne, o przedostatnią parametru. Jest napisane:

Parametr hMod musi być ustawiony na NULL [...], jeśli procedura haka mieści się w kodzie powiązanym z bieżącym procesem.

Nie stwierdza, że ​​dotyczy to tylko niektórych typów haczyków, ale nie dotyczy to WH_KEYBOARD_LL i WH_MOUSE_LL.

+0

Tak, to właśnie mają na myśli - dla niskiego poziomu myszy lub haka klawiatury (lub dowolnego innego lokalnego haka) hMod powinien być IntPtr.Zero. –

+0

Hmmm, mówisz, że inne posty nie były pomocne, następnie opublikuj tę samą odpowiedź, którą już podał nobugz, i oznacz swoją jako poprawną odpowiedź. –

+0

Nobugz nie mówi w ogóle o tym, co zrobić z hModem, a w przeciwieństwie do pierwszego komentarza, ta odpowiedź sugeruje, że hMod ma być ustawiony na coś ** innego ** niż IntPtr.Zero. –

5

Będziesz musiał użyć SetWindowsHookEx(). Istnieją tylko dwa typy haków, które można implementować w zarządzanym języku WH_KEYBOARD_LL i WH_MOUSE_LL. Wszystkie inne haki wymagają biblioteki DLL, którą można wstrzyknąć do innego procesu. Zarządzane biblioteki DLL nie mogą być wstrzykiwane, nie można zainicjować środowiska CLR.

Ten blog post ma funkcjonalny przykład.

+0

Większość innych haczyków można również zaimplementować w zarządzanym języku, ale tylko wtedy, gdy są ograniczone do wątków bieżącego procesu. Niski poziom myszy i haki klawiatury to jedyne "globalne" haczyki dozwolone. –

+0

To tylko przeciera powierzchnię problemu i nie wchodzi w żaden głęboki poziom. –

+1

To jest bardzo konkretna odpowiedź na konkretne pytanie. Trochę jest krótka i zawiera kilka informacji dla uproszczenia, ale zawiera wszystkie informacje, których potrzebowałby kompetentny programista. –

2

Jeśli użyjesz tej techniki w poście, do której odwołuje się nobugz, musisz upewnić się, że delegatowi nie zostaną pobrane śmieci, np. za pomocą GC.KeepAlive (_proc) podczas ustawiania haka, w przeciwnym razie po okresie nieokreślonym hak przestanie działać, gdy delagate otrzyma GCed.

Powiązane problemy