Condividi tramite


Funzione SetWindowsHookExA (winuser.h)

Installa una procedura di hook definita dall'applicazione in una catena di hook. È possibile installare una procedura di hook per monitorare il sistema per determinati tipi di eventi. Questi eventi sono associati a un thread specifico o a tutti i thread nello stesso desktop del thread chiamante.

Sintassi

HHOOK SetWindowsHookExA(
  [in] int       idHook,
  [in] HOOKPROC  lpfn,
  [in] HINSTANCE hmod,
  [in] DWORD     dwThreadId
);

Parametri

[in] idHook

Tipo: int

Tipo di procedura di hook da installare. Questo parametro può avere uno dei valori seguenti.

Valore Significato
WH_CALLWNDPROC
4

Installa una routine di hook che monitora i messaggi prima che il sistema li invii alla procedura della finestra di destinazione. Per altre informazioni, vedere la procedura di hook CallWndProc .

WH_CALLWNDPROCRET
12
Installa una procedura di hook che monitora i messaggi dopo che sono stati elaborati dalla procedura della finestra di destinazione. Per altre informazioni, vedere la procedura di hook [HOOKPROC callback](nc-winuser-hookproc.md).
WH_CBT
5
Installa una procedura di hook che riceve notifiche utili per un'applicazione CBT. Per altre informazioni, vedere la procedura di hook CBTProc .
WH_DEBUG
9

Installa una routine di hook utile per il debug di altre procedure di hook. Per altre informazioni, vedere la procedura di hook DebugProc .

WH_FOREGROUNDIDLE
11

Installa una routine di hook che verrà chiamata quando il thread in primo piano dell'applicazione sta per diventare inattivo. Questo hook è utile per eseguire attività con priorità bassa durante il tempo di inattività. Per altre informazioni, vedere la procedura di hook ForegroundIdleProc .

WH_GETMESSAGE
3

Installa una routine di hook che monitora i messaggi pubblicati in una coda di messaggi. Per altre informazioni, vedere la procedura di hook GetMsgProc .

WH_JOURNALPLAYBACK
1

Avviso

Windows 11 e versioni successive: le API di associazione journaling non sono supportate. È consigliabile usare invece l'API SendInput TextInput .

Installa una routine di hook che pubblica i messaggi registrati in precedenza da una routine di hook WH_JOURNALRECORD . Per altre informazioni, vedere la procedura di hook JournalPlaybackProc .

WH_JOURNALRECORD
0

Avviso

Windows 11 e versioni successive: le API di associazione journaling non sono supportate. È consigliabile usare invece l'API SendInput TextInput .

Installa una routine di hook che registra i messaggi di input inviati alla coda dei messaggi di sistema. Questo hook è utile per registrare le macro. Per altre informazioni, vedere la procedura di hook JournalRecordProc .

WH_KEYBOARD
2

Installa una procedura di hook che monitora i messaggi di sequenza di tasti. Per altre informazioni, vedere la procedura di hook KeyboardProc .

WH_KEYBOARD_LL
13
Installa una procedura di hook che monitora gli eventi di input della tastiera di basso livello. Per altre informazioni, vedere la procedura di hook [LowLevelKeyboardProc](/windows/win32/winmsg/lowlevelkeyboardproc).
WH_MOUSE
7

Installa una procedura di hook che monitora i messaggi del mouse. Per altre informazioni, vedere la procedura di hook MouseProc .

WH_MOUSE_LL
14

Installa una procedura di hook che monitora gli eventi di input del mouse di basso livello. Per altre informazioni, vedere la procedura di hook LowLevelMouseProc .

WH_MSGFILTER
-1

Installa una routine di hook che monitora i messaggi generati come risultato di un evento di input in una finestra di dialogo, una finestra di messaggio, un menu o una barra di scorrimento. Per altre informazioni, vedere la procedura di hook MessageProc .

WH_SHELL
10
Installa una procedura di hook che riceve notifiche utili per le applicazioni shell. Per altre informazioni, vedere la procedura di hook ShellProc .
WH_SYSMSGFILTER
6

