VB6实现键盘鼠标全局Hook

(声明:魏滔序原创,转贴请注明出处。)
标准模块(mHook):
Option Explicit

Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_CANCELJOURNAL = &H4B

Private Type POINTAPI
    x As Long
    y As Long
End Type

Private Type TMSG
    hwnd As Long
    Message As Long
    wParam As Long
    lParam As Long
    Time As Long
    PT As POINTAPI
End Type

Public hJouHook As Long, hAppHook As Long, lpHooker As Long

Public Function JouHookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If nCode < 0 Then
        JouHookProc = CallNextHookEx(hJouHook, nCode, wParam, lParam)
        Exit Function
    End If

    Call CallEvent(lpHooker, lParam)
    Call CallNextHookEx(hJouHook, nCode, wParam, lParam)
End Function

Public Function AppHookProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If nCode < 0 Then
        AppHookProc = CallNextHookEx(hAppHook, nCode, wParam, lParam)
        Exit Function
    End If

    Dim msg As TMSG
    CopyMemory msg, ByVal lParam, Len(msg)

    Select Case msg.Message
        Case WM_CANCELJOURNAL
            If wParam = 1 Then Call CallEvent(lpHooker, WM_CANCELJOURNAL)
    End Select
    Call CallNextHookEx(hAppHook, nCode, wParam, ByVal lParam)
End Function

Private Sub CallEvent(ByVal lpObj As Long, ByVal lParam As Long)
    Dim Hooker As Hooker
    CopyMemory Hooker, lpObj, 4&
    Hooker.CallEvent lParam
    CopyMemory Hooker, 0&, 4&
End Sub


类模块(Hooker):
Option Explicit
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
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
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long

Private Const WH_JOURNALRECORD = &H0
Private Const WH_GETMESSAGE = &H3
Private Const WM_CANCELJOURNAL = &H4B

Private Const WM_KEYDOWN = &H100
Private Const WM_KEYUP = &H101
Private Const WM_MOUSEMOVE = &H200
Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202
Private Const WM_LBUTTONDBLCLK = &H203
Private Const WM_RBUTTONDOWN = &H204
Private Const WM_RBUTTONUP = &H205
Private Const WM_RBUTTONDBLCLK = &H206
Private Const WM_MBUTTONDOWN = &H207
Private Const WM_MBUTTONUP = &H208
Private Const WM_MBUTTONDBLCLK = &H209
Private Const WM_MOUSEWHEEL = &H20A
Private Const WM_SYSTEMKEYDOWN = &H104
Private Const WM_SYSTEMKEYUP = &H105

Private Type EVENTMSG
    wMsg As Long
    lParamL As Long
    lParamH As Long
    msgTime As Long
    hWndMsg As Long
End Type

Private EMSG As EVENTMSG

Public Event MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
Public Event KeyDown(KeyCode As Integer, Shift As Integer)
Public Event KeyUp(KeyCode As Integer, Shift As Integer)
Public Event SysKeyDown(KeyCode As Integer)
Public Event SysKeyUp(KeyCode As Integer)

Public Sub CreateHook()
    If hJouHook = 0 Then hJouHook = SetWindowsHookEx(WH_JOURNALRECORD, AddressOf JouHookProc, App.hInstance, 0)
    If hAppHook = 0 Then hAppHook = SetWindowsHookEx(WH_GETMESSAGE, AddressOf AppHookProc, App.hInstance, App.ThreadID)
End Sub

Public Property Get HookState() As Boolean
    If hAppHook = 0 Then
        HookState = False
    Else
        HookState = True
    End If
End Property

Public Sub RemoveHook()
    UnhookWindowsHookEx hAppHook: hAppHook = 0
    UnhookWindowsHookEx hJouHook: hJouHook = 0
End Sub

Private Sub Class_Initialize()
    lpHooker = ObjPtr(Me)
End Sub

Private Sub Class_Terminate()
    If hJouHook Or hAppHook Then RemoveHook
End Sub

