00. 目录

文章目录

  • 00. 目录
  • 01. INPUT_RECORD结构
  • 02. KEY_EVENT_RECORD结构
  • 03. ReadConsoleInput函数
  • 04. 示例程序

01. INPUT_RECORD结构

描述控制台输入缓冲区中的输入事件。可以使用ReadConsoleInputPeekConsoleInput函数从输入缓冲区读取这些记录,也可以使用WriteConsoleInput函数将这些记录写入输入缓冲区。

类型声明:

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

输入事件类型的句柄和存储在Event成员中的事件记录。

该成员可以是以下值之一。

含义
FOCUS_EVENT 0x0010 事件成员包含一个FOCUS_EVENT_RECORD结构。这些事件在内部使用,应该被忽略。
KEY_EVENT 0x0001 事件成员包含一个KEY_EVENT_RECORD结构有关键盘事件的信息。
MENU_EVENT 0x0008 事件成员包含一个MENU_EVENT_RECORD结构。这些事件在内部使用,应该被忽略。
MOUSE_EVENT 0x0002 所述事件构件包含MOUSE_EVENT_RECORD结构用约鼠标移动或按键按压事件的信息。
WINDOW_BUFFER_SIZE_EVENT 0x0004 事件成员包含一个WINDOW_BUFFER_SIZE_RECORD结构有关控制台屏幕缓冲区的新大小信息。

事件
事件信息。此成员的格式取决于EventType成员指定的事件类型。

02. KEY_EVENT_RECORD结构

描述控制台INPUT_RECORD结构中的键盘输入事件。

typedef struct _KEY_EVENT_RECORD {BOOL  bKeyDown;WORD  wRepeatCount;WORD  wVirtualKeyCode;WORD  wVirtualScanCode;union {WCHAR UnicodeChar;CHAR  AsciiChar;} uChar;DWORD dwControlKeyState;
} KEY_EVENT_RECORD;

bKeyDown
如果按下该键,则该成员为TRUE。否则,此成员为FALSE(密钥已释放)。

wRepeatCount
重复计数,表示正在按住某个键。例如,当按下某个键时,您可能会获得五个事件,该成员等于1,一个事件的成员等于5,或者此成员的多个事件大于或等于1。

wVirtualKeyCode
虚拟键码识别在设备无关的方式给定的键。

wVirtualScanCode
给定键的虚拟扫描代码,表示键盘硬件生成的与设备相关的值。

uChar
以下成员的联盟。

UnicodeChar
翻译的Unicode字符。

AsciiChar
翻译的ASCII字符。

dwControlKeyState
控制键的状态。该成员可以是以下一个或多个值。

含义
CAPSLOCK_ON 0x0080 大写锁定被打开
ENHANCED_KEY 0x0100 扩展键被按下
LEFT_ALT_PRESSED 0x0002 按下左ALT键。
LEFT_CTRL_PRESSED 0x0008 按下左CTRL键。
NUMLOCK_ON 0x0020 数字锁定被打开
RIGHT_ALT_PRESSED 0x0001 按下右ALT键。
RIGHT_CTRL_PRESSED 0x0004 按下右CTRL键。
SCROLLLOCK_ON 0x0040 滚动锁定被打开
SHIFT_PRESSED 0x0010 按下SHIFT键。

虚拟键值码表

下表显示了系统使用的虚拟键代码的符号常量名称,十六进制值以及鼠标或键盘等效项。代码按数字顺序列出。