Installa una routine di hook che monitora i messaggi generati come risultato di un evento di input in una finestra di dialogo, una finestra di messaggio, un menu o una barra di scorrimento. La procedura di hook monitora questi messaggi per tutte le applicazioni nello stesso desktop del thread chiamante. Per altre informazioni, vedere la procedura di hook SysMsgProc .

[in] lpfn

Tipo: HOOKPROC

Puntatore alla procedura di hook. Se il parametro dwThreadId è zero o specifica l'identificatore di un thread creato da un processo diverso, il parametro lpfn deve puntare a una routine di hook in una DLL. In caso contrario, lpfn può puntare a una routine di hook nel codice associato al processo corrente.

[in] hmod

Tipo: HINSTANCE

Handle alla DLL contenente la routine hook a cui punta il parametro lpfn . Il parametro hMod deve essere impostato su NULL se il parametro dwThreadId specifica un thread creato dal processo corrente e se la procedura di hook si trova all'interno del codice associato al processo corrente.

[in] dwThreadId

Tipo: DWORD

Identificatore del thread con cui deve essere associata la routine di hook. Per le app desktop, se questo parametro è zero, la procedura di hook è associata a tutti i thread esistenti in esecuzione nello stesso desktop del thread chiamante. Per le app di Windows Store, vedere la sezione Osservazioni.

Valore restituito

Tipo: HHOOK

Se la funzione ha esito positivo, il valore restituito è l'handle della procedura di hook.

Se la funzione ha esito negativo, il valore restituito è NULL. Per informazioni dettagliate sull'errore, chiamare GetLastError.

Commenti

SetWindowsHookEx può essere usato per inserire una DLL in un altro processo. Non è possibile inserire una DLL a 32 bit in un processo a 64 bit e non è possibile inserire una DLL a 64 bit in un processo a 32 bit. Se un'applicazione richiede l'uso di hook in altri processi, è necessario che una chiamata di applicazione a 32 bit SetWindowsHookEx per inserire una DLL a 32 bit in processi a 32 bit e una chiamata di applicazione a 64 bit SetWindowsHookEx per inserire una DLL a 64 bit in processi a 64 bit. Le DLL a 32 bit e a 64 bit devono avere nomi diversi.

Poiché gli hook vengono eseguiti nel contesto di un'applicazione, devono corrispondere al "bitness" dell'applicazione. Se un'applicazione a 32 bit installa un hook globale in Windows a 64 bit, l'hook a 32 bit viene inserito in ogni processo a 32 bit (si applicano i limiti di sicurezza consueti). In un processo a 64 bit, i thread sono ancora contrassegnati come "collegati". Tuttavia, poiché un'applicazione a 32 bit deve eseguire il codice hook, il sistema esegue l'hook nel contesto dell'app di hook; in particolare, nel thread che ha chiamato SetWindowsHookEx. Ciò significa che l'applicazione di collegamento deve continuare a pompare i messaggi o potrebbe bloccare il normale funzionamento dei processi a 64 bit.

Se un'applicazione a 64 bit installa un hook globale in Windows a 64 bit, l'hook a 64 bit viene inserito in ogni processo a 64 bit, mentre tutti i processi a 32 bit usano un callback all'applicazione di hook.

Per associare tutte le applicazioni sul desktop di un'installazione di Windows a 64 bit, installare un hook globale a 32 bit e un hook globale a 64 bit, ognuno dei processi appropriati e assicurarsi di mantenere i messaggi di pompa nell'applicazione hooking per evitare di bloccare il normale funzionamento. Se si dispone già di un'applicazione di hook globale a 32 bit e non è necessario eseguirla nel contesto di ogni applicazione, potrebbe non essere necessario creare una versione a 64 bit.

Può verificarsi un errore se il parametro hMod è NULL e il parametro dwThreadId è zero o specifica l'identificatore di un thread creato da un altro processo.

La chiamata della funzione CallNextHookEx per concatenare la routine hook successiva è facoltativa, ma è altamente consigliata; in caso contrario, altre applicazioni che hanno installato hook non riceveranno notifiche hook e potrebbero comportarsi in modo non corretto di conseguenza. È consigliabile chiamare CallNextHookEx , a meno che non sia assolutamente necessario impedire che la notifica venga visualizzata da altre applicazioni.