Friend Sub CallEvent(ByVal lParam As Long)
    Dim i As Integer, j As Integer, K As Integer, s As String

    If lParam = WM_CANCELJOURNAL Then
        hJouHook = 0: CreateHook
        Exit Sub
    End If

    CopyMemory EMSG, ByVal lParam, Len(EMSG)

    Select Case EMSG.wMsg
        Case WM_KEYDOWN
            If GetAsyncKeyState(vbKeyShift) Then j = (j Or 1)
            If GetAsyncKeyState(vbKeyControl) Then j = (j Or 2)
            If GetAsyncKeyState(vbKeyMenu) Then j = (j Or 4)

            s = Hex(EMSG.lParamL)
            K = (EMSG.lParamL And &HFF)

            RaiseEvent KeyDown(K, j)

            s = Left$(s, 2) & Right$("00" & Hex(K), 2)
            EMSG.lParamL = CLng("&h" & s)
            CopyMemory ByVal lParam, EMSG, Len(EMSG)

        Case WM_KEYUP
            If GetAsyncKeyState(vbKeyShift) Then j = (j Or 1)
            If GetAsyncKeyState(vbKeyControl) Then j = (j Or 2)
            If GetAsyncKeyState(vbKeyMenu) Then j = (j Or 4)
            s = Hex(EMSG.lParamL)
            K = (EMSG.lParamL And &HFF)

            RaiseEvent KeyUp(K, j)

            s = Left$(s, 2) & Right$("00" & Hex(K), 2)
            EMSG.lParamL = CLng("&h" & s)
            CopyMemory ByVal lParam, EMSG, Len(EMSG)

        Case WM_MOUSEMOVE
            If GetAsyncKeyState(vbKeyLButton) Then i = (i Or 1)
            If GetAsyncKeyState(vbKeyRButton) Then i = (i Or 2)
            If GetAsyncKeyState(vbKeyMButton) Then i = (i Or 4)
            If GetAsyncKeyState(vbKeyShift) Then j = (j Or 1)
            If GetAsyncKeyState(vbKeyControl) Then j = (j Or 2)
            If GetAsyncKeyState(vbKeyMenu) Then j = (j Or 4)

            RaiseEvent MouseMove(i, j, CSng(EMSG.lParamL), CSng(EMSG.lParamH))

        Case WM_LBUTTONDOWN, WM_RBUTTONDOWN, WM_MBUTTONDOWN
            If GetAsyncKeyState(vbKeyShift) Then i = (i Or 1)
            If GetAsyncKeyState(vbKeyControl) Then i = (i Or 2)
            If GetAsyncKeyState(vbKeyMenu) Then i = (i Or 4)

            RaiseEvent MouseDown(2 ^ ((EMSG.wMsg - 513) / 3), i, CSng(EMSG.lParamL), CSng(EMSG.lParamH))

        Case WM_LBUTTONUP, WM_RBUTTONUP, WM_MBUTTONUP
            If GetAsyncKeyState(vbKeyShift) Then i = (i Or 1)
            If GetAsyncKeyState(vbKeyControl) Then i = (i Or 2)
            If GetAsyncKeyState(vbKeyMenu) Then i = (i Or 4)

            RaiseEvent MouseUp(2 ^ ((EMSG.wMsg - 514) / 3), i, CSng(EMSG.lParamL), CSng(EMSG.lParamH))

        Case WM_SYSTEMKEYDOWN
            s = Hex(EMSG.lParamL)
            K = (EMSG.lParamL And &HFF)

            If K <> vbKeyMenu Then RaiseEvent SysKeyDown(K)

            s = Left$(s, 2) & Right$("00" & Hex(K), 2)
            EMSG.lParamL = CLng("&h" & s)
            CopyMemory ByVal lParam, EMSG, Len(EMSG)

        Case WM_SYSTEMKEYUP
            s = Hex(EMSG.lParamL)
            K = (EMSG.lParamL And &HFF)

            If K <> vbKeyMenu Then RaiseEvent SysKeyUp(K)

            s = Left$(s, 2) & Right$("00" & Hex(K), 2)
            EMSG.lParamL = CLng("&h" & s)
            CopyMemory ByVal lParam, EMSG, Len(EMSG)

        Case Else
    End Select
End Sub

应网友要求,在此补充示例代码
Option Explicit
Private WithEvents Hooker As Hooker

Private Sub Form_Load()
    Set Hooker = New Hooker
    Hooker.CreateHook
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Hooker.RemoveHook
    Set Hooker = Nothing
End Sub

Private Sub Hooker_KeyUp(KeyCode As Integer, Shift As Integer)
    Debug.Print KeyCode, Shift
End Sub

Private Sub Hooker_MouseDown(Button As Integer, Shift As Integer, x As Single, y As Single)
    Debug.Print Button, Shift, x, y
End Sub

Private Sub Hooker_MouseMove(Button As Integer, Shift As Integer, x As Single, y As Single)
    Debug.Print Button, Shift, x, y
End Sub

Private Sub Hooker_MouseUp(Button As Integer, Shift As Integer, x As Single, y As Single)
    Debug.Print Button, Shift, x, y
End Sub

Private Sub Hooker_SysKeyDown(KeyCode As Integer)
    Debug.Print KeyCode
End Sub

Private Sub Hooker_SysKeyUp(KeyCode As Integer)
    Debug.Print KeyCode
End Sub

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
VB HookAPI是一种在Visual Basic中使用的编程技术,用于拦截和修改Windows操作系统的API调用。它可以通过拦截API函数的调用来监视和处理特定的系统事件和消息。 通过使用VB HookAPI,我们可以实现许多有趣和有用的功能。例如,我们可以拦截键盘鼠标的输入,以便在特定按键或鼠标动作时执行特定的操作。我们还可以拦截窗口消息,并根据需要修改或禁止其执行。此外,可以利用VB HookAPI来实现对窗口的监视和控制,包括窗口焦点的管理、窗口的移动和调整大小等。 VB HookAPI的实现通常包括以下步骤:首先,我们需要确定要拦截的API函数,并在代码中声明它们的外部函数。然后,我们需要创建一个钩子过程(Hook Procedure),它会接收系统的消息和事件,并对其进行处理。接下来,我们使用VB HookAPI函数来安装和卸载钩子,并将钩子过程链接到特定的系统事件或消息上。最后,我们可以在钩子过程中编写我们自己的代码,用于处理相应的系统事件和消息。 需要注意的是,VB HookAPI需要一定的编程经验和对Windows操作系统的了解。此外,使用钩子技术需要谨慎,因为不正确的使用可能导致系统不稳定或产生安全风险。在使用VB HookAPI时,我们需要确保只拦截需要处理的事件和消息,并在不需要时及时卸载钩子,以确保系统的稳定和安全。 总的来说,VB HookAPI是一种强大的编程技术,可以让我们在Visual Basic中实现对系统事件和消息的监视和控制。通过合理运用它,我们可以实现各种功能和效果,为我们的应用程序增添更多的灵活性和个性化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值