想要做一个函数,功能如下:
    用参数传递快捷键和快捷键所要触发的事件,一旦按下该快捷键,就执行所指定的事件,如:
         SetShortCut("CTRL","A",Command1_click); '如果按下CTRL + A 就执行Command1_Click事件请问这个函数能实现吗?

解决方案 »

  1.   

    哈哈,我們知道菜單有快捷鍵的阿,菜單cmdMenu的click事件中調用command1_click就好啦!
      

  2.   

    '给你参考一下Private Sub form1_KeyDown(KeyCode As Integer, Shift As Integer)
      '窗体快捷键
      Dim btn As MSComctlLib.Button
      If Shift = vbCtrlMask Then
         Select Case KeyCode
           Case vbKeyP    '打印
               ....
           Case vbKeyA    '增加
               ...
         end select
      end if
    end sub
      

  3.   

    to lzqgj() 
    用定义热键的方法不是很好,很容易和其它软件的热键产生冲突 
      

  4.   

    这个问题可以灵活运用,你可以给这个FORM做个热键,比如它PREE了哪个键就执行相当的操作,不知道我说得对不对?
      

  5.   

    to yinbin(yinbin)
    谢谢
    我的目的是想做一个公用函数,以后任何窗体都可以调用
      

  6.   

    '模块:'--------热键定义API----------------
    Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
    Private Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
    Private 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
    Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal ID As Long, ByVal fskey_Modifiers As Long, ByVal vk As Long) As Long
    Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal ID As Long) As LongConst WM_HOTKEY = &H312
    Const MOD_ALT = &H1
    Const MOD_CONTROL = &H2
    Const MOD_SHIFT = &H4
    Const GWL_WNDPROC = (-4)    '窗口函数的地址Dim key_preWinProc As Long '用来保存窗口信息
    Dim key_Modifiers As Long, key_uVirtKey As Long, key_idHotKey As Long
    Dim key_IsWinAddress    As Boolean '是否取得窗口信息的判断
    '------------------------------------Function keyWndproc(ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long        If Msg = WM_HOTKEY Then
                    Select Case wParam 'wParam 值就是 key_idHotKey
                            '激活热键后,热键所对应的操作,大家在其他的程序中,只要修改此处就可以了
                            '注意:所要求的过程要祛除过程定义中的 "Private" 一句,才能找到此过程
                            Case 1    'Ctrl+F1
                                Call frmMain.事件过程
                            Case 2    'F2
                                Call 某某事件过程
                            Case 3    'Ctrl+Alt+F2 
                                Call 某某事件过程
                    End Select
            End If
            
            '将消息传送给指定的窗口
            keyWndproc = CallWindowProc(key_preWinProc, hwnd, Msg, wParam, lParam)
            
    '----------在窗体 Form_Load 事件中定义热键格式------------------    'SetHotkey 1, "Ctrl,112", "Add"             ' 按 Ctrl+F1 激活指定程序
        'SetHotkey 2, 113, "Add"                        '按 F2 激活指定程序
        'SetHotkey 3, "Ctrl+Alt,113", "Add"        '按 Ctrl+Alt+F2 激活指定程序
        
    '注:关于激活热键后的操作,由自定义函数 SetHotkey 的 KeyId 传送的值来判断'----------在窗体 Form_Unload 事件中注销热键格式----------------    'SetHotkey 1, "", "Del"                         ' 退出程序是一定要用上的,不然会导至程序死掉
        'SetHotkey 2, "", "Del"
        'SetHotkey 3, "", "Del"
        
    '---------------------------------------------------------------End Function
    Function SetHotkey(ByVal KeyId As Long, ByVal KeyAss0 As String, ByVal Action As String)
            Dim KeyAss1 As Long
            Dim KeyAss2 As String
            Dim i As Long
            
            i = InStr(1, KeyAss0, ",")
            If i = 0 Then
                    KeyAss1 = Val(KeyAss0)
                    KeyAss2 = ""
            Else
                    KeyAss1 = Right(KeyAss0, Len(KeyAss0) - i)
                    KeyAss2 = Left(KeyAss0, i - 1)
            End If
            
            key_idHotKey = 0
            key_Modifiers = 0
            key_uVirtKey = 0
            
            If key_IsWinAddress = False Then    '判断是否需要取得窗口信息,如果重复取得,再最后恢复窗口时,将会造成程序死掉
                    '记录原来的window程序地址
                    key_preWinProc = GetWindowLong(frmMain.hwnd, GWL_WNDPROC)
                    '用自定义程序代替原来的window程序
                    SetWindowLong frmMain.hwnd, GWL_WNDPROC, AddressOf keyWndproc
            End If        key_idHotKey = KeyId
            Select Case Action
                    Case "Add"
                            If KeyAss2 = "Ctrl" Then key_Modifiers = MOD_CONTROL
                            If KeyAss2 = "Alt" Then key_Modifiers = MOD_ALT
                            If KeyAss2 = "Shift" Then key_Modifiers = MOD_SHIFT
                            If KeyAss2 = "Ctrl+Alt" Then key_Modifiers = MOD_CONTROL + MOD_ALT
                            If KeyAss2 = "Ctrl+Shift" Then key_Modifiers = MOD_CONTROL + MOD_SHIFT
                            If KeyAss2 = "Ctrl+Alt+Shift" Then key_Modifiers = MOD_CONTROL + MOD_ALT + MOD_SHIFT
                            If KeyAss2 = "Shift+Alt" Then key_Modifiers = MOD_SHIFT + MOD_ALT
                            key_uVirtKey = Val(KeyAss1)
                            RegisterHotKey frmMain.hwnd, key_idHotKey, key_Modifiers, key_uVirtKey '向窗口注册系统热键
                            key_IsWinAddress = True '不需要再取得窗口信息
                            
                    Case "Del"
                            SetWindowLong frmMain.hwnd, GWL_WNDPROC, key_preWinProc '恢复窗口信息
                            UnregisterHotKey frmMain.hwnd, key_uVirtKey '取消系统热键
                            key_IsWinAddress = False '可以再次取得窗口信息
            End Select
    End Function
      

  7.   

    自定义组合热键 
     
     
          通过截取系统消息,我们可以方便的实现自定义组合热键.
    下面的例子实现了该功能:
    >>步骤1----建立新工程;
    >>步骤2----建立一个模块;
    >>步骤3----在模块中写入如下代码:Declare 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, uVirtKey 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    If Msg = WM_HOTKEY Then
            If wParam = idHotKey Then
                Dim lp As taLong, i2 As t2Int
                lp.ll = lParam
                LSet i2 = lp
                If (i2.lWord = Modifiers) And i2.hWord = uVirtKey Then
                    Shell "Notepad", vbNormalFocus
                End If
            End If
        End If
        '如果不是热键信息则调用原来的程序
        Wndproc = CallWindowProc(preWinProc, hWnd, Msg, _
            wParam, lParam)
    End Function>>步骤4----在窗体中写入如下代码:
    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
        Modifiers = MOD_ALT + MOD_CONTROL 'Alt+Ctrl 键
        uVirtKey = vbKeyN 'N键
        ret = RegisterHotKey(Me.hWnd, idHotKey, Modifiers, uVirtKey)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
        Dim ret As Long
        '取消Message的截取,使之送往原来的windows程序
        ret = SetWindowLong(Me.hWnd, GWL_WNDPROC, preWinProc)
        Call UnregisterHotKey(Me.hWnd, uVirtKey)
    End Sub
    >>步骤5----编译运行
     
    ==============================================
    在软件中设定热键
    无论窗体活不活动只要按下热键就可执行一定功能。
    Private Declare Function GetAsyncKeyState Lib ″user32″ Alias ″GetAsyncKeyState″ (Byval vkey as Long) as integer
      Private Function MyHotKey(vKeyCode) As Boolean
      MyHotKey=((GetAsyncKeyState(vKeyCode)<0)
      End Function
      然后在循环中或Timer的Timer事件中检测:
      If myHotKey(vbkeyA) then .....
      其中vbkeyA是键盘″A″的常数
      

  8.   

    =====================
    定义全局热键
     
     
     按下某组键(HotKey)便执行某程式
    在Dos的年代,我们常会以拦截中断向量的方式,做到按下某个hotkey而自动执行某个程式,在Window呢,也可以,不过它是用RegisterHotkey API来完成。使用RegisterHotkey的概念是,它会定义一组按键的组合,当使用者不管在哪个程式之中,按下Window有注册的HotKey时,OS会传送WM_HOTKEY 的讯息给待接收该讯息的Window,而该Window收到WM_HOTKEY时,便可知道有本身Thread所定义的HotKey被按下,於是可以从wParam, lParam来得知是哪一组HotKey被按下。RegisterHotKey(
    ByVal hwnd As Long , //接收Hotkey的Window
    ByVal idHotKey as Long, // identifier of hot key,range 0x0000 through 0xBFFF
    ByVal Modifiers As Long, // 定义alt shift control等的组合
    ByVal uVirtKey As Long // virtual-key code
    )WM_HOTKEY 叁数的定义
    idHotKey = wParam; // identifier of hot key 
    Modifiers = (UINT) LOWORD(lParam); // key-modifier flags 
    uVirtKey = (UINT) HIWORD(lParam); // virtual-key code所以了,除了设定RegisterHotkey外,另要使用SubClassing的技巧才会得知HotKey被按下;最後,程式结束前要使用UnRegisterHotkey将HotKey的定义取消掉。以下程式功能是:不管在哪个程式中,只要按下ALT-SHIFT-G 便执行NotePad。
    '以下在.Bas
    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, uVirtKey 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
    If Msg = WM_HOTKEY Then
    If wParam = idHotKey Then
    Dim lp As taLong, i2 As t2Int
    lp.ll = lParam
    LSet i2 = lp
    If (i2.lWord = Modifiers) And i2.hword = uVirtKey Then
    Debug.Print "HotKey Shift-Alt-G Pressed "
    Shell "notepad", vbNormalFocus
    End If
    End If
    End If
    '将之送往原来的Window Procedure
    wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam)
    End Function'以下在 Form
    Sub Form_Load()
    Dim ret As Long
    preWinProc = GetWindowLong(Me.hwnd, GWL_WNDPROC)
    ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, AddressOf wndproc)
    idHotKey = 1 'in the range &h0000 through &hBFFF
    Modifiers = MOD_ALT + MOD_SHIFT
    uVirtKey = vbKeyG
    ret = RegisterHotKey(Me.hwnd, idHotKey, Modifiers, uVirtKey)
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    Dim ret As Long
    '取消Message的截取,而使之又只送往原来的Window Procedure
    ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc)
    Call UnregisterHotKey(Me.hwnd, uVirtKey)
    End Sub
     
    ===================================
    为你的应用程序设置热键?
     
     
     启动工程后,在你的工程中添加一个标准模块,然后将下面的代码粘贴到模块的声明段中。Option ExplicitDeclare Function SendMessage Lib "user32" _
    Alias "SendMessageA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, _
    lParam As Long) As LongDeclare Function DefWindowProc Lib "user32" _
    Alias "DefWindowProcA" (ByVal hwnd As Long, _
    ByVal wMsg As Long, ByVal wParam As Long, _
    ByVal lParam As Long) As LongPublic Const WM_SETHOTKEY = &H32
    Public Const WM_SHOWWINDOW = &H18
    Public Const HK_SHIFTA = &H141 'Shift + A
    Public Const HK_SHIFTB = &H142 'Shift * B
    Public Const HK_CONTROLA = &H241 'Control + A
    Public Const HK_ALTZ = &H45A 
    请注意组合键的值必须以低/高位字节的格式进行声明。也就是说是一个十六进制的数字。后两位是低端字节,如41=a;前两位是高端字节,如01=1=shift。在窗体的Load事件中加入下面的代码:Private Sub Form_Load()
    Dim erg As Long
    Me.WindowState = vbMinimized
    '让windows知道你想要的热键。
    erg& = SendMessage(Me.hwnd, WM_SETHOTKEY,HK_ALTZ, 0)
    '检查函数是否执行成功
    If erg& <> 1 Then
    MsgBox "You need another hotkey", vbOKOnly,"Error"
    End If
    '告诉windows热键按下后做什么--显示窗口
    erg& = DefWindowProc(Me.hwnd, WM_SHOWWINDOW,0, 0)End Sub
    按F5运行程序后,再按下ALT+Z就会看到结果了。 
      

  9.   

    to csdngoodnight(居然比我还快,你真行!) 
    请问能不能使事件和快捷键动态绑定而不用在模块里先定义快捷键所要触发的事件?