Come utilizzare correttamente SetWindowsHookEx & amp; CallNextHookEx
Domanda
Posso configurare correttamente un hook di Windows, ma sono confuso dalla linea in MSDN che dice " Chiamare la funzione CallNextHookEx per concatenare la procedura di hook successiva è facoltativo, ma è altamente raccomandato; in caso contrario, altre applicazioni che hanno installato hook non riceveranno notifiche hook e potrebbero comportarsi in modo errato di conseguenza. Dovresti chiamare CallNextHookEx a meno che non sia assolutamente necessario impedire che la notifica venga vista da altre applicazioni. & Quot ;.
Voglio essere un buon cittadino di programmazione e chiamare il prossimo hook. Ma la mia procedura hook è simile a questa:
LRESULT CALLBACK CBTProc(int code, WPARAM wp, LPARAM lp)
{
if (code != HCBT_CREATEWND)
{
// What do I do here? It's not the event I requested so how do I pass it on?
return 0;
}
// It's the code we want (create window)
CallNextHookEx(...);
...
}
Quindi, cosa succede nella procedura hook se il codice non è quello a cui sono interessato? Come posso chiamare il prossimo hook?
Modifica: Il problema principale è che un HHOOK viene restituito da SetWindowsHookEx e che deve essere passato alla funzione CallNextHookEx.
Aggiornamento: sembra che il parametro hook sia ignorato sulle piattaforme NT:
http://msdn.microsoft.com/en-us/library/ms644974.aspx
http://www.klenotic.com/pl/null_hhook/
Soluzione
Secondo i documenti, la cosa giusta da fare è passare gli argomenti che hai ricevuto direttamente a CallNextHookEx, esattamente come li hai ricevuti. Dovresti anche chiamare CallNextHookEx indipendentemente dal fatto che tu abbia deciso di gestire il messaggio hook.
Secondo MSDN , il primo parametro per CallNextHookEx
è ignorato su NT / XP / 2003 e per i sistemi operativi basati su Win95 precedenti dovrebbe essere il HHOOK
che hai ricevuto quando hai registrato il tuo hook con SetWindowsHookEx
. I documenti non specificano un valore per Windows 2000, ma poiché fanno parte della famiglia NT, un'ipotesi ragionevole è che venga ignorato anche lì.
Detto questo, un buon modo per codificare il metodo per i sistemi operativi della famiglia NT potrebbe essere questo:
LRESULT CALLBACK CBTProc( int code, WPARAM wp, LPARAM lp )
{
if( code == HCBT_CREATEWND )
ProcessCreateWnd( wp, lp );
return CallNextHookEx( 0, code, wp, lp );
}
void ProcessCreateWnd( WPARAM wp, LPARAM lp )
{
// my code here
}
Questo assicura che tu chiami sempre l'hook alla fine dell'elaborazione e rende difficile aggiungere accidentalmente un return
che aggirerà CallNextHookEx
.