VB6 WH_GETMESSAGE消息挂钩 [英] VB6 WH_GETMESSAGE message hook
问题描述
朋友您好,我想监视表单上的IP地址控件(由CreateWindowEx创建)的输入事件.我使用API SetWindowsHookEx来挂接WH_GETMESSAGE消息,但现在我不能将输入消息当作(MSG) lParam-> message = WM_NULL像在C中一样,所以我需要您的帮助,朋友.你能给我解决方法吗?
hello friends,i want to monitor an IP address control's(created by CreateWindowEx) input events which is on a form.i have used the API SetWindowsHookEx to hook WH_GETMESSAGE message ,but now i cannt eat the input message as (MSG)lParam->message = WM_NULL like in C,So i need your help,friends. can you give me the solution?
下面是代码:
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
过滤器函数中跳过对CallNextHookEx
的调用通常是一个坏主意.如果执行此操作,则不会调用链中的其他过滤器功能.也许,开发机器上什么都没有,但是在野外"还会有其他安装钩子的应用程序.如果您阻止它们的过滤器功能被调用,这些应用程序将无法正常工作. - 您可能不希望分析仅从队列中偷看而又未从队列中删除的消息.对于已从队列中删除的邮件,用
wParam = PM_REMOVE
调用GetMsgProc
. -
VB6或C ++或任何其他语言,忽略MSDN的API规范是一种致命的做法.这是
GetMsgProc
过滤器函数应基于其第一个参数的值做出决定的方式:
- Skipping the call to
CallNextHookEx
inGetMsgProc
filter function is generally a bad idea. If you do this then other filter functions in the chain will not be called. Maybe, there are none on a dev machine, but 'in the wild' there will be other applications that installed hooks. Those applications will misbehave if you prevent their filter functions from being called. - You probably wouldn't want to analyze messages that have been merely peeked from the queue, but not removed from it.
GetMsgProc
is called withwParam = PM_REMOVE
for messages that have been removed from queue. VB6 or C++ or whatever, it is a deadly practice to ignore MSDN specification for API. This is how
GetMsgProc
filter function should make a decision based on a value of its first argument:
代码 [输入]
指定挂钩过程是否必须处理 信息.如果代码是HC_ACTION,则挂钩过程必须处理 信息.如果代码小于零,则挂钩过程必须通过 消息发送给CallNextHookEx函数,而无需进一步处理和 应该返回CallNextHookEx返回的值.
Specifies whether the hook procedure must process the message. If code is HC_ACTION, the hook procedure must process the message. If code is less than zero, the hook procedure must pass the message to the CallNextHookEx function without further processing and should return the value returned by CallNextHookEx.
http://msdn.microsoft.com/zh-CN/library/windows/desktop/ms644981%28v=vs.85%29.aspx
尽管CopyMemory
应该可以工作(假设您正确声明了它),但在这里我不会打扰.将过滤器函数的第三个参数声明为ByRef lParam As MSG
是完全可以的.
Although CopyMemory
should work (assuming you declare it correctly), I wouldn't bother with it here. It's perfectly OK to declare 3rd parameter of filter function as ByRef lParam As MSG
.
这是应放在标准模块中的代码(与安装钩子的任何其他代码一样).如果我用它来嗅探WM_RBUTTONDOWN
消息到位于主窗体上的TextBox
控件,则对我有用.
Here is the code that should be placed in a standard module (as any other code that installs hooks). It works for me if I use it to sniff WM_RBUTTONDOWN
messages to, say, TextBox
control placed on a 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 a form module in the following fashion:
SetHook App.ThreadID, Me.Text1.hWnd
这篇关于VB6 WH_GETMESSAGE消息挂钩的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!