Prima di terminare, un'applicazione deve chiamare la funzione funzione UnhookWindowsHookEx per liberare le risorse di sistema associate all'hook.

L'ambito di un hook dipende dal tipo di hook. Alcuni hook possono essere impostati solo con ambito globale; altri possono anche essere impostati solo per un thread specifico, come illustrato nella tabella seguente.

Gancio Ambito
WH_CALLWNDPROC Thread o globale
WH_CALLWNDPROCRET Thread o globale
WH_CBT Thread o globale
WH_DEBUG Thread o globale
WH_FOREGROUNDIDLE Thread o globale
WH_GETMESSAGE Thread o globale
WH_JOURNALPLAYBACK Solo globale
WH_JOURNALRECORD Solo globale
WH_KEYBOARD Thread o globale
WH_KEYBOARD_LL Solo globale
WH_MOUSE Thread o globale
WH_MOUSE_LL Solo globale
WH_MSGFILTER Thread o globale
WH_SHELL Thread o globale
WH_SYSMSGFILTER Solo globale

Per un tipo di hook specificato, gli hook di thread vengono chiamati prima, quindi hook globali. Tenere presente che i WH_MOUSE, WH_KEYBOARD, WH_JOURNAL*, WH_SHELL e hook di basso livello possono essere chiamati sul thread che ha installato l'hook anziché sul thread che elabora l'hook. Per questi hook, è possibile che gli hook a 32 bit e a 64 bit vengano chiamati se un hook a 32 bit è davanti a un hook a 64 bit nella catena di hook.

Gli hook globali sono una risorsa condivisa e l'installazione di una influisce su tutte le applicazioni nello stesso desktop del thread chiamante. Tutte le funzioni hook globali devono trovarsi nelle librerie. Gli hook globali devono essere limitati alle applicazioni per scopi speciali o da usare come aiuto per lo sviluppo durante il debug dell'applicazione. Le librerie che non richiedono più un hook devono rimuovere la procedura hook.

Sviluppo di app di Windows Store Se dwThreadId è zero, le DLL hook finestra non vengono caricate in-process per i processi dell'app di Windows Store e il processo di broker Windows Runtime a meno che non siano installati da uno dei processi uiAccess (strumenti di accessibilità). La notifica viene recapitata sul thread del programma di installazione per questi hook:

  • WH_JOURNALPLAYBACK
  • WH_JOURNALRECORD
  • WH_KEYBOARD
  • WH_KEYBOARD_LL
  • WH_MOUSE
  • WH_MOUSE_LL
Questo comportamento è simile a quello che accade quando si verifica una mancata corrispondenza dell'architettura tra la DLL hook e il processo dell'applicazione di destinazione, ad esempio quando la DLL hook è a 32 bit e il processo dell'applicazione a 64 bit.

Esempio

Per un esempio, vedere Installazione e rilascio di procedure hook.

Nota

L'intestazione winuser.h definisce SetWindowsHookEx come alias che seleziona automaticamente la versione ANSI o Unicode di questa funzione in base alla definizione della costante del preprocessore UNICODE. La combinazione dell'utilizzo dell'alias indipendente dalla codifica con il codice che non è indipendente dalla codifica può causare mancate corrispondenze che generano errori di compilazione o di runtime. Per altre informazioni, vedere Convenzioni per i prototipi di funzioni.

Requisiti

Requisito Valore
Client minimo supportato Windows 2000 Professional [solo app desktop]
Server minimo supportato Windows 2000 Server [solo app desktop]
Piattaforma di destinazione Windows
Intestazione winuser.h (include Windows.h)
Libreria User32.lib
DLL User32.dll
Set di API ext-ms-win-ntuser-window-l1-1-0 (introdotto in Windows 8)

Vedi anche

Funzione CallNextHookEx

Funzione CallWindowProc

Funzione UnhookWindowsHookEx

CBTProc

CallWndProc

CallWndRetProc

DebugProc

ForegroundIdleProc

GetMsgProc

JournalPlaybackProc

JournalRecordProc

KeyboardProc

LowLevelKeyboardProc

LowLevelMouseProc

MessageProc

MouseProc

ShellProc

SysMsgProc

Informazioni concettuali

Hook