Übersicht über Hooks
Ein Hook ist ein Mechanismus, mit dem eine Anwendung Ereignisse wie Nachrichten, Mausaktionen und Tastenanschläge abfangen kann. Eine Funktion, die einen bestimmten Ereignistyp abfängt, wird als Hookprozedur bezeichnet. Eine Hookprozedur kann auf jedes empfangene Ereignis reagieren und das Ereignis dann ändern oder verwerfen.
Das folgende Beispiel verwendet für Hooks:
- Überwachen von Nachrichten zu Debugzwecken
- Bereitstellen von Unterstützung für die Aufzeichnung und Wiedergabe von Makros
- Bereitstellen von Support für einen Hilfeschlüssel (F1)
- Simulieren von Maus- und Tastatureingaben
- Implementieren einer CBT-Anwendung (Computer-Based Training)
Hinweis
Hooks neigen dazu, das System zu verlangsamen, da sie die Verarbeitungsmenge erhöhen, die das System für jede Nachricht ausführen muss. Sie sollten einen Hook nur bei Bedarf installieren und so schnell wie möglich entfernen.
In diesem Abschnitt wird Folgendes erläutert:
Hakenketten
Das System unterstützt viele verschiedene Arten von Haken; jeder Typ bietet Zugriff auf einen anderen Aspekt des Mechanismus für die Nachrichtenverarbeitung. Beispielsweise kann eine Anwendung den WH_MOUSE-Hook verwenden, um den Nachrichtendatenverkehr für Mausnachrichten zu überwachen.
Das System verwaltet eine separate Hakenkette für jeden Hakentyp. Eine Hook chain ist eine Liste von Zeigern auf spezielle, anwendungsdefinierte Rückruffunktionen, die als Hookprozeduren bezeichnet werden. Wenn eine Nachricht auftritt, die einem bestimmten Hooktyp zugeordnet ist, übergibt das System die Nachricht an jede Hookprozedur, auf die in der Hookkette verwiesen wird, nacheinander. Die Aktion, die eine Hookprozedur ausführen kann, hängt vom Typ des betreffenden Hooks ab. Die Hookprozeduren für einige Arten von Hooks können nur Nachrichten überwachen. andere können Nachrichten ändern oder ihren Fortschritt durch die Kette beenden, hindern sie daran, die nächste Hookprozedur oder das Zielfenster zu erreichen.
Hookprozeduren
Um einen bestimmten Hooktyp zu nutzen, stellt der Entwickler eine Hookprozedur bereit und verwendet die SetWindowsHookEx-Funktion , um sie in der Kette zu installieren, die dem Hook zugeordnet ist. Eine Hookprozedur muss die folgende Syntax aufweisen:
LRESULT CALLBACK HookProc(
int nCode,
WPARAM wParam,
LPARAM lParam
)
{
// process event
...
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
HookProc ist ein Platzhalter für einen anwendungsdefinierten Namen.
Der nCode-Parameter ist ein Hookcode, den die Hookprozedur verwendet, um die auszuführende Aktion zu bestimmen. Der Wert des Hookcodes hängt vom Typ des Hooks ab. Jeder Typ verfügt über einen eigenen charakteristischen Satz von Hookcodes. Die Werte der Parameter wParam und lParam hängen vom Hookcode ab, enthalten jedoch in der Regel Informationen zu einer gesendeten oder geposteten Nachricht.
Die SetWindowsHookEx-Funktion installiert immer eine Hookprozedur am Anfang einer Hookkette. Wenn ein Ereignis auftritt, das von einem bestimmten Hooktyp überwacht wird, ruft das System die Prozedur am Anfang der Hookkette auf, die dem Hook zugeordnet ist. Jede Hookprozedur in der Kette bestimmt, ob das Ereignis an die nächste Prozedur übergeben werden soll. Eine Hookprozedur übergibt ein Ereignis an die nächste Prozedur, indem die CallNextHookEx-Funktion aufgerufen wird.
Beachten Sie, dass die Hookprozeduren für einige Hooktypen nur Nachrichten überwachen können. Das System übergibt Nachrichten an jede Hookprozedur, unabhängig davon, ob eine bestimmte Prozedur CallNextHookEx aufruft.
Ein globaler Hook überwacht Nachrichten für alle Threads auf demselben Desktop wie der aufrufende Thread. Ein threadspezifischer Hook überwacht Nachrichten nur für einen einzelnen Thread. Eine globale Hookprozedur kann im Kontext jeder Anwendung auf demselben Desktop wie der aufrufende Thread aufgerufen werden. Daher muss sich die Prozedur in einem separaten DLL-Modul befinden. Eine threadspezifische Hookprozedur wird nur im Kontext des zugeordneten Threads aufgerufen. Wenn eine Anwendung eine Hookprozedur für einen ihrer eigenen Threads installiert, kann sich die Hookprozedur entweder im selben Modul wie der rest des Anwendungscodes oder in einer DLL befinden. Wenn die Anwendung eine Hookprozedur für einen Thread einer anderen Anwendung installiert, muss sich die Prozedur in einer DLL befinden. Weitere Informationen finden Sie unter Bibliotheken mit dynamischer Verknüpfung.
Hinweis
Sie sollten globale Hooks nur zu Debugzwecken verwenden. Andernfalls sollten Sie sie vermeiden. Globale Hooks beeinträchtigen die Systemleistung und führen zu Konflikten mit anderen Anwendungen, die denselben globalen Hook implementieren.
Hooktypen
Jeder Hooktyp ermöglicht es einer Anwendung, einen anderen Aspekt des Mechanismus für die Nachrichtenverarbeitung des Systems zu überwachen. In den folgenden Abschnitten werden die verfügbaren Hooks beschrieben.
- WH_CALLWNDPROC und WH_CALLWNDPROCRET
- WH_CBT
- WH_DEBUG
- WH_FOREGROUNDIDLE
- WH_GETMESSAGE
- WH_JOURNALPLAYBACK
- WH_JOURNALRECORD
- WH_KEYBOARD_LL
- WH_KEYBOARD
- WH_MOUSE_LL
- WH_MOUSE
- WH_MSGFILTER und WH_SYSMSGFILTER
- WH_SHELL
WH_CALLWNDPROC und WH_CALLWNDPROCRET
Mit den WH_CALLWNDPROC - und WH_CALLWNDPROCRET-Hooks können Sie Nachrichten überwachen, die an Fensterprozeduren gesendet werden. Das System ruft eine WH_CALLWNDPROC Hookprozedur auf, bevor die Nachricht an die empfangende Fensterprozedur übergeben wird, und ruft die WH_CALLWNDPROCRET Hookprozedur auf, nachdem die Fensterprozedur die Nachricht verarbeitet hat.
Der WH_CALLWNDPROCRET Hook übergibt einen Zeiger auf eine CWPRETSTRUCT-Struktur an die Hookprozedur. Die Struktur enthält den Rückgabewert aus der Fensterprozedur, die die Nachricht verarbeitet hat, sowie die der Nachricht zugeordneten Nachrichtenparameter. Das Unterklassen des Fensters funktioniert nicht für Nachrichten, die zwischen Prozessen festgelegt werden.
Weitere Informationen finden Sie in den Rückruffunktionen CallWndProc und CallWndRetProc .
WH_CBT
Das System ruft eine WH_CBT Hook-Prozedur auf, bevor ein Fenster aktiviert, erstellt, zerstört, minimiert, maximiert, verschoben oder dimensioniert wird. vor Abschluss eines Systembefehls; vor dem Entfernen eines Maus- oder Tastaturereignisses aus der Systemnachrichtenwarteschlange; bevor Sie den Eingabefokus festlegen; oder vor der Synchronisierung mit der Systemnachrichtenwarteschlange. Der Wert, den die Hookprozedur zurückgibt, bestimmt, ob das System einen dieser Vorgänge zulässt oder verhindert. Der WH_CBT-Hook ist in erster Linie für computerbasierte Trainingsanwendungen (CBT) vorgesehen.
Weitere Informationen finden Sie in der Rückruffunktion CBTProc .
Weitere Informationen finden Sie unter WinEvents.
WH_DEBUG
Das System ruft eine WH_DEBUG Hookprozedur auf, bevor Hookprozeduren aufgerufen werden, die einem anderen Hook im System zugeordnet sind. Sie können diesen Hook verwenden, um zu bestimmen, ob das System Hookprozeduren aufrufen kann, die anderen Hooktypen zugeordnet sind.
Weitere Informationen finden Sie in der Rückruffunktion DebugProc .
WH_FOREGROUNDIDLE
Der WH_FOREGROUNDIDLE-Hook ermöglicht Es Ihnen, Aufgaben mit niedriger Priorität in Zeiten auszuführen, in denen sich der Vordergrundthread im Leerlauf befindet. Das System ruft eine WH_FOREGROUNDIDLE Hookprozedur auf, wenn der Vordergrundthread der Anwendung im Leerlauf steht.
Weitere Informationen finden Sie in der Rückruffunktion ForegroundIdleProc .
WH_GETMESSAGE
Der WH_GETMESSAGE Hook ermöglicht es einer Anwendung, Nachrichten zu überwachen, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden. Sie können den WH_GETMESSAGE Hook verwenden, um Maus- und Tastatureingaben sowie andere Nachrichten zu überwachen, die an die Nachrichtenwarteschlange gesendet werden.
Weitere Informationen finden Sie in der Rückruffunktion GetMsgProc .
WH_JOURNALPLAYBACK
Warnung
Journaling Hooks-APIs werden ab Windows 11 nicht mehr unterstützt und werden in einer zukünftigen Version entfernt. Daher wird dringend empfohlen, stattdessen die SendInput TextInput-API aufzurufen.
Der WH_JOURNALPLAYBACK-Hook ermöglicht es einer Anwendung, Nachrichten in die Systemnachrichtenwarteschlange einzufügen. Sie können diesen Hook verwenden, um eine Reihe von Maus- und Tastaturereignissen wiederzugeben, die zuvor mit WH_JOURNALRECORD aufgezeichnet wurden. Normale Maus- und Tastatureingaben sind deaktiviert, solange ein WH_JOURNALPLAYBACK Hook installiert ist. Ein WH_JOURNALPLAYBACK Hook ist ein globaler Hook. Er kann nicht als threadspezifischer Hook verwendet werden.
Der WH_JOURNALPLAYBACK Hook gibt einen Timeoutwert zurück. Dieser Wert teilt dem System mit, wie viele Millisekunden gewartet werden soll, bevor die aktuelle Nachricht vom Wiedergabehook verarbeitet wird. Dadurch kann der Hook das Timing der ereignisse steuern, die er wiedergibt.
Weitere Informationen finden Sie unter der Rückruffunktion JournalPlaybackProc .
WH_JOURNALRECORD
Warnung
Journaling Hooks-APIs werden ab Windows 11 nicht mehr unterstützt und werden in einer zukünftigen Version entfernt. Daher wird dringend empfohlen, stattdessen die SendInput TextInput-API aufzurufen.
Mit dem WH_JOURNALRECORD Hook können Sie Eingabeereignisse überwachen und aufzeichnen. In der Regel verwenden Sie diesen Hook, um eine Sequenz von Maus- und Tastaturereignissen aufzuzeichnen, die später mithilfe von WH_JOURNALPLAYBACK wiedergegeben werden sollen. Der WH_JOURNALRECORD Hook ist ein globaler Hook. Er kann nicht als threadspezifischer Hook verwendet werden.
Weitere Informationen finden Sie in der Rückruffunktion JournalRecordProc .
WH_KEYBOARD_LL
Mit dem WH_KEYBOARD_LL Hook können Sie Tastatureingabeereignisse überwachen, die in einer Threadeingabewarteschlange bereitgestellt werden.
Weitere Informationen finden Sie in der Rückruffunktion LowLevelKeyboardProc .
WH_KEYBOARD
Der WH_KEYBOARD-Hook ermöglicht es einer Anwendung, den Nachrichtendatenverkehr auf WM_KEYDOWN und WM_KEYUP Nachrichten zu überwachen, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden. Sie können den WH_KEYBOARD Hook verwenden, um Tastatureingaben zu überwachen, die in eine Nachrichtenwarteschlange gesendet werden.
Weitere Informationen finden Sie in der Rückruffunktion KeyboardProc .
WH_MOUSE_LL
Mit dem WH_MOUSE_LL-Hook können Sie Mauseingabeereignisse überwachen, die in einer Threadeingabewarteschlange bereitgestellt werden.
Weitere Informationen finden Sie in der Rückruffunktion LowLevelMouseProc .
WH_MOUSE
Mit dem WH_MOUSE-Hook können Sie Mausnachrichten überwachen, die von der GetMessage - oder PeekMessage-Funktion zurückgegeben werden. Sie können den WH_MOUSE Hook verwenden, um Mauseingaben zu überwachen, die an eine Nachrichtenwarteschlange gesendet werden.
Weitere Informationen finden Sie unter der Rückruffunktion MouseProc .
WH_MSGFILTER und WH_SYSMSGFILTER
Mit WH_MSGFILTER und WH_SYSMSGFILTER Hooks können Sie Nachrichten überwachen, die von einem Menü, einer Bildlaufleiste, einem Meldungsfeld oder einem Dialogfeld verarbeitet werden sollen, und erkennen, wann ein anderes Fenster aktiviert wird, nachdem der Benutzer die Tastenkombination ALT+TAB oder ALT+ESC gedrückt hat. Der WH_MSGFILTER Hook kann nur Nachrichten überwachen, die an ein Menü, eine Bildlaufleiste, ein Meldungsfeld oder ein Dialogfeld übergeben werden, das von der Anwendung erstellt wurde, die die Hookprozedur installiert hat. Der WH_SYSMSGFILTER Hook überwacht solche Meldungen für alle Anwendungen.
Mit WH_MSGFILTER- und WH_SYSMSGFILTER-Hooks können Sie während modaler Schleifen nachrichtenfiltern, die der Filterung in der Standard-Nachrichtenschleife entspricht. Beispielsweise untersucht eine Anwendung häufig eine neue Nachricht in der Standard-Schleife zwischen dem Zeitpunkt, zu dem sie die Nachricht aus der Warteschlange abruft, und dem Zeitpunkt, zu dem sie die Nachricht versendet, und führt bei Bedarf eine spezielle Verarbeitung aus. Während einer modalen Schleife ruft das System jedoch Nachrichten ab und verteilt sie, ohne einer Anwendung die Möglichkeit zu geben, die Nachrichten in der Standard Nachrichtenschleife zu filtern. Wenn eine Anwendung eine WH_MSGFILTER - oder WH_SYSMSGFILTER Hookprozedur installiert, ruft das System die Prozedur während der modalen Schleife auf.
Eine Anwendung kann den WH_MSGFILTER Hook direkt aufrufen, indem die CallMsgFilter-Funktion aufgerufen wird. Mithilfe dieser Funktion kann die Anwendung denselben Code verwenden, um Nachrichten während modaler Schleifen zu filtern, wie sie in der Standard-Nachrichtenschleife verwendet. Kapseln Sie dazu die Filtervorgänge in einer WH_MSGFILTER Hookprozedur, und rufen Sie CallMsgFilter zwischen den Aufrufen der Funktionen GetMessage und DispatchMessage auf.
while (GetMessage(&msg, (HWND) NULL, 0, 0))
{
if (!CallMsgFilter(&qmsg, 0))
DispatchMessage(&qmsg);
}
Das letzte Argument von CallMsgFilter wird einfach an die Hookprozedur übergeben. Sie können einen beliebigen Wert eingeben. Die Hookprozedur kann durch Definieren einer Konstanten wie MSGF_MAINLOOP diesen Wert verwenden, um zu bestimmen, wo die Prozedur aufgerufen wurde.
Weitere Informationen finden Sie unter den Rückruffunktionen MessageProc und SysMsgProc .
WH_SHELL
Eine Shellanwendung kann den WH_SHELL Hook verwenden, um wichtige Benachrichtigungen zu empfangen. Das System ruft eine WH_SHELL Hookprozedur auf, wenn die Shellanwendung aktiviert wird und wenn ein Fenster der obersten Ebene erstellt oder zerstört wird.
Beachten Sie, dass benutzerdefinierte Shellanwendungen keine WH_SHELL Nachrichten empfangen. Daher muss jede Anwendung, die sich selbst als Standardshell registriert, die SystemParametersInfo-Funktion aufrufen, bevor sie (oder eine andere Anwendung) WH_SHELL Nachrichten empfangen kann. Diese Funktion muss mit SPI_SETMINIMIZEDMETRICS und einer MINIMIZEDMETRICS-Struktur aufgerufen werden. Legen Sie den iArrange-Member dieser Struktur auf ARW_HIDE fest.
Weitere Informationen finden Sie in der ShellProc-Rückruffunktion .