keybd_event(VK_SPACE,0,0,0);    //模拟按下空格键,不会释放
但这个必须是在窗口拥有焦点的情况下才可以,我希望程序在后台也可以接受到并执行,所以想用Send/PostMessage来模拟这个键持续按下,有什么办法吗?我想确认某个键是否已经被按下,该如何做啊?

解决方案 »

  1.   

    我想确认某个键是否已经被按下,该如何做啊?
    --------------------------------------------
    可以使用GetKeyState函数
      

  2.   

    用底层技术吧~在核心态Ring0下用IO端口模拟,这是最强的
      

  3.   

    GetKeyState确认某个键是否已经被按下成功了
    难道空格键没有后台按下的方法吗?
      

  4.   

    我来告诉你最强的模拟按键方式:通过硬件端口发送消息,也就是说等同于真实按键的全过程,完全不必考虑是否前台,焦点等等,就是等同于按键盘
    但是这段代码是vb的,我改了一部分有很大问题,大家一起来研究吧
     
    vb原码:
    Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
    Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
    Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
    Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
    Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
    Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
    Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
    Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean
    Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
    Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean' ------------------------------------以上是WINIO函数声明-------------------------------------------Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long'-----------------------------------以上是WIN32 API函数声明-----------------------------------------再添加下面这个过程:
    Sub KBCWait4IBE()   '等待键盘缓冲区为空
    Dim dwVal As Long
    Do
    GetPortVal &H64, dwVal, 1
    '这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
    'GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
    Loop While (dwVal And &H2)
    End Sub
    上面的是一个根据KBC规范写的过程,它的作用是在向键盘端口写入数据前等待一段时间,后面将会用到。
    然后再添加如下过程,这2个过程用来模拟按键:Public Const KBC_KEY_CMD = &H64   '键盘命令端口
    Public Const KBC_KEY_DATA = &H60   '键盘数据端口Sub MyKeyDown(ByVal vKeyCoad As Long)   
    '这个用来模拟按下键,参数vKeyCoad传入按键的虚拟码
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)  KBCWait4IBE   '发送数据前应该先等待键盘缓冲区为空
      SetPortVal KBC_KEY_CMD, &HD2, 1   '发送键盘写入命令
    'SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
      KBCWait4IBE
      SetPortVal KBC_KEY_DATA, btScancode, 1 '写入按键信息,按下键
      
    End SubSub MyKeyUp(ByVal vKeyCoad As Long)   
    '这个用来模拟释放键,参数vKeyCoad传入按键的虚拟码
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)  KBCWait4IBE   '等待键盘缓冲区为空
      SetPortVal KBC_KEY_CMD, &HD2, 1 '发送键盘写入命令
      KBCWait4IBE
      SetPortVal KBC_KEY_DATA, (btScancode Or &H80), 1 '写入按键信息,释放键End Sub
    定义了上面的过程后,就可以用它来模拟键盘输入了。在窗体模块中添加一个定时器控件,然后加入以下代码:
    Private Sub Form_Load()If InitializeWinIo = False Then   
    '用InitializeWinIo函数加载驱动程序,如果成功会返回true,否则返回false
      MsgBox "驱动程序加载失败!"
      Unload Me
    End If
    Timer1.Interval=3000
    Timer1.Enabled=True
    End SubPrivate Sub Form_Unload(Cancel As Integer)
    ShutdownWinIo '程序结束时记得用ShutdownWinIo函数卸载驱动程序
    End SubPrivate Sub Timer1_Timer()
    Dim VK_A as Long = &H41
    MyKeyDown VK_A   
    MyKeyUp VK_A   '模拟按下并释放A键
    End Sub
    这是我改的,问题很多,都来研究吧,也可以到我的帖子里去解答
      

  5.   

    如果实在找不到后台的方法。。还是得要用前台了
    但是用前台的话就必须让目标程序获得焦点。我开了5个程序,这5个程序都需要持续按下空格键10秒,然后再松开空格键。
    用SetForegroundWindow有时候只有第一个在前面的程序获得焦点,后面4个程序有可能就一直得等着。
    有没有其他的方法让多个程序连续准确的获得/失去焦点啊?
      

  6.   

    keybd_event(VK_SPACE,0,0,0);    //模拟按下空格键,不会释放
    但这个必须是在窗口拥有焦点的情况下才可以,我希望程序在后台也可以接受到并执行,所以想用Send/PostMessage来模拟这个键持续按下,有什么办法吗?我想确认某个键是否已经被按下,该如何做啊?窗口失去焦点的时候模拟按键:
    1、定义一个变量:
      var
        hSelfWnd: THandle;  //该窗口句柄
    2、窗口启动时OnCreate事件中
      hSelfWnd := Self.Handle;
    3、定义一个定时器,在定时器的OnTimer事件中;
      普通按键:
      SendMessage(hSelfWnd, WM_CHAR, wParam, lParam);
      系统按键:
      SendMessage(hSelfWnd, WM_SYSCHAR, wParam, lParam);注:wParam, lParam这两个参数具体使用忘了,可以模拟按键,按键和鼠标结合。
      

  7.   

    谁有SendMessage(hSelfWnd, WM_SYSCHAR, wParam, lParam);的详细介绍啊