VB6 WH_GETMESSAGE消息钩子
您好,朋友们,我想监视一个IP地址控件(由CreateWindowEx创建)的输入事件,它位于一个窗体上。我已经使用API SetWindowsHookEx来钩住WH_GETMESSAGE消息,但是现在我不能像C中那样将输入消息作为(MSG)lParam->message=WM_NULL来接收,所以我需要您的帮助,朋友们。你能给我答案吗 代码如下:VB6 WH_GETMESSAGE消息钩子,vb6,hook,Vb6,Hook,您好,朋友们,我想监视一个IP地址控件(由CreateWindowEx创建)的输入事件,它位于一个窗体上。我已经使用API SetWindowsHookEx来钩住WH_GETMESSAGE消息,但是现在我不能像C中那样将输入消息作为(MSG)lParam->message=WM_NULL来接收,所以我需要您的帮助,朋友们。你能给我答案吗 代码如下: Private Function GetMsgProc(ByVal nCode As Long, ByVal wParam As Long, ByR
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
GetMsgProc
filter函数中跳过对CallNextHookEx
的调用通常是个坏主意。如果执行此操作,则不会调用链中的其他筛选器函数。也许在开发人员的机器上没有,但是“在野外”会有其他安装了钩子的应用程序。如果您阻止调用这些应用程序的筛选函数,它们将出现错误行为wParam=PM_REMOVE
调用code>GetMsgProcGetMsgProc
filter函数根据其第一个参数的值作出决定的方式:
代码[输入]
指定钩子过程是否必须处理
消息如果代码是HC_动作,则钩子过程必须处理
消息如果代码小于零,则钩子过程必须通过
消息发送到CallNextHookEx函数,无需进一步处理和
应返回CallNextHookEx返回的值
虽然CopyMemory
应该可以工作(假设您正确声明了它),但我不会在这里为它操心。将filter函数的第三个参数声明为ByRef lParam为MSG
,这完全可以
下面是应该放在标准模块中的代码(与安装挂钩的任何其他代码一样)。如果我用它来嗅探WM_RBUTTONDOWN
消息,比如说,TextBox
控件放在主窗体上,它对我很有用
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
挂钩以以下方式安装在表单模块中:
SetHook App.ThreadID, Me.Text1.hWnd
你会展示你的代码吗(最重要的部分)?你如何声明
p
变量?我已经声明p为MSG,私有类型MSG hWnd为Long message为Long wParam为Long lParam为Long time为Long pt为POINTAPI End Type所以你的钩子函数不会被调用,你不会崩溃,问题是p.message
总是WM\u NULL
。对吗?不,我只是想吃掉这条消息,这样表单就不会响应它。根据MSDN,我必须将这条消息设置为VM_NULL。非常感谢!我已经将filter函数的第三个参数声明为ByRef lParam as MSG,并将lParam.message=VM_NULL,这样它就可以工作了。@Sanycn噢,您想首先修改捕获的消息吗?你的问题(对我)不清楚。你能不能回去一会儿,把问题整理一下,以便更好地反映这一点?