恒/值 描述
VK_LBUTTON 0×01 鼠标左键
VK_RBUTTON 0×02 鼠标右键
VK_CANCEL 0×03 控制中断处理
VK_MBUTTON 0×04 鼠标中键(三键鼠标)
VK_XBUTTON1 0×05 X1鼠标按钮
VK_XBUTTON2 0×06 X2鼠标按钮
**- **0×07 未定义
VK_BACK0x08的 BACKSPACE键
VK_TAB×09 TAB键
**-**0x0A至0B 保留的
VK_CLEAR0x0C 清除键
VK_RETURN0X0D 回车键
**-**为0x0E-0F 未定义
VK_SHIFT为0x10 SHIFT键
VK_CONTROL为0x11 CTRL键
VK_MENU0×12 ALT键
VK_PAUSE0×13 暂停键
VK_CAPITAL0×14 CAPS LOCK键
**-**0x1A的 未定义
VK_ESCAPE0x1B ESC键
VK_CONVERT为0x1C IME转换
VK_NONCONVERT0x1D IME非转换
VK_ACCEPT0X1E IME接受
VK_MODECHANGE为0x1F IME模式更改请求
VK_SPACE为0x20 空格键
VK_PRIOR为0x21 PAGE UP键
VK_NEXT为0x22 PAGE DOWN键
VK_END0×23 结束键
VK_HOME0X24 Home键
VK_LEFT0x25 左箭头键
VK_UP0×26 向上箭头键
VK_RIGHT0×27 右箭头键
VK_DOWN0×28 向下箭头键
VK_SELECT0x29 SELECT键
VK_PRINT0x2A 打印键
VK_EXECUTE0x2B访问 执行键
VK_SNAPSHOT0x2c上 PRINT SCREEN键
VK_INSERT0x2D INS键
VK_DELETE0x2E之间 DEL键
VK_HELP值为0x2F 帮助键
的0x30 0键
0X31 1键
0x32 2键
0x33 3键
0x34 4键
0x35 5键
0x36 6键
0×37 7键
0x38 8键
0x39 9键
**-**0x3A-40 未定义
的0x41 关键
的0x42 B键
0x43中 C键
0×44 D键
0×45 E键
0×46 F键
0X47 G键
0x48 H键
×49 我关键
0x4A J键
0x4B K键
0x4C L键
送出0x4d M键
0x4E N键
0x4F 哦关键
为0x50 P键
0x51 Q键
0×52 R键
0x53 S键
0x54 T键
0x55的 U键
0x56储存 V键
的0x57 W键
将0x58 X键
0×59 Y键
0x5A Z键
VK_LWIN0x5B 左键Windows键(自然键盘)
VK_RWIN0x5C 右键Windows键(自然键盘)
VK_APPS0x5D 应用键(自然键盘)
**-**0x5E 保留的
VK_SLEEP0x5F的 电脑睡眠键
VK_NUMPAD00X60 数字小键盘0键
VK_NUMPAD10x61 数字小键盘1键
VK_NUMPAD20X62 数字小键盘2键
VK_NUMPAD30x63 数字小键盘3键
VK_NUMPAD40x64 数字键盘4键
VK_NUMPAD50x65 数字键盘5键
VK_NUMPAD60x66 数字小键盘6键
VK_NUMPAD70×67 数字小键盘7键
VK_NUMPAD80x68 数字小键盘8键
VK_NUMPAD90×69 数字小键盘9键
VK_MULTIPLY的0x6A 乘以键
VK_ADD0x6B 添加密钥
VK_SEPARATOR0x6C 分隔键
VK_SUBTRACT0x6D 减去关键
VK_DECIMAL0x6E 十进制键
VK_DIVIDE0x6F 划分密钥
VK_F10x70 F1键
VK_F20x71 F2键
VK_F30x72 F3键
VK_F40x73 F4键
VK_F50x74 F5键
VK_F60x75 F6键
VK_F70x76 F7键
VK_F80x77 F8键
VK_F90x78 F9键
VK_F100x79的 F10键
VK_F110x7A F11键
VK_F120x7B F12键
VK_F130x7C F13键
VK_F140x7D F14键
VK_F15的0x7E F15键
VK_F160x7F的 F16键
VK_F170x80的 F17键
VK_F180×81 F18键
VK_F19为0x82 F19键
VK_F200×83 F20键
VK_F21的0x84 F21键
VK_F220x85 F22键
VK_F230x86可以 F23键
VK_F2487H的 F24键
**-**0x88-8F 未分配
VK_NUMLOCK的0x90 NUM LOCK键
VK_SCROLL0x91 滚动锁定键
0x92-96 OEM特定
**-**0x97-9F 未分配
VK_LSHIFT0XA0 左SHIFT键
VK_RSHIFT0xA1 右SHIFT键
VK_LCONTROL0xA2 左控制键
VK_RCONTROL0xA3执行 右控制键
VK_LMENU0xA4 左MENU键
VK_RMENU的0xA5 右键MENU
VK_BROWSER_BACK0xA6 浏览器返回键
VK_BROWSER_FORWARD0xA7 浏览器转发键
VK_BROWSER_REFRESH0xA8 浏览器刷新键
VK_BROWSER_STOP0xA9 浏览器停止键
VK_BROWSER_SEARCH和0xAA 浏览器搜索键
VK_BROWSER_FAVORITES是0xAB 浏览器收藏夹键
VK_BROWSER_HOME0xAC 浏览器开始和主页键
VK_VOLUME_MUTE0xAD,将 音量静音键
VK_VOLUME_DOWN0xAE 降低音量键
VK_VOLUME_UP0xAF执行 提高音量键
VK_MEDIA_NEXT_TRACK0XB0 下一曲目键
VK_MEDIA_PREV_TRACK0xB1 上一曲目键
VK_MEDIA_STOP0xB2 停止媒体键
VK_MEDIA_PLAY_PAUSE0xB3 播放/暂停媒体键
VK_LAUNCH_MAIL0xB4 启动邮件密钥
VK_LAUNCH_MEDIA_SELECT0xB5执行 选择媒体键
VK_LAUNCH_APP10xB6 启动应用程序1键
VK_LAUNCH_APP20xB7 启动应用程序2密钥
**-**0xB8-B9 保留的
VK_OEM_10xBA 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,使用’;:'键
VK_OEM_PLUS为0xBB 对于任何国家/地区,请使用“+”键
VK_OEM_COMMA0xBC 对于任何国家/地区,请使用“,”键
VK_OEM_MINUS0xBD 对于任何国家/地区,请使用“ - ”键
VK_OEM_PERIOD0xBE 对于任何国家/地区,’。’ 键
VK_OEM_2为0xBF 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,’/?’ 键
VK_OEM_3将0xC0 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,使用’〜'键
**-**0xC1-D7 保留的
**-**0xD8-DA 未分配
VK_OEM_4位于0xDB 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,’[{'键
VK_OEM_5的0xDC 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,’\ |’ 键
VK_OEM_60xDD 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,使用’]}'键
VK_OEM_7写0xDE 用于杂项字符; 它可以因键盘而异。 对于美国标准键盘,“单引号/双引号”键
VK_OEM_80xDF 用于杂项字符; 它可以因键盘而异。
**-**取0xE0 保留的
0xE1 OEM特定
VK_OEM_1020xE2 RT 102键键盘上的尖括号键或反斜杠键
0xE3-E4 OEM特定
VK_PROCESSKEY为0xE5 IME PROCESS键
0xE6 OEM特定
VK_PACKET0xE7 用于传递Unicode字符,就像它们是击键一样。VK_PACKET键是用于非键盘输入方法的32位虚拟键值的低位字。有关更多信息,请参阅KEYBDINPUTSendInputWM_KEYDOWNWM_KEYUP中的备注
**-**0xE8 未分配
0xE9-F5 OEM特定
VK_ATTN0xF6 关键
VK_CRSEL0xF7 CrSel密钥
VK_EXSEL0xF8的 ExSel密钥
VK_EREOF0xF9 擦除EOF键
VK_PLAY0xFA回应 播放键
VK_ZOOM0xFB的才能 缩放键
VK_NONAME0xFC有 保留的
VK_PA10xFD PA1键
VK_OEM_CLEAR0xFE的 清除键

