个性化 CMD 选择菜单的实现
控制台程序编程中,如果主菜单总是需要输入数字选择,那显得很不直观,不像正常主菜单方向键可以上下移动选择按钮,所以这一次写代码的时候就直接改善此问题!
一、效果预览
二、原理详释
1.1 控制台窗口光标移动
原本控制台的光标是逐文本向后的,我们要想实现任意位置的文本重输出就需要将光标移动到指定位置,然后覆盖原文本。但是, Windows 系统并没有为我们提供相应的 API ,所以我们需要自己编写一个函数用来控制控制台光标的位置。
1 | //定位函数 |
注释:
COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标。其定义为:
1 | typedef struct _COORD { |
1.2 键盘事件监听
输入事件中的键盘事件通常有字符事件和按键事件,这些事件的附带信息构成了键盘输入的信息,而想要读取这些信息,是要通过API函数 ReadConsoleInput来获取的,函数原型如下:
1 |
|
另外还需要了解几个和读取键盘输入事件有关的结构体,各结构体原型如下:
1 | typedef struct _INPUT_RECORD //输入事件结构体 |
接下来我们可以写一个最简单的实例代码以供参考:
1 |
|
注意:
在上面的样例程序中,当你按下Esc键后又马上释放,程序会输出两次Esc,因为有两次事件的虚拟键代码都是Esc键的代码,一次是按下,一次是释放。如果要实现按下键后出现反应,释放不出现反应,那么需将上例程序中第18行代码的条件改成:
1 | if (keyrec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE |
根据控制键的状态我们可以实现不同的状态输出不同的值以及组合键的实现,下面的样例程序在大写锁定打开时输入A键则输出大写字母A,否则输出小写字母a。而在Shift键被按下的状态是则输出Shift+A以及Shift+a。样例程序如下:
1 |
|
最后附上部分常用虚拟键代码表:
虚拟键代码 | 值 | 键名称 |
---|---|---|
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 | .>键 |
1.3 控制台文本颜色控制
控制台局部文本样式是通过控制台的转义序列来实现的,这是文本模式下的系统显示功能。转义序列是以ESC开始的,即\033,ESC的十进制是27,转为八进制就是33了。
通用格式大致为ESC[{attr1};{attr2};…;{attrn}m
,其中 attr 表示的是属性,也是属性值,通常直接就是数字表示了。在此我们进行三个常用属性的设置,主要是显示方式、字体颜色和背景色。
1 | 显示方式 |
1 | 字体颜色 |
1 | 背景色 |
下面给出一个参考实例,仅供参考:
1 | printf("\033[4;31;42m*测试文本*\033[0m"); |
效果图:
三、结束语
到这里,相关的核心知识点都已经总结完成。剩下的具体功能还需要自己自行开发和实现,过多的叙述往往会限制大家的创造能力。所以,相关的逻辑代码就由大家自己完成吧!
补充一下,那个按键选择实际上并不是真的有个按键,而是通过光标重新定位然后覆盖原输出,做出按键选择到了该位置的假象…好了,就说这么多吧!拜拜ヾ(•ω•`)o~