OVH Cloud OVH Cloud

Chaine de Hook

6 réponses
Avatar
Alain CROS
Bonjour.

Le code suivant installe 2 CBTHook puis affiche successivement 2 Msgbox.
La première Msgbox est bien affectée par les 2 Hook, puis la seconde n'est pas affectée puisque les hook ont été supprimés.

Si je passe en commentaire la ligne comportant CallNextHookEx, je me serais attendu au fonctionnement suivant :
Le Hook2 affecte la première Msgbox puis le Hook1 affecte la seconde Msgbox.
Mais il n'en est rien, le Hook1 n'est pas éxécuté?

Quelqu'un aurait'il une explication?

Merci.

Alain CROS

Private Declare Function CallNextHookEx& _
Lib "user32.dll" _
(ByVal hHook&, ByVal ncode&, ByVal wParam&, ByRef lParam As Any)

Private Declare Function SetDlgItemText& _
Lib "user32" Alias "SetDlgItemTextA" _
(ByVal hDlg&, ByVal nIDDlgItem&, ByVal lpString$)

Private Declare Function GetCurrentThreadId& _
Lib "kernel32" _
()

Private Declare Function SetWindowsHookEx& _
Lib "user32" Alias "SetWindowsHookExA" _
(ByVal idHook&, ByVal lpfn&, ByVal hmod&, ByVal dwThreadId&)

Private Declare Function UnhookWindowsHookEx& _
Lib "user32" _
(ByVal hHook&)

Private lgHook1&, lgHook2&

Sub MsgBoxPerso()
Const WH_CBT& = &H5
lgHook1 = SetWindowsHookEx(WH_CBT, AddressOf LeHook1, 0&, GetCurrentThreadId)
lgHook2 = SetWindowsHookEx(WH_CBT, AddressOf LeHook2, 0&, GetCurrentThreadId)
MsgBox "HookChain", vbYesNo
MsgBox "HookChain", vbYesNo
UnhookWindowsHookEx lgHook1
End Sub

Private Function LeHook1&(ByVal lMsg&, ByVal wParam&, ByRef lParam&)
Const HCBT_ACTIVATE& = &H5
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, 7&, "Hook1"
UnhookWindowsHookEx lgHook1
End If
LeHook1 = False
End Function

Private Function LeHook2&(ByVal lMsg&, ByVal wParam&, ByRef lParam&)
Const HCBT_ACTIVATE& = &H5
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, 6&, "Hook2"
UnhookWindowsHookEx lgHook2
End If
LeHook2 = False
LeHook2 = CallNextHookEx(ByVal lgHook2, ByVal lMsg, ByVal wParam, lParam)
End Function

6 réponses

Avatar
Jacques93
Bonjour,

Alain CROS wrote:
Bonjour.

Le code suivant installe 2 CBTHook puis affiche successivement 2 Msgbox.
La première Msgbox est bien affectée par les 2 Hook, puis la seconde n'est pas affectée puisque les hook ont été supprimés.

Si je passe en commentaire la ligne comportant CallNextHookEx, je me serais attendu au fonctionnement suivant :
Le Hook2 affecte la première Msgbox puis le Hook1 affecte la seconde Msgbox.
Mais il n'en est rien, le Hook1 n'est pas éxécuté?

Quelqu'un aurait'il une explication?




Pas d'explication, mais deux constatations :
en ajoutant des traces :
=================================================================== Private Function LeHook1&(ByVal lMsg&, ByVal wParam&, ByRef lParam&)
Const HCBT_ACTIVATE& = &H5
If lMsg = HCBT_ACTIVATE Then
Debug.Print "Hook1"
SetDlgItemText wParam, 7&, "Hook1"
UnhookWindowsHookEx lgHook1
End If
LeHook1 = False
End Function

Private Function LeHook2&(ByVal lMsg&, ByVal wParam&, ByRef lParam&)
Const HCBT_ACTIVATE& = &H5
If lMsg = HCBT_ACTIVATE Then
Debug.Print "Hook2"
SetDlgItemText wParam, 6&, "Hook2"
UnhookWindowsHookEx lgHook2
End If
LeHook2 = False
'LeHook2 = CallNextHookEx(ByVal lgHook2, ByVal lMsg, ByVal wParam,
lParam)
End Function
===================================================================== On voit que le Hook1 est executé mais n'a pas d'effet sur le texte du
bouton.

Si l'on met en remarque la ligne :

UnhookWindowsHookEx lgHook1

On a le comportement auquel tu t'attendais.

Dur pour un vendredi soir. Je vais faire un Hook par la cuisine :-)
--
Cordialement,

Jacques.
Avatar
parci
On Fri, 15 Apr 2005 17:39:00 +0200, "Alain CROS" wrote:

Bonjour.

Le code suivant installe 2 CBTHook puis affiche successivement 2 Msgbox.
La première Msgbox est bien affectée par les 2 Hook, puis la seconde n'est pas affectée puisque les hook ont été supprimés.

Si je passe en commentaire la ligne comportant CallNextHookEx, je me serais attendu au fonctionnement suivant :
Le Hook2 affecte la première Msgbox puis le Hook1 affecte la seconde Msgbox.



