VB6 WH_GETMESSAGE message hook

让人想犯罪 __ 提交于 2019-12-11 19:17:25

问题


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?

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

回答1:


  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:

    code [in]

    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/en-us/library/windows/desktop/ms644981%28v=vs.85%29.aspx

    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.

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


来源:https://stackoverflow.com/questions/15756386/vb6-wh-getmessage-message-hook

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!