分享

使用GetKeyboardState 和 SetkeyboardState设置键盘状态

 quasiceo 2014-01-01

使用GetKeyboardState 和 SetkeyboardState设置键盘状态

热度 5已有 3240 次阅读2011-9-7 09:00 |个人分类:知识点| SetkeyboardState

配合以下知识理解KEY库的源码应该有帮助。就转了过来。
Sendlnput函数可以模拟键盘事件,它执行的效果和实际操作键盘效果是一样,即SendInput一个键盘按下事件,在任何进程中都可以捕获到该事件。
而SetKeyboardState设置的键盘状态只能在本进程中有效。
首先看Windows API参考大全中的介绍:
GetKeyboardState
  函数功能:该函数将256个虚拟键的状态拷贝到指定的缓冲区中。
  函数原型:BOOL GetKeyboardState(PBYTE IpKeyState);
  参数:
  IpKeyState:指向一个256字节的数组,数组用于接收每个虚拟键的状态。
  返回值:若函数调用成功,则返回非0值。若函数调用不成功,则返回值为0。若要获得更多的错误信息,可以调用GetLastError函数。
  备注:应用程序可以调用该函数来检取所有虚拟键的当前状态。当键盘消息被从该线程的消息队列中移去时,虚拟键的状态发生改变。当键盘消息被发送到该线程的消息队列中,或者,当键盘消息被发送到其他线程的消息队列或被从其他线程的消息队列中检取到时,虚拟键的状态不发生改变。(例外:通过AttachThreadlnput连接的线程共享同一键盘状态。)当函数返回时,由lpKeyState参数指向的每一个数组成员中都包含了一个虚拟键的状态数据。若最高位被置为1,则该键处于down状态;否则,该键处于up状态。若最低位被置为1,则该键被触发。当一个键被打开时称之为被触发,如capslock键。若最低位被置为0,该键被关闭且不被触发。一个触发键也键盘上的指示灯(如果有的话)在该键被触发时点亮,在不被触发时灭掉。若要检取单个虚拟键的状态信息,可以调用GetKeyState函数。若要检取任一虚拟键的当前状态,而不管相应的键盘消息足否己从消息队列中检取到,可以使用GetAsyncKevState函数。应用程序可以使用虚拟键码常数VK_SHIFT,VK_CONTROL和VK_MENU作为IpKeyState所指向的数组的下标。这样给出的Shift,Ctrl,Alt键的状态不区分左右键。应用程序也可以使用如下的虚拟键码常数作为以上键的区分左右键的下标:
  VK_LSHIFT,VK_RSHIFT,VK_LCONTROL,VK_RCONTROL;VW_LMENU,VW_RMENU仅当应用程序调用GetKeyboardState;SetKeyboardState,GetAsycKeystate,GetKeyState和MapVirtualKey函数时,才可用这些区分左右键的常数。
SetkeyboardState
  函数功能:该函数拷贝一个存放键盘键状态的256字节的数组到调用线程的键盘输入状态表中。该表与GetkeyboardState和GetkeyState函数访问的是同一个表。对该表的改变不会影响其他线程的键盘输入。
  函数原型:BOOL SetkeyboardState(LPBYTE lpKeyState);
  参数:
  lpKeyState:指向一个包含键盘键状态的256字节的数组。
  返回值:若函数调用成功,则返回值不为0。若函数调用失败,则返回值为0。若要获得更多的错误信息,可以调用GetLastError函数。
 
 
因此可以用这两个函数模拟在同一个进程中的键盘消息:
BYTE KeyStatus[256] = {0};
 GetKeyboardState( KeyStatus );
 KeyStatus[VK_SHIFT] = -1; //设置Shift按键为按下状态
 SetKeyboardState( KeyStatus );
 PostMessage( WM_KEYDOWN, VK_SHIFT, 0 );//发生键盘被按下的消息
此时,在消息处理函数中可以接收到该消息,并且查询Shift的状态确实为按下状态:
BOOL CTEST2Dlg::PreTranslateMessage(MSG* pMsg)
{
     if( WM_KEYDOWN == pMsg->message )
    {
    SHORT state = GetKeyState((int)pMsg->wParam );
    TRACE( _T("\r\nPreTranslateMessage state %d wparam 0x%0x\r\n"),state,pMsg->wParam  );
    }
  return CDialog::PreTranslateMessage(pMsg);
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多