Ca marche pas comme ça : un hook capture tous les messages avant de
passer au hook suivant (s'il en existe un) dans la chaîne.
Si tu laissais les hooks, tu aurais donc une séquence :
MsgBox "HookChain", vbYesNo
HCBT_ACTIVATE dans LeHook1
HCBT_ACTIVATE dans LeHook2
MsgBox "HookChain", vbYesNo
HCBT_ACTIVATE dans LeHook1
HCBT_ACTIVATE dans LeHook2

Donc pourquoi faire 2 hooks ?

Mais il n'en est rien, le Hook1 n'est pas éxécuté?

Quelqu'un aurait'il une explication?



Je ne comprends pas très bien ce que tu veux. Mais ce qui est certain,
c'est que la CBTProc (tes fonctions LeHook1& et LeHook2&) doit
retourner 1 si tu veux que le hook soit effectif, sinon la fonction
doit retourner la valeur de CallNextHookEx.

Ca devrait donc plutôt s'écrire comme ça :

Private Function LeHook1&(ByVal lMsg&, ByVal wParam&, ByRef lParam&)
Const HCBT_ACTIVATE& = &H5
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, 7&, "Hook1"
UnhookWindowsHookEx lgHook1
LeHook1 = 1
lgHook1 = 0
Exit Function
End If

LeHook1 = CallNextHookEx(ByVal lgHook1, ByVal lMsg, ByVal wParam,
lParam)
End Function
Avatar
Alain CROS
Bonjour.

Donc pourquoi faire 2 hooks ?



Le but est de comprendre le fonctionnement d'une chaîne de Hook qui apparemment ne fonctionne pas (dans ce cas là) comme spécifié
dans la doc.

Je ne comprends pas très bien ce que tu veux. Mais ce qui est certain,
c'est que la CBTProc (tes fonctions LeHook1& et LeHook2&) doit
retourner 1 si tu veux que le hook soit effectif, sinon la fonction
doit retourner la valeur de CallNextHookEx.




Là, c'est un truc qui ne correspond pas non plus à la doc.

Return Values

For operations corresponding to the following CBT hook codes, the return value must be 0 to allow the operation, or 1 to prevent it:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND

Si tu as des explications complémentaires, n'hésite pas.

Alain CROS.
Avatar
Alain CROS
Bonjour.

Merci pour ta réponse qui ne m'éclaire guère.

Apparemment, si on n'utilise pas CallNextHookEx dans le premier hook, le second hook est exécuté mais n'a pas d'action. ????

Ce n'est pas ce que je croyais comprendre de ma doc.

If a hook procedure does not call CallNextHookEx, Windows does not call the hook procedures installed before the current hook
procedure was installed.

Si ton Hook cuisine t'avais inspiré, n'hésite pas.

Alain CROS

"Jacques93" a écrit dans le message de news:
Avatar
François Picalausa
Hello,

Pour CallNextHookEx, il est dit:
This value is returned by the next hook procedure in the chain. The current
hook procedure must also return this value. The meaning of the return value
depends on the hook type. For more information, see the descriptions of the
individual hook procedures.

Maintenant, pour savoir pourquoi ça ne marche pas, j'ai une théorie aussi
;-)
Quand tu affiche Msgbox1, tu active une fenêtre (celle de la messagebox) et
tu vires hook2.
Ensuite, quand MsgBox1 est fermée, alors que MsgBox2 n'est pas activée,
l'IDE est réactivée... et on vire hook1

Par conséquent, avec 3 hooks, ça fonctionne:
'mêmes déclarations d'API
Private Const HCBT_ACTIVATE& = &H5

Private lgHook1 As Long, lgHook2 As Long, lgHook3 As Long

Sub MsgBoxPerso()
Const WH_CBT& = &H5
lgHook1 = SetWindowsHookEx(WH_CBT, AddressOf LeHook1, 0&,
GetCurrentThreadId)
lgHook2 = SetWindowsHookEx(WH_CBT, AddressOf LeHook2, 0&,
GetCurrentThreadId)
lgHook3 = SetWindowsHookEx(WH_CBT, AddressOf LeHook3, 0&,
GetCurrentThreadId)
MsgBox "HookChain", vbYesNo
MsgBox "HookChain", vbYesNo
UnhookWindowsHookEx lgHook1
End Sub

Private Function LeHook1(ByVal lMsg&, ByVal wParam&, ByRef lParam&) As Long
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, 7&, "Hook1"
Debug.Print UnhookWindowsHookEx(lgHook1)
End If

LeHook1 = CallNextHookEx(ByVal lgHook1, ByVal lMsg, ByVal wParam,
lParam)
End Function

Private Function LeHook2(ByVal lMsg&, ByVal wParam&, ByRef lParam&) As Long
If lMsg = HCBT_ACTIVATE Then
Debug.Print UnhookWindowsHookEx(lgHook2)
End If

LeHook2 = 0
End Function

Private Function LeHook3(ByVal lMsg&, ByVal wParam&, ByRef lParam&) As Long
If lMsg = HCBT_ACTIVATE Then
SetDlgItemText wParam, 6&, "Hook3"
Debug.Print UnhookWindowsHookEx(lgHook3)
End If

LeHook3 = 0
End Function

--
François Picalausa

"Alain CROS" a écrit dans le message de news:

Je ne comprends pas très bien ce que tu veux. Mais ce qui est
certain, c'est que la CBTProc (tes fonctions LeHook1& et LeHook2&)
doit retourner 1 si tu veux que le hook soit effectif, sinon la
fonction doit retourner la valeur de CallNextHookEx.




Là, c'est un truc qui ne correspond pas non plus à la doc.

Return Values

For operations corresponding to the following CBT hook codes, the
return value must be 0 to allow the operation, or 1 to prevent it:
HCBT_ACTIVATE
HCBT_CREATEWND
HCBT_DESTROYWND
HCBT_MINMAX
HCBT_MOVESIZE
HCBT_SETFOCUS
HCBT_SYSCOMMAND


Avatar
Alain CROS
Bonjour.

C'est tout à fais ça.
Merci beaucoup.

Alain CROS

"François Picalausa" a écrit dans le message de news:
Hello,