VB6 WH_GETMESSAGE消息挂钩 [英] VB6 WH_GETMESSAGE message hook

查看:193
本文介绍了VB6 WH_GETMESSAGE消息挂钩的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

朋友您好,我想监视表单上的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

推荐答案

  1. GetMsgProc过滤器函数中跳过对CallNextHookEx的调用通常是一个坏主意.如果执行此操作,则不会调用链中的其他过滤器功能.也许,开发机器上什么都没有,但是在野外"还会有其他安装钩子的应用程序.如果您阻止它们的过滤器功能被调用,这些应用程序将无法正常工作.
  2. 您可能不希望分析仅从队列中偷看而又未从队列中删除的消息.对于已从队列中删除的邮件,用wParam = PM_REMOVE调用GetMsgProc.
  3. VB6或C ++或任何其他语言,忽略MSDN的API规范是一种致命的做法.这是GetMsgProc过滤器函数应基于其第一个参数的值做出决定的方式:

  1. Skipping the call to CallNextHookEx in GetMsgProc 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.
  2. You probably wouldn't want to analyze messages that have been merely peeked from the queue, but not removed from it. GetMsgProc is called with wParam = PM_REMOVE for messages that have been removed from queue.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