VB6 WH_GETMESSAGE message widget
Hi friends, I want to keep track of input IP management events (generated by CreateWindowEx) that are on the form. I used the SetWindowsHookEx API to connect the WH_GETMESSAGE message, but now I cannot eat the input message as (MSG) lParam-> message = WM_NULL as in C, So I need your help friends. can you give me a solution?
here is the code:
Private Function GetMsgProc(ByVal nCode As Long, ByVal wParam As Long, ByRef lParam As Long) As Long
CopyMemory p, ByVal lParam, LenB(p)
If p.message = WM_RBUTTONDOWN And GetParent(p.hWnd) = lngHWNDCtl Then
GetMsgProc = 0
Else
GetMsgProc = CallNextHookEx(hHook, nCode, wParam, ByVal lParam)
End If
End Function
Public Sub SetHook(ByVal lngThread As Long, lngHWND As Long, bFlag As Boolean)
If bFlag Then
lngHWNDCtl = lngHWND
hHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf GetMsgProc, 0, lngThread)
Else
If hHook Then UnhookWindowsHookEx hHook
End If
End Sub
source to share
- Skipping a call
CallNextHookEx
to aGetMsgProc
filter function is generally a bad idea. If you do this, no other filter functions in the chain will be called. They may not be on the dev machine, but there will be other applications "in the wild" that have hooks installed. These apps will misbehave if you disable their filtering functionality. - You probably don't want to parse messages that were just peeking out of the queue but not being removed from it.
GetMsgProc
called withwParam = PM_REMOVE
for messages that have been removed from the queue. -
VB6 or C ++ or whatever, it's deadly practice to ignore the MSDN spec for the API. This is how the filter function
GetMsgProc
should make a decision based on the value of its first argument:code [in]
Indicates whether the hook procedure should process the message. If the code is HC_ACTION, the hook procedure should process the message. If the code is less than zero, the hook procedure must go through the CallNextHookEx function message without further processing and must return the value returned by CallNextHookEx.
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644981%28v=vs.85%29.aspx
While it
CopyMemory
should work (assuming you state it correctly), I wouldn't bother with it here. It's okay OK to declare the third parameter of the filter function asByRef lParam As MSG
.
Here is the code that should be put into the standard module (like any other code that sets hooks). It works for me if I use it to sniff posts WM_RBUTTONDOWN
like TextBox
posted on the main form.
Option Explicit
'http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805%28v=vs.85%29.aspx
Private Type tagPOINT
x As Long
y As Long
End Type
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958%28v=vs.85%29.aspx
Private Type MSG
hWnd As Long
message As Long
wParam As Long
lParam As Long
time As Long
pt As tagPOINT
End Type
Private bHooked As Boolean
Private hHook As Long
Private hHwndToSniff As Long
Private Const HC_Action As Long = &H0
Private Const PM_NOREMOVE As Long = &H0
Private Const PM_REMOVE As Long = &H1
Private Const WH_GETMESSAGE As Long = &H3
Private Const WM_RBUTTONDOWN As Long = &H204
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644974%28v=vs.85%29.aspx
Private Declare Function CallNextHookEx Lib "user32" _
(ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx
Private Declare Function SetWindowsHookEx Lib "user32" _
Alias "SetWindowsHookExA" _
(ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644993%28v=vs.85%29.aspx
Private Declare Function UnhookWindowsHookEx Lib "user32" _
(ByVal hHook As Long) As Long
Public Sub RemoveHook()
If bHooked Then
UnhookWindowsHookEx hHook
bHooked = False
End If
End Sub
Public Sub SetHook(ByVal hThreadToHook As Long, hHwndFilter As Long)
If Not bHooked Then
hHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf GetMsgProc, 0, hThreadToHook)
If hHook > 0 Then
bHooked = True
hHwndToSniff = hHwndFilter
Else
Debug.Assert False
End If
End If
End Sub
'http://msdn.microsoft.com/en-us/library/windows/desktop/ms644981%28v=vs.85%29.aspx
Private Function GetMsgProc(ByVal uCode As Long _
, ByVal wParam As Long _
, ByRef lParam As MSG) As Long
If uCode = 0 Then
If wParam = PM_REMOVE Then
If lParam.message = WM_RBUTTONDOWN Then
If lParam.hWnd = hHwndToSniff Then
MsgBox "You right-clicked a text box!"
End If
End If
End If
End If
GetMsgProc = CallNextHookEx(hHook, uCode, wParam, lParam)
End Function
The hook is installed in the form module as follows:
SetHook App.ThreadID, Me.Text1.hWnd
source to share