官方参考手册: https://docs.microsoft.com/en-us/windows/desktop/inputdev/virtual-key-codes

03. ReadConsoleInput函数

从控制台输入缓冲区读取数据并将其从缓冲区中删除。

函数声明:

BOOL WINAPI ReadConsoleInput(_In_  HANDLE        hConsoleInput,_Out_ PINPUT_RECORD lpBuffer,_In_  DWORD         nLength,_Out_ LPDWORD       lpNumberOfEventsRead
);
功能:从控制台输入缓冲区读取数据并将其从缓冲区中删除。
参数:hConsoleInput 控制台输入缓冲区的句柄。句柄必须具有GENERIC_READ访问权限。lpBuffer 指向接收输入缓冲区数据的INPUT_RECORD结构数组的指针。nLength 数组元素中lpBuffer参数 指向的数组大小。lpNumberOfEventsRead 指向接收读取的输入记录数的变量的指针。返回值:如果函数成功,则返回值为非零值。如果函数失败,则返回值为零。要获取扩展错误信息,请调用GetLastError。

官方参考网址:https://docs.microsoft.com/en-us/windows/console/readconsoleinput

04. 示例程序

示例程序一:

用户按下ESC键,则终端输出ESC


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#include<string.h>
#include<stdlib.h>#include <Windows.h>
#include <conio.h>int main(void)
{//定义句柄变量HANDLE hOut = NULL;HANDLE hIn = NULL;//定义输入事件结构体INPUT_RECORD keyRecord;//用于存储读取记录DWORD res;//获取标准输出句柄hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输入句柄hIn = GetStdHandle(STD_INPUT_HANDLE);while (1){//读取输入事件ReadConsoleInput(hIn, &keyRecord, 1, &res);//如果当前事件是键盘事件if (keyRecord.EventType == KEY_EVENT){//单击鼠标左键if (keyRecord.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE){printf("用户按下了ESC键");}}}//关闭句柄CloseHandle(hOut);CloseHandle(hIn);//system("pause");getchar();return 0;
}

在上面的样例程序中,当你按下Esc键后又马上释放,程序会输出两次Esc,因为有两次事件的虚拟键代码都是Esc键的代码,一次是按下,一次是释放。如果要实现按下键后出现反应,释放不出现反应。

代码优化如下:

     //如果当前事件是键盘事件if (keyRecord.EventType == KEY_EVENT){//单击按键左键  如果是按下就输出, 如果是释放就不输出if (keyRecord.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE&& keyRecord.Event.KeyEvent.bKeyDown == 1){printf("用户按下了ESC键");}}

示例程序二:


#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>
#include<string.h>
#include<stdlib.h>#include <Windows.h>
#include <conio.h>int main(void)
{//定义句柄变量HANDLE hOut = NULL;HANDLE hIn = NULL;//定义输入事件结构体INPUT_RECORD keyRecord;//用于存储读取记录DWORD res;//获取标准输出句柄hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输入句柄hIn = GetStdHandle(STD_INPUT_HANDLE);while (1){//读取输入事件ReadConsoleInput(hIn, &keyRecord, 1, &res);//如果当前事件是键盘事件if (keyRecord.EventType == KEY_EVENT){//单击按键左键  如果是按下就输出, 如果是释放就不输出if (keyRecord.Event.KeyEvent.wVirtualKeyCode == 'B'&& keyRecord.Event.KeyEvent.bKeyDown == 1){if (keyRecord.Event.KeyEvent.dwControlKeyState & CAPSLOCK_ON){printf("B");}else{printf("b");}}}}//关闭句柄CloseHandle(hOut);CloseHandle(hIn);//system("pause");getchar();return 0;
}

【注意】

各个控制键状态的的确定并不是使用等于符号==而是按位与&运算符,因为在同一时刻可能有多种控制键状态值,比如各种锁定都被打开且各种控制键也被同时按下。因为使用位操作,方便查询各个控制键的状态而不使之出现冲突。

【C语言】控制台窗口图形界面编程(八):键盘事件相关推荐

  1. 如何打开电脑c语言窗口,C语言控制台窗口图形界面编程(五). -电脑资料

    控制文本的移动是控制台窗口界面编程的一个很重要的功能,有了这个功能我们可以实现界面的滚动, BOOL ScrollConsoleScreenBuffer(      //文本移动函数 HANDLE h ...

  2. C语言控制台窗口图形界面编程

    一:设置句柄与窗口信息 在Windows操作系统下用C语言编写控制台的窗口界面首先要获取当前标准输入和标准输出设备的句柄.通过调用函数GetStdHandle可以获取当前标准输入以及输出设备的句柄.函 ...

  3. C语言控制台窗口图形界面编程(五).

    控制文本的移动是控制台窗口界面编程的一个很重要的功能,有了这个功能我们可以实现界面的滚动.下面我们介绍一个控制文本移动的函数,如下: BOOL ScrollConsoleScreenBuffer(   ...

  4. C语言控制台窗口图形界面编程(七):键盘事件

    输入事件中的键盘事件通常有字符事件和按键事件,这些事件的附带信息构成了键盘输入的信息,而想要读取这些信息,是要通过API函数ReadConsoleInput来获取的,函数原型如下: 1 BOOL Re ...

  5. 【C语言】控制台窗口图形界面编程(一)句柄和文本属性

    00. 目录 文章目录 00. 目录 01. 句柄 02. GetStdHandle函数 03. CloseHandle函数 04. SetConsoleTextAttribute函数 05. 十进制 ...

  6. 【C语言】控制台窗口图形界面编程(三)窗口相关设置

    00. 目录 文章目录 00. 目录 01. GetConsoleTitle函数 02. SetConsoleTitle函数 03. SetConsoleScreenBufferSize函数 04. ...

  7. 【C语言】控制台窗口图形界面编程(二)窗口信息和填充缓冲区

    00. 目录 文章目录 00. 目录 01. COORD结构体 02. SMALL_RECT结构 03. CONSOLE_SCREEN_BUFFER_INFO结构体 04. GetConsoleScr ...

  8. 【C语言】控制台窗口图形界面编程(七):鼠标事件

    00. 目录 文章目录 00. 目录 01. INPUT_RECORD结构 02. MOUSE_EVENT_RECORD结构 03. ReadConsoleInput函数 04. 示例程序 01. I ...

  9. 【C语言】控制台窗口图形界面编程(五):文本移动

    00. 目录 文章目录 00. 目录 01. CHAR_INFO结构 02. ScrollConsoleScreenBuffer函数 03. 程序示例 04. 官方参考程序 01. CHAR_INFO ...

最新文章

  1. android 动画 最顶层_【Android编程实战】StrandHogg漏洞复现及原理分析_Android系统上的维京海盗...
  2. postgres 支持的线程数_为什么 Java 坚持多线程不选择协程?
  3. 20145335郝昊《网络攻防》Bof逆向基础——ShellCode注入与执行
  4. non-rigid shape registration using similarity-invariant differential coordinates
  5. MATLAB R2018a 安装教程
  6. ubuntu下eclipse搭建安卓开发环境
  7. php实现微信登录详细教程,[文档教程]PHP实现微信开放平台扫码登录源码下载 - 技术编程 - 极思维...
  8. Java8 实战系列-02-lambda 表达式简介
  9. 【单片机仿真】(二)keil 安装教程
  10. edge设置IE兼容模式
  11. 计算机大专学历,2019如何应届毕业薪水过万!
  12. this指向 改变this指向
  13. 南通大学计算机科学与技术在哪个校区,南通大学各校区分别哪些专业
  14. BUUCTF SimpleRev(涉及大小端序存储的问题)
  15. 当前开源的SLAM方案汇总2021.02
  16. Android Studio 开发
  17. 真正的美剧字幕组翻译高手教你如何学好英语!心得经验之谈啊!
  18. java中Stream的使用以及List转set和map方法
  19. python安装教程——最新详细版
  20. 7-14 周游世界 周游世界是件浪漫事,但规划旅行路线就不一定了…… 全世界有成千上万条航线、铁路线、大巴线,令人眼花缭乱。所以旅行社会选择部分运输公司组成联盟,每家公司提供一条线路,然后帮助客户规划

热门文章

  1. Intel Quiet System Technology (QST) Support In ...
  2. Functions are not valid as a React child. This may happen if you return a Component instead of 「Comp
  3. 2021年焊工(初级)考试资料及焊工(初级)免费试题
  4. 小米笔记本2020版云测评
  5. 计算机组成原理学习笔记——计算机外围设备
  6. MATLAB基本常识
  7. Centos7安装trash-cli
  8. 通用文件清除脚本,可对多个指定目录按照磁盘空间、文件保存天数进行清理,并可设置目录扫描深度
  9. 怎样提高解决问题的能力
  10. 升职加薪/积分落户必备职称——2020年中级经济师不容错过