扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
BOOL SetConsoleCursorInfo( // 设置光标信息 HANDLE hConsoleOutput, // 句柄 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo // 光标信息 ); BOOL GetConsoleCursorInfo( // 获取光标信息 HANDLE hConsoleOutput, // 句柄 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo // 返回光标信息 ); |
typedef struct _CONSOLE_CURSOR_INFO { DWORD dwSize; // 光标百分比大小 BOOL bVisible; // 是否可见 } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO; |
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; |
typedef struct _KEY_EVENT_RECORD { BOOL bKeyDown; // TRUE表示键按下,FALSE表示键释放 WORD wRepeatCount; // 按键次数 WORD wVirtualKeyCode; // 虚拟键代码 WORD wVirtualScanCode; // 虚拟键扫描码 union { WCHAR UnicodeChar; // 宽字符 CHAR AsciiChar; // ASCII字符 } uChar; // 字符 DWORD dwControlKeyState; // 控制键状态 } KEY_EVENT_RECORD; |
#include HANDLE hOut; HANDLE hIn; void DrawBox(bool bSingle, SMALL_RECT rc); void ClearScreen(void); void CharWindow(char ch, SMALL_RECT rc); // 将ch输入到指定的窗口中 void ControlStatus(DWORD state); // 在最后一行显示控制键的状态 void DeleteTopLine(SMALL_RECT rc); // 删除指定窗口中最上面的行并滚动 void main() { hOut = GetStdHandle(STD_OUTPUT_HANDLE); // 获取标准输出设备句柄 hIn = GetStdHandle(STD_INPUT_HANDLE); // 获取标准输入设备句柄 WORD att = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE ; // 背景是蓝色,文本颜色是黄色 SetConsoleTextAttribute(hOut, att); ClearScreen(); // 清屏 INPUT_RECORD keyRec; DWORD state = 0, res; char ch; SMALL_RECT rc = {20, 2, 40, 12}; DrawBox(true, rc); COORD pos = {rc.Left+1, rc.Top+1}; SetConsoleCursorPosition(hOut, pos); // 设置光标位置 for(;;) // 循环 { ReadConsoleInput(hIn, &keyRec, 1, &res); if (state != keyRec.Event.KeyEvent.dwControlKeyState) { state = keyRec.Event.KeyEvent.dwControlKeyState; ControlStatus(state); } if (keyRec.EventType == KEY_EVENT){ if (keyRec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) break; // 按ESC键退出循环 if (keyRec.Event.KeyEvent.bKeyDown) { ch = keyRec.Event.KeyEvent.uChar.AsciiChar; CharWindow(ch, rc); } } } pos.X = 0; pos.Y = 0; SetConsoleCursorPosition(hOut, pos); // 设置光标位置 CloseHandle(hOut); // 关闭标准输出设备句柄 CloseHandle(hIn); // 关闭标准输入设备句柄 } void CharWindow(char ch, SMALL_RECT rc) // 将ch输入到指定的窗口中 { static COORD chPos = {rc.Left+1, rc.Top+1}; SetConsoleCursorPosition(hOut, chPos); // 设置光标位置 if ((ch<0x20)||(ch>0x7e)) return; WriteConsoleOutputCharacter(hOut, &ch, 1, chPos, NULL); if (chPos.X>=(rc.Right-1)) { chPos.X = rc.Left; chPos.Y++; } if (chPos.Y>(rc.Bottom-1)) { DeleteTopLine(rc); chPos.Y = rc.Bottom-1; } chPos.X++; SetConsoleCursorPosition(hOut, chPos); // 设置光标位置 } void ControlStatus(DWORD state) // 在最后一行显示控制键的状态 { CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); COORD home = {0, bInfo.dwSize.Y-1}; WORD att0 = BACKGROUND_INTENSITY ; WORD att1 = FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_RED; FillConsoleOutputAttribute(hOut, att0, bInfo.dwSize.X, home, NULL); FillConsoleOutputCharacter(hOut, ' ', bInfo.dwSize.X, home, NULL); SetConsoleTextAttribute(hOut, att1); COORD staPos = {bInfo.dwSize.X-16,bInfo.dwSize.Y-1}; SetConsoleCursorPosition(hOut, staPos); if (state & NUMLOCK_ON) WriteConsole(hOut, "NUM", 3, NULL, NULL); staPos.X += 4; SetConsoleCursorPosition(hOut, staPos); if (state & CAPSLOCK_ON) WriteConsole(hOut, "CAPS", 4, NULL, NULL); staPos.X += 5; SetConsoleCursorPosition(hOut, staPos); if (state & SCROLLLOCK_ON) WriteConsole(hOut, "SCROLL", 6, NULL, NULL); SetConsoleTextAttribute(hOut, bInfo.wAttributes); // 恢复原来的属性 SetConsoleCursorPosition(hOut, bInfo.dwCursorPosition); // 恢复原来的光标位置 } void DeleteTopLine(SMALL_RECT rc) { COORD crDest; CHAR_INFO chFill; SMALL_RECT rcClip = rc; rcClip.Left++; rcClip.Right--; rcClip.Top++; rcClip.Bottom--; crDest.X = rcClip.Left; crDest.Y = rcClip.Top - 1; CONSOLE_SCREEN_BUFFER_INFO bInfo; GetConsoleScreenBufferInfo( hOut, &bInfo ); chFill.Attributes = bInfo.wAttributes; chFill.Char.AsciiChar = ' '; ScrollConsoleScreenBuffer(hOut, &rcClip, &rcClip, crDest, &chFill); } |
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者