'===================MODE=====================
Option Explicit
Public 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
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Any) As Long
Public hHook As Long
Public Const WH_KEYBOARD = 2
'具体的钩子程序,本例中该过程被包含在Module1中
Public Function HookProc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    'On Error Resume Next
    Debug.Print iCode
    HookProc = 0 '表示要处理这个消息
    If iCode >= 0 Then
         '屏蔽ALT+F4组合键
        If wParam = 115 And (lParam And H20000000) <> 0 Then
            If (lParam And &HC000000) = 0 Then '是否进行ALT+F4操作
               HookProc = 1 '钩子吃掉这个消息
            End If
        End If
    End If
    'MsgBox "4"
    Call CallNextHookEx(hHook, iCode, wParam, lParam) '将消息传给下一个钩子
    'MsgBox "5"
End Function
Public Function EnableHook()
If hHook <> 0 Then
        Exit Function
End If
hHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf _
                          HookProc, App.hInstance, App.ThreadID)
    Form1.Caption = hHook
    
End FunctionPublic Function FreeHook()
If hHook <> 0 Then
        UnhookWindowsHookEx hHook
        hHook = 0
End If
End Function'=================FROM1================='安装钩子
Private Sub Command1_Click()
    Call EnableHook
End Sub
'卸载钩子
Private Sub Command2_Click()
    Call FreeHook
End SubPrivate Sub Form_Unload(Cancel As Integer)
    Call FreeHook
End SubPrivate Sub Text1_Change()
    On Error Resume Next
    Text2 = Chr(Text1)
End Sub'====================================================
'=================== 下面问题  ========================
'====================================================
上面代码, 为什么在钩子过程 hookproc里头 有下面的IF语句就会出错, 拿掉IF语句就不出错呢?
那个if语句是用来判断组合按键的!!!
        If wParam = 115 And (lParam And H20000000) <> 0 Then
            If (lParam And &HC000000) = 0 Then '是否进行ALT+F4操作
               HookProc = 1 '钩子吃掉这个消息
            End If
        End If
老师们来指点一下, 谢谢, 一直没搞明白!!!
还有这个(lParam And H20000000)像这样的啥意思, 根据什么原理来判断ALT按键状态的?

解决方案 »

  1.   

    Call CallNextHookEx(hHook, iCode, wParam, lParam)
    =>
    HookProc = CallNextHookEx(hHook, iCode, wParam, lParam)
      

  2.   

    这个一眼一看就有问题啊.H前少了个&.不过你的模块里添加了Option Explicit,怎么可能运行得起来呢?
      

  3.   

    太好了今天不断测试已经发现是少了&, 老马眼力太好了,一出手直接看出问题了后面那个组合判断ALT+F4我还不懂, 现在在看虚拟键和扫描键知识, 好像32位运算方面的东西, 慢慢看, 谢谢
      

  4.   

    谁能再帮忙解释一下
      If wParam = 115 And (lParam And &H20000000) <> 0 Then
      If (lParam And &HC000000) = 0 Then '是否进行ALT+F4操作这里为什么要用  &H20000000 来进行位运算而不用其它数字呢?
      

  5.   

    HOOK过程中,wparam是键码,lparam是一些组合信息,其中包含ALT键的状态.你这代码写得非常不规范,使用了魔法数,会把人看晕的.If wParam = 115 这里的115其实是VK_F4,声明个常量会让你的程序可读性大大增加.而lparam的第29位就是ALT键是否按下,按下为1,否则为零.具体情况查查MSDN吧.
      

  6.   

    谢谢老马指点, 我是在学习这个, 在网上找的一段代码上面说的那个错误让我头疼了1个星期, 我太笨了, 后来仔细看才知道少了个&lParam这个参数我已经知道了是个32位的 3个组合参数
    &h 00 00 00 00
    高8位 00=按下  C0=弹起
    中8位 扫描码
    低16位 按键次数和扩展功能你说的魔法数,意思是不是编程人员因为非常熟悉代码, 随便用了个“富含特定技巧”的数字?如果这样, 我就得搞明白, 这个数字是不是通用了,怕哪天换成 ALT+SHIFT+F4,能不能屏蔽就不知道了
      

  7.   

    '具体的钩子程序,本例中该过程被包含在Module1中
    Public Function HookProc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
        Debug.Print okEvent
        If okEvent = True Then
                   keybd_event vbKeyA, MapVirtualKey(vbKeyA, 0), 0, 0      '按下A键
                   keybd_event vbKeyA, MapVirtualKey(vbKeyA, 0), KEYEVENTF_KEYUP, 0      '释放A键
                   okEvent = False
        End If
        HookProc = 0 '表示要处理这个消息
        If iCode >= 0 Then
            '屏蔽ALT+F4组合键
            If wParam = 115 And (lParam And &H20000000) <> 0 Then
                If (lParam And &HC0000000) = 0 Then '是否进行ALT+F4操作 &H C0 00 00 00
                   okEvent = True
                   HookProc = 1 '钩子吃掉这个消息
                End If
            End If
        End If
        Call CallNextHookEx(hHook, iCode, wParam, lParam) '将消息传给下一个钩子
    End Function
    '打算测试一下屏蔽热键, 替代为 A,,,,怎么就发送不了A。。?怎么办。。
      

  8.   

    那些常量是不会变的,所以叫"常"量.具体的值要去MSDN里查,你搜索WH_KEYBOARD就会有相关的信息出来.