Twoje pytanie wzbudziło moje zainteresowanie, więc trochę poszperałem i chociaż, niestety, nie mam dla ciebie właściwej odpowiedzi, pomyślałem, że podzielę się tym, co mam.
Znalazłem ten przykład tworzenia haka klawiatury (w Delphi) napisany w 1998 roku, ale można go kompilować w Delphi 2007 z kilkoma poprawkami.
To biblioteka DLL z wywołaniem SetWindowsHookEx
które przechodzi przez funkcję zwrotną, która może następnie przechwytywać naciśnięcia klawiszy: w tym przypadku majstruje przy nich dla zabawy, zmieniając lewy kursor w prawo itd. Następnie prosta aplikacja wywołuje bibliotekę DLL i raportuje z powrotem jego wyniki oparte na zdarzeniu TTimer. Jeśli jesteś zainteresowany, mogę wysłać kod oparty na Delphi 2007.
Jest dobrze udokumentowany i skomentowany i potencjalnie możesz go użyć jako podstawy do ustalenia, dokąd zmierza naciśnięcie klawisza. Gdybyś mógł uzyskać uchwyt aplikacji, która wysłała naciśnięcia klawiszy, możesz to prześledzić w ten sposób. Dzięki temu uchwytowi będziesz w stanie łatwo uzyskać potrzebne informacje.
Inne aplikacje próbowały określić skróty klawiszowe, przechodząc przez swoje skróty, ponieważ mogą zawierać klawisz skrótu, który jest po prostu kolejnym określeniem skrótu klawiszowego. Jednak większość aplikacji nie ustawia tej właściwości, więc może nie zwracać dużo. Jeśli jesteś zainteresowany tą trasą, Delphi ma dostęp do IShellLink
interfejsu COM, z którego możesz wczytać skrót i uzyskać jego skrót:
uses ShlObj, ComObj, ShellAPI, ActiveX, CommCtrl;
procedure GetShellLinkHotKey;
var
LinkFile : WideString;
SL: IShellLink;
PF: IPersistFile;
HotKey : Word;
HotKeyMod: Byte;
HotKeyText : string;
begin
LinkFile := 'C:\Temp\Temp.lnk';
OleCheck(CoCreateInstance(CLSID_ShellLink, nil, CLSCTX_INPROC_SERVER, IShellLink, SL));
// The IShellLink implementer must also support the IPersistFile
// interface. Get an interface pointer to it.
PF := SL as IPersistFile;
// Load file into IPersistFile object
OleCheck(PF.Load(PWideChar(LinkFile), STGM_READ));
// Resolve the link by calling the Resolve interface function.
OleCheck(SL.Resolve(0, SLR_ANY_MATCH or SLR_NO_UI));
// Get hotkey info
OleCheck(SL.GetHotKey(HotKey));
// Extract the HotKey and Modifier properties.
HotKeyText := '';
HotKeyMod := Hi(HotKey);
if (HotKeyMod and HOTKEYF_ALT) = HOTKEYF_ALT then
HotKeyText := 'ALT+';
if (HotKeyMod and HOTKEYF_CONTROL) = HOTKEYF_CONTROL then
HotKeyText := HotKeyText + 'CTRL+';
if (HotKeyMod and HOTKEYF_SHIFT) = HOTKEYF_SHIFT then
HotKeyText := HotKeyText + 'SHIFT+';
if (HotKeyMod and HOTKEYF_EXT) = HOTKEYF_EXT then
HotKeyText := HotKeyText + 'Extended+';
HotKeyText := HotKeyText + Char(Lo(HotKey));
if (HotKeyText = '') or (HotKeyText = #0) then
HotKeyText := 'None';
ShowMessage('Shortcut Key - ' + HotKeyText);
end;
Jeśli masz dostęp do Safari Books Online , w przewodniku Borland Delphi 6 Developer's Guide Steve Teixeira i Xavier Pacheco znajduje się dobra sekcja dotycząca pracy ze skrótami / linkami powłoki . Mój przykład powyżej jest zmasakrowaną wersją stamtąd i tej strony .
Mam nadzieję, że to pomoże!
WM_HOTKEY
wiadomości w dzienniku wiadomości po naciśnięciu klawisza skrótu, może być konieczne uruchomienie 32-bitowej wersji Spy ++ .Po pewnych badaniach wydaje się, że musisz uzyskać dostęp do wewnętrznej struktury używanej przez MS do przechowywania skrótów klawiszowych. ReactOS ma implementację czystego pomieszczenia, która implementuje
GetHotKey
wywołanie poprzez iterację wewnętrznej listy i wyodrębnienie skrótu klawiszowego, który dopasowuje parametry do wywołania.W zależności od tego, jak blisko implementacji ReactOS jest implementacja MS, możesz być w stanie przeszukać pamięć, aby znaleźć strukturę, ale to nad moją głową ...
Przypuszczam, że ten wątek na temat sysinternals został zadany przez kogoś związanego z tym pytaniem, ale pomyślałem, że i tak połączę się z nim, aby utrzymać oba razem. Wątek wygląda bardzo intrygująco, ale podejrzewam, że musiało się zdarzyć jakieś głębokie nurkowanie, aby to rozgryźć bez dostępu do wewnętrznych elementów stwardnienia rozsianego.
źródło
Na wszelki wypadek możesz spróbować wyliczyć wszystkie okna za pomocą EnumWindows, a następnie w wywołaniu zwrotnym wysłać WM_GETHOTKEY do każdego okna.
Edycja: W tej chwili się myliłem. MSDN zawiera więcej informacji:
Uwaga: oto program, który rzekomo ma funkcjonalność, której szukasz. Możesz spróbować go zdekompilować.
źródło
To wydaje się dużo mówić: http://hkcmdr.anymania.com/help.html
źródło
hoo
używanaSetWindowHookEx
do ustawienia dwóch punktów zaczepienia, jednegoWH_KEYBOARD_LL
i jednegoWH_GETMESSAGE
... reszta powinna być prawie udokumentowana w witrynie MSDN.Inny wątek wspomina o globalnym zaczepie klawiatury na poziomie NT:
Ponownie przypisz / zastąp klawisz skrótu (Win + L), aby zablokować okna
być może uda ci się uzyskać uchwyt procesu, który w ten sposób nazwał zaczep, który możesz następnie rozwiązać na nazwę procesu
(zastrzeżenie: miałem to w swoich zakładkach, tak naprawdę nie wypróbowałem / nie przetestowałem)
źródło
Wiem, że możesz przechwycić strumień wiadomości w dowolnym oknie w ramach własnego procesu - to, co nazywaliśmy podklasą w VB6. (Chociaż nie pamiętam funkcji, być może SetWindowLong?) Nie jestem pewien, czy możesz to zrobić dla okien poza własnym procesem. Ale ze względu na ten post załóżmy, że znajdziesz sposób, aby to zrobić. Następnie możesz po prostu przechwycić wiadomości ze wszystkich okien najwyższego poziomu, monitorować pod kątem wiadomości WM_HOTKEY. Nie byłbyś w stanie poznać wszystkich klawiszy od razu, ale ponieważ zostały wciśnięte, możesz łatwo dowiedzieć się, która aplikacja ich używa. Jeśli wyniki były utrwalane na dysku i ładowano je ponownie za każdym razem, gdy uruchamiano aplikację monitorującą, można z czasem zwiększyć wydajność aplikacji.
źródło
Nie jest to dokładna odpowiedź na część pytania, która dotyczy interfejsu API systemu Windows, ale odpowiada na część pytania, która dotyczy listy globalnych skrótów klawiszowych i aplikacji, które je „posiadają”.
Darmowy Hotkey Explorer pod adresem http://hkcmdr.anymania.com/ wyświetla listę wszystkich globalnych skrótów klawiszowych i aplikacji, które są ich właścicielami. To właśnie pomogło mi zrozumieć, dlaczego klawisz skrótu specyficzny dla aplikacji przestał działać i jak to naprawić (poprzez rekonfigurację zarejestrowanego globalnego skrótu w aplikacji, w której został zarejestrowany) w ciągu kilku sekund.
źródło