使用的API  代码如下Private Sub Form_Load()
Dim ret As Long
'记录原来的window程序地址
preWinProc = GetWindowLong(Me.hWnd, GWL_WNDPROC)
'用自定义程序代替原来的window程序
ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, AddressOf wndproc)
idHotKey = 1 'in the range &h0000 through &hBFFF
Modifiers = MOD_CONTROL '辅助键为Alt
uVirtKey1 = vbKey1 '注册的热键为Alt+Q
'注册热键
ret = RegisterHotKey(Me.hWnd, idHotKey, Modifiers, uVirtKey1)
If ret = 0 Then
MsgBox "注册热键失败,请使用其它热键!", vbCritical, "错误"
End If
End SubPrivate Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Dim ret As Long
'取消Message的截取,使之送往原来的window程序
ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, preWinProc)
Call UnregisterHotKey(Me.hWnd, uVirtKey1)
End Sub
模块如下:Option ExplicitDeclare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function RegisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Declare Function UnregisterHotKey Lib "user32" (ByVal hWnd As Long, ByVal id As Long) As LongPublic Const WM_HOTKEY = &H312
Public Const MOD_ALT = &H1
Public Const MOD_CONTROL = &H2
Public Const MOD_SHIFT = &H4
Public Const GWL_WNDPROC = (-4)Public preWinProc As Long
Public Modifiers As Long, uVirtKey1 As Long, idHotKey As LongPrivate Type taLong
ll As Long
End TypePrivate Type t2Int
lWord As Integer
hword As Integer
End TypePublic Function wndproc(ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim lp As taLong, i2 As t2IntIf Msg = WM_HOTKEY Then
If wParam = idHotKey Then
lp.ll = lParam
LSet i2 = lp
If (i2.lWord = Modifiers) And i2.hword = uVirtKey1 Then
Form1.Visible = Not Form1.Visible
End If
End If
End If
'如果不是热键信息则调用原来的程序
wndproc = CallWindowProc(preWinProc, hWnd, Msg, wParam, lParam)
End Function
问题:
1、按下热键不放,会不停的执行事件,如何实现按下不放只执行一次事件,放开再按再执行。
2、多次出现问题,热键按下后已放开,但是系统还在不停的执行事件,应该是系统认为热键按下后没放开,
   请问这种问题是什么原因,如何解决。
谢谢高手指教。

解决方案 »

  1.   

    没仔细看代码看了你的问题,可不可以加个全局变量作为判断条件呢?比如在事件中true执行,false跳过
      

  2.   


    n... 我写的一个代码想追求这种效果.. lz 写的代码想放弃这种效果
    多么xx的异步,这样做有什么不好?用子类化实现,就得弄个标志类似这样:dim i as boolean
    function wndproc(...) as long 
    if msg=wm_hotkey then
     if i then exit function else i = true :xxxxxxx : i=false
    end if
    end function不过这样做可能不是最好的方法, 用peekmessage 做,可以很方便的弄成你想要的效果,不过我还是觉得带异步的效果好.........
      

  3.   

    顶一下 
    问题依然没有解决这样做标志不行的  要能判断键盘放开才行还有就是CTRL键按下 放开后 系统认为CTRL没有放开
    会不会和别的软件热键有冲突导致的
      

  4.   

    根据MSDN中的WM_KEYUP消息的约定
    WM_KEYUP
    nVirtKey = (int) wParam;    // virtual-key code
    lKeyData = lParam;          // key dataParameters
    nVirtKey
    Value of wParam. Specifies the virtual-key code of the nonsystem key.
    lKeyData
    Value of lParam. Specifies the repeat count, scan code, extended-key flag, context code, previous key-state flag, and transition-state flag, as shown in the following table. Value Description
    0–15 Specifies the repeat count for the current message. The value is the number of times the keystroke is auto-repeated as a result of the user holding down the key. The repeat count is always one for a WM_KEYUP message.
    16–23 Specifies the scan code. The value depends on the original equipment manufacturer (OEM).
    24 Specifies whether the key is an extended key, such as the right-hand alt and ctrl keys that appear on an enhanced 101- or 102-key keyboard. The value is 1 if it is an extended key; otherwise, it is 0.
    25–28 Reserved; do not use.
    29 Specifies the context code. The value is always 0 for a WM_KEYUP message.
    30 Specifies the previous key state. The value is always 1 for a WM_KEYUP message.
    31 Specifies the transition state. The value is always 1 for a WM_KEYUP message.似乎应该判断热键释放的消息
    把你上面代码If wParam = idHotKey Then
    改成If wParam = idHotKey and ((lParam and &he0ff)=&hc001) Then
    试试