什么API函数可以来编写一键功能,即程序只在后台运行,当按下某个键时自动打开相应的程序?

解决方案 »

  1.   

    下面我们就来看看具体程序,这个程序的功能是无论在哪个程序中按下ALT-SHIFT-G就执行记事本程序: 
       '以下程序放在模块中 
      Option Explicit 
       
      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 Long 
       
      Public 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 Long 
       
      Private Type taLong 
       ll As Long 
      End Type 
      Private Type t2Int 
       lWord As Integer 
       hword As Integer 
      End Type 
       Public 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 
       '如果不是热键信息则调用原来的程序 
       wndproc = CallWindowProc(preWinProc, hwnd, Msg, wParam, lParam) 
       End Function 
       
      '以下程序放在窗体中 
      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_ALT + MOD_SHIFT 
       uVirtKey = vbKeyG 
       '注册热键 
       ret =RegisterHotKey(Me.hwnd, idHotKey, Modifiers, uVirtKey) 
       End Sub 
       
       Private Sub Form_Unload(Cancel As Integer) 
       Dim ret As Long 
       '取消Message的截取,使之送往原来的window程序 
       ret = SetWindowLong(Me.hwnd, GWL_WNDPROC, preWinProc) 
       Call UnregisterHotKey(Me.hwnd, uVirtKey) 
       End Sub
      

  2.   

    你说的情况,我想可以这样解决,你把想要后台运行的程序,注册为服务,然后用这几个函数:SetWindowLong、GetWindowLong、CallWindowProc、RegisterHotKey,UnregisterHotKey,向系统注册一个热键,就可以了!!!
      

  3.   

    其它我想,用一个API函数就足够了,而且简单:Private Declare Function Getasynckeystate Lib "user32" (Byval vKey As Long) as Integer
    '该api函数是根据返回值来判断是否按下指定键(无论在前台或后台皆可)的,返回值小于0时则为按下了该键,不然……你说呢?Private Sub Timer1_Timer()
        Dim back_ctrl , back_alt , back_S as Long
        '定义back_ctrl等变量来接收返回值
        
        back_ctrl = Getasynckeystate(17)     '“17”为“ctrl”键的keycode值
        back_alt = Getasynckeystate(18)      '“18”为“alt”键的keycode值
        back_S = Getasynckeystate(83)        '“83”为“S”键的keycode值    If back_ctrl < 0 and back_alt < 0 and back_S < 0 then
        '判断ctrl和alt和S键是否同时被按下
           shell "C:\WINNT\NOTEPAD.exe",vbNormalFocus
           '用shell函数来运行指定的“记事本”程序
        End if
    End Sub  这样的话,就可以用Timer控件来检测键盘操作了。
      (我也就是个学了一个多月编程的菜鸟,请多多指教!)
      E-mail: [email protected]
      

  4.   

    Getasynckeystate函数好象只在当前窗口活动时才有用,否则不能获得键盘按键状态
      

  5.   

    Getasynckeystate是可以在整个系统下工作的!但需要有timer控件的支持,才能时时起作用。
      

  6.   

    但是以前我看过别人用这个写的程序,当那个窗口为活动窗口时可以获得按键状态,如果失去焦点,就不能获得键盘状态了。MSDN里面好象也说只是获得当前进程缓冲区的键盘状态呀。不知上面那位老兄是否试过。
      

  7.   

    使用这个函数的程序是可以在后台工作时获得键盘按键操作的,只是它不能够屏蔽其它的热键操作。例:你把热键F1设为打开“记事本”的热键时,在VB使用中如果按了“F1”键,由MSDN和“记事本”会一同打开。试试?
      

  8.   

    GetAsynckeyState就可以.......例如(按下ESC键就结束程序)Option Explicit
    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As IntegerPrivate Sub Form_Load()
        Me.Caption = "点击窗体开始测试"
    End SubPrivate Sub Form_Click()
    Do
        DoEvents
                            'ESC
        If GetAsyncKeyState(27) <> 0 Then
            End
        End If
        DoEvents
    Loop
    End Sub
      

  9.   

    //Getasynckeystate是可以在整个系统下工作的!但需要有timer控件的支持,才能时时起作用。Return Value...
    Windows NT/2000/XP: The return value is zero for the following cases: The current desktop is not the active desktop
    The foreground thread belongs to another process and the desktop does not allow the hook or the journal record....MSDN上已经说明,对于NT系统,GetAsyncKeyState也会被隔离内存所作用,无法获取其它线程的输入(可能用AttachThreadInput附加线程输入就能解决)。所以还是用RegisterHotkey最正规,最安全。
      

  10.   

    如果只想识别一种按键组合,可以用注册系统热键的api,上面很多文章都提到了
    如果像识别多种组合,建议使用系统键盘钩子。
    不建议使用timer控件:Interval的值过大,则容易漏掉按键
    Interval过小,太占用系统资源
    同样容易出现漏掉按键的情况