一、问题的提出 有的程序员希望能够识别所有键盘上按下的键,以便在应用程序中能够正确地处理它。特别希望知道的是用户是否按下了键 SHIFT、CTRL、ALT、NUMLOCK 或 CAPSLOCK。对于键 SHIFT、CTRL 和 ALT,程 序员关心的用户是否当前按下此键;对于键 NUMLOCK 和 CAPSLOCK,程序员只关心用户是否在应用程序取得控制之前选取了此键。
二、解决方法 这是一个非常有趣的问题。如何在多任务、多窗口系统上确定键盘上哪个键是按下的,以使键盘状态对 所有应用程序来说都是一致的呢?由于有的键可能在另外的窗口中被按下,所以不能简单地捕捉键的按下操作。由于键 NUMLOCK 有可能在应用程序启动之前已被按下,所以也不能简单地监视此键被按下。 因此,要完成此任务所需要的是一个能够随时获取键盘状态的方法。幸运的是,Windows API 对此问题提供了一个简单的解决方案,即 API 函数 GetKeyboardState。
三、实现步骤 按照下列步骤实现一个例子程序。运行此例子程序,从菜单 Keyboard 中选择菜单项 Keys Pressed, 将弹出一个显示一系列键的对话框,每个键旁边没有文本。按下几个键并点击按钮 Show,则列表右边的状 态值将改变以反映这些键的当前状态。
实现例子程序的具体步骤如下: 1.在 Visual C++ 中,利用 AppWizard 创建新的项目文件,并命名此项目文件为 LD18.MAK. 2.进入 AppStudio 并创建新的对话框,在对话框中,添加五个文本域,标题分别为 Control Key、 Shift Key、Alt Key、Num Lock Key 和 Caps Lock Key。 3.与刚创建的五个文本域对齐,创建另外五个文本域。标题为空,ID 分别为:ID_CONTROL_KEY、 ID_SHIFT_KEY、ID_ALT_KEY、ID_NUM_LOCK_KEY 和 ID_CAPS_LOCK_KEY。 4.改变对话框的标题为 View Key States。 5.添加两个按钮,标题分别为 Show 和 Close,ID 分别为 ID_SHOW 和 IDOK。 6.进入 ClassWizard,选择按钮 Add Class。命名对话框类为 CKeyShowDlg。 7.在 ClassWizard 中,从下拉列表中选择 CKeyShowDlg ,从列表对象中选择按钮 ID_SHOW, 从消息列表中选择消息 COMMAND,点击按钮 Add Function,函数命名为 OnShow。 8.在对象 CKeyShowDlg 的方法 OnShow 中输入下列代码:
void CKeyShowDlg::OnShow() { unsigned char kbuf[256]; GetKeyboardState(kbuf);
if(kbuf[VK_CAPITAL]&1) GetDlgItem(ID_CAPS_LOCK_KEY)->SetWindowText("On"); else GetDlgItem(ID_CAPS_LOCK_KEY)->SetWindowText("Off");
if(kbuf[VK_SHIFT]&128) GetDlgItem(ID_SHIFT_KEY)->SetWindowText("On"); else GetDlgItem(ID_SHIFT_KEY)->SetWindowText("Off");
if(kbuf[VK_CONTROL]&128) GetDlgItem(ID_CTRL_KEY)->SetWindowText("On"); else GetDlgItem(ID_CTRL_KEY)->SetWindowText("Off");
if(kbuf[VK_MENU]&128) GetDlgItem(ID_ALT_KEY)->SetWindowText("On"); else GetDlgItem(ID_ALT_KEY)->SetWindowText("Off");
if(kbuf[VK_NUMLOCK]&1) GetDlgItem(ID_NUM_LOCK_KEY)->SetWindowText("On"); else GetDlgItem(ID_NUM_LOCK_KEY)->SetWindowText("Off"); }
9.进入 AppStudio,在菜单 IDR_MAINFAME 中,添加新的菜单 Keyboard。在菜单 Keybosrd 中, 添加菜单项 Keys Pressed,其 ID 为 ID_KEY_PRESSED。进入 ClassWizard,为对象 ID_KEY_PRESSED 和 消息 COMMAND 添加新的函数,命名此函数为 OnKeyPressed,并在此函数中添加下列代码:
void CMainFrame::OnKeyPressed() { CKeyShowDlg dlg;
dlg.DoModal(); }
10.在文件 MAINFRM.CPP 的顶部添加下列行: #include "KeyShowDlg.h" 11.编译并运行此例子程序。
用法 Windows API 函数 GetKeyboardState 返回键盘上每一键的状态。对于可以按下和松开的键,如 SHIFT,CTRl,TAB 以及所有的字符键。键的”状态“或是高位设置(表示键被按下)或是高位清除(表 示键未被按下,即松开的)。对于切换选择的键,如 NUM LOCK 或 CAPS LOCK,低位设置表示此键当前 是选中(开)状态,低位清除表示此键当前是未选中(关)状态。 通过在预定时间检查键盘状态,可以随时得到被按下的任何键和所有键。例如:如果用户按下键 CTRL-ALT-SHIFT-F10,则在键盘缓冲区将设置下列键值的高位: VK_SHIFT VK_CONTROL VK_MENU(为 ALT 键) VK_F10 在线帮助或 include 文件 Windows.h 中都列出了键盘上所有这些键的虚拟键码。
|
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=3236