副标题#e#
输入事件中的键盘事件凡是有字符事件和按键事件,这些事件的附带信息组成了键盘输入的信息,而想要读取这些信息,是要通过API函数ReadConsoleInput来获取的,函数原型如下:
BOOL ReadConsoleInput( //读取输入信息 HANDLE hConsoleInput, //句柄 PINPUT_RECORD lpBuffer, //输入事件布局体的指针 DWORD nLength, //要读取的记录数 LPDWORD lpNumberOfEventsRead //用来接管乐成读取记录数的指针 ); //假如该函数乐成挪用,返回非零值 //输入事件布局体的指针可以是布局体数组的首地点,这样就可以一次性读取多个记录数。
下面先容几个和读取键盘输入事件有关的布局体,各布局体原型如下:
typedef struct _INPUT_RECORD //输入事件布局体 { WORD EventType; //事件范例 union { KEY_EVENT_RECORD KeyEvent; //按键事件 MOUSE_EVENT_RECORD MouseEvent; //鼠标事件 WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent; MENU_EVENT_RECORD MenuEvent; FOCUS_EVENT_RECORD FocusEvent; } Event; //详细的事件 } INPUT_RECORD; /* 个中事件范例EventType的值有5种 KEY_EVENT 代表Event包括一个KEY_EVENT_RECODE布局体 MOUSE_EVENT 代表Event包括一个MOUSE_EVENT_RECODE布局体 WINDOW_BUFFER_SIZE_EVENT 代表Event包括一个WINDOW_BUFFER_SIZE_EVENT_RECORD布局体 MENU_EVENT 代表Event包括一个MENU_EVENT_RECORD布局体 FOCUS_EVENT 代表Event包括一个FOCUS_EVENT_RECORD布局体 */ typedef struct _KEY_EVENT_RECORD //键盘事件布局体 { BOOL bKeyDown; //按键状态,true代表键按下,false代表键释放 WORD wRepeatCount; //按键次数 WORD wVirtualKeyCode; //虚拟键 WORD wVirtualScanCode; //虚拟键扫描码 union { WCHAR UnicodeChar; //表明成Unicode宽字符 CHAR AsciiChar; //表明成ASCII码字符 } uChar; DWORD dwControlKeyState; //节制键状态 } KEY_EVENT_RECORD; /* 节制键各状态的值 ENHANCED_KEY 扩展键被按下 LEFT_ALT_PRESSED 左Alt键被按下 LEFT_CTRL_PRESSED 左Ctrl键被按下 RIGHT_ALT_PRESSED 右Alt键被按下 RIGHT_CTRL_PRESSED 右Ctrl键被按下 NUMLOCK_ON 数字锁定被打开 SCROLLLOCK_ON 转动锁定被打开 CAPSLOCK_ON 大写锁定被打开 SHIFT_PRESSED Shift键被按下 */
当输入事件为键盘事件时,事件范例就为键盘事件,为其他事件时,事件范例就为对应的事件。别的,键盘上每个有意义的键都对应着一个独一的扫描码,固然扫描码可以作为键的标识,可是它是依赖于详细的设备的。因此,在应用措施中,利用的往往是与详细设备无关的虚拟键代码。这种虚拟键代码是一种与详细设备无关的键盘编码。而节制键状态好比大写锁定开启状态,Ctrl键按下状态等、、、
下面是部门常用虚拟键代码表:
/* 虚拟键代码 值 键名称 ----------------------------------------------------- VK_BACK 0x08 退格键 VK_TAB 0x09 Tab键 VK_RETURN 0x0D 回车键 VK_SHIFT 0x10 Shift键 VK_LSHIFT 0xA0 左Shift键 VK_RSHIFT 0xA1 右Shift键 VK_CONTROL 0x11 Ctrl键 VK_LCONTROL 0xA2 左Ctrl键 VK_RCONTROL 0xA3 右Ctrl键 VK_MENU 0x12 Alt键 VK_LMENU 0xA4 左Alt键 VK_RMENU 0xA5 右Alt键 VK_PAUSE 0x13 Pause键 VK_CAPITAL 0x14 Caps Lock键 VK_NUMLOCK 0x90 Num Lock键 VK_SCROLL 0x91 Scroll Lock键 VK_ESCAPE 0x1B Esc键 VK_SPACE 0x20 空格键 VK_PRIOR 0x21 Page Up键 VK_NEXT 0x22 Page Down键 VK_END 0x23 End键 VK_HOME 0x24 Home键 VK_LEFT 0x25 左偏向键 VK_UP 0x26 上偏向键 VK_RIGHT 0x27 右偏向键 VK_DOWN 0x28 下偏向键 VK_DELETE 0x2E Delete键 VK_INSERT 0x2D Insert键 '0' 0x30 0键(非小键盘) '1' 0x31 1键(非小键盘) '2' 0x32 2键(非小键盘) ... ... ... '9' 0x39 9键(非小键盘) 'A' 0x41 A键 'B' 0x42 B键 ... ... ... 'Z' 0x5A Z键 VK_SLEEP 0x5F Sleep键 VK_NUMPAD0 0x60 小键盘0键 VK_NUMPAD1 0x61 小键盘1键 VK_NUMPAD2 0x62 小键盘2键 ... ... ... VK_NUMPAD9 0x69 小键盘9键 VK_MULTIPLY 0x6A 小键盘乘键* VK_ADD 0x6B 小键盘加键+ VK_SUBTRACT 0x6D 小键盘减键- VK_DIVIDE 0x6F 小键盘除键/ VK_DECIMAL 0x6E 小键盘货键. VK_F1 0x70 F1键 VK_F2 0x71 F2键 ... ... ... VK_F12 0x7B F12键 VK_F13 0x7C F13键 注:别问我,我也不知道什么电脑有这么多键 ... ... ... VK_F24 0x87 F24键 VK_OEM_1 0xBA ;:键 VK_OEM_2 0xBF /?键 VK_OEM_3 0xC0 ·~键 VK_OEM_4 0xDB [{键 VK_OEM_5 0xDC \|键 VK_OEM_6 0xDD ]}键 VK_OEM_7 0xDE '"键 VK_OEM_PLUS 0xBB =+键 VK_OEM_MINUS 0xBD -_键 VK_OEM_COMMA 0xBC ,<键 VK_OEM_PERIOD 0xBE .>键 */
#p#分页标题#e#
以上是部门常用的微软虚拟键盘码表,想要知道更具体的,请拜见MSDN。个中各个虚拟键的详细利用环境按照大师编译器或IDE等的差异而有所差别。下面是一个实现按Esc键就输出Esc的样例措施:
本栏目
#p#副标题#e#
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <conio.h> #define true 1 #define false 0 int main() { HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); //得到尺度输入设备句柄 INPUT_RECORD keyrec; //界说输入事件布局体 DWORD res; //界说返回记录 for (;;) { ReadConsoleInput(handle_in, &keyrec, 1, &res); //读取输入事件 if (keyrec.EventType == KEY_EVENT) //假如当前事件是键盘事件 { if (keyrec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) //当前事件的虚拟键为Esc键 { printf("Esc "); } } } return 0; }
在上面的样例措施中,当你按下Esc键后又顿时释放,措施会输出两次Esc,因为有两次事件的虚拟键代码都是Esc键的代码,一次是按下,一次是释放。假如要实现按下键后呈现回响,释放不呈现回响,那么将上例措施中第18行代码的条件改成
if (keyrec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE && keyrec.Event.KeyEvent.bKeyDown == true) //暗示当前为键按下而不是键释放
就行了。
按照节制键的状态我们可以实现差异的状态输出差异的值以及组合键的实现,下面的样例措施在大写锁定打开时输入A键则输出大写字母A,不然输出小写字母a。而在Shift键被按下的状态是则输出Shift+A以及Shift+a。样例措施如下
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <conio.h> #define true 1 #define false 0 int main() { HANDLE handle_in = GetStdHandle(STD_INPUT_HANDLE); //得到尺度输入设备句柄 INPUT_RECORD keyrec; //界说输入事件布局体 DWORD res; //界说返回记录 for (;;) { ReadConsoleInput(handle_in, &keyrec, 1, &res); //读取输入事件 if (keyrec.EventType == KEY_EVENT) //假如当前事件是键盘事件 { if (keyrec.Event.KeyEvent.wVirtualKeyCode == 'A' && keyrec.Event.KeyEvent.bKeyDown == true) //当按下字母A键时 { if (keyrec.Event.KeyEvent.dwControlKeyState & SHIFT_PRESSED) //Shift键为按下状态 { printf("Shift+"); } if (keyrec.Event.KeyEvent.dwControlKeyState & CAPSLOCK_ON) //大写锁定为打开状态 { printf("A "); } else //大写锁定封锁状态 { printf("a "); } } } } return 0; }
由上例需要相识到的是,各个节制键状态的简直定并不是利用便是标记==而是按位与&运算符,因为在同一时刻大概有多种节制键状态值,好比各类锁定都被打开且各类节制键也被同时按下。利用&运算符则显得尤其高超,利便查询各个节制键的状态而不使之呈现斗嘴。呵呵,不平不可啊,感应一下,照旧要多进修一下别人高超的处所,好比机动运用位运算符实现各类成果等等······
From:cnblogs 龙梦之痕