国外模板网站,哪个旅游网站可以做私人定制,小程序推广任务,建设企业网站有什么好处1 前言
正常情况下#xff0c;我们在控制台程序中只关注程序的输入和输出#xff0c;而不在意输出的格式、光标位置等。 因此#xff0c;当我们想要完美控制程序的输入输出时#xff0c;就必须要使用系统提供的操作接口#xff0c;来实现我们的目标。 由于linux平台的控制…1 前言
正常情况下我们在控制台程序中只关注程序的输入和输出而不在意输出的格式、光标位置等。 因此当我们想要完美控制程序的输入输出时就必须要使用系统提供的操作接口来实现我们的目标。 由于linux平台的控制台显示完全由ANSI 转义序列控制在这里仅仅讨论windows平台的实现。
2 接口
window系统提供了大量由于操作控制台的函数以下列举了一些常用函数。
功能说明CreateConsoleScreenBuffer创建控制台屏幕缓冲区。FillConsoleOutputCharacter将字符写入控制台屏幕缓冲区指定的次数。FlushConsoleInputBuffer刷新控制台输入缓冲区。GetConsoleCursorInfo检索有关指定控制台屏幕缓冲区的光标大小和可见性的信息。GetConsoleScreenBufferInfo检索有关指定控制台屏幕缓冲区的信息。GetConsoleWindow检索与调用进程关联的控制台使用的窗口句柄。GetNumberOfConsoleInputEvents检索控制台的输入缓冲区中未读输入记录的数目。GetStdHandle检索标准输入、标准输出或标准错误设备的句柄。PeekConsoleInput从指定的控制台输入缓冲区读取数据而不将其从缓冲区中删除。ReadConsole从控制台输入缓冲区读取字符输入并将其从缓冲区中删除。ReadConsoleInput从控制台输入缓冲区读取数据并将其从缓冲区中删除。ReadConsoleOutput从控制台屏幕缓冲区中的字符单元格矩形块读取字符和颜色属性数据。ReadConsoleOutputCharacter从控制台屏幕缓冲区的连续单元格复制多个字符。ScrollConsoleScreenBuffer移动屏幕缓冲区中的数据块。SetConsoleActiveScreenBuffer将指定的屏幕缓冲区设置为当前显示的主机屏幕缓冲区。SetConsoleCursorInfo为指定的控制台屏幕缓冲区设置光标的大小和可见性。SetConsoleCursorPosition设置指定控制台屏幕缓冲区中的光标位置。SetConsoleMode设置控制台输入缓冲区的输入模式或控制台屏幕缓冲区的输出模式。SetConsoleOutputCP设置与调用进程关联的控制台使用的输出代码页。SetConsoleScreenBufferSize更改指定控制台屏幕缓冲区的大小。SetConsoleTitle设置当前控制台窗口的标题。SetConsoleWindowInfo设置控制台屏幕缓冲区窗口的当前大小和位置。SetStdHandle设置标准输入、标准输出或标准错误设备的句柄。WriteConsole从当前光标位置开始将字符串写入控制台屏幕缓冲区。WriteConsoleInput将数据直接写入控制台输入缓冲区。WriteConsoleOutput将字符和颜色属性数据写入控制台屏幕缓冲区中的指定矩形字符单元格块。WriteConsoleOutputCharacter将多个字符复制到控制台屏幕缓冲区的连续单元格。
3 示例
3.1 创建新的控制台
使用读写权限GENERIC_READ | GENERIC_WRITE创建控制台缓冲区同时设置读共享FILE_SHARE_READ。(此处必须设置读共享否终在替换缓冲区后无法从标准输入获取输入信息。) 创建句柄后将创建的句柄设置为当前活动缓冲区在不影响旧的缓冲区前提下用新的屏幕替代。 HANDLE hOutput CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,CONSOLE_TEXTMODE_BUFFER, NULL);// replace STD_OUTPUT_HANDLE with hOutputSetConsoleActiveScreenBuffer(hOutput);3.2 设置无滚动条
Windows并未提供滚动条设置的相关接口但是分析可以发现之所以出现滚动条是因为屏幕缓冲区的大小比实际窗口的大因此才会出现纵向滚动条。 在此前提下我们可以通过设置屏幕缓冲区的大小和窗口大小保持一致来隐藏滚动条。 CONSOLE_SCREEN_BUFFER_INFO screen_info;// 获取当前缓冲区信息GetConsoleScreenBufferInfo(hOutput, screen_info);// 根据窗口大小计算长宽height screen_info.srWindow.Bottom - screen_info.srWindow.Top 1;width screen_info.srWindow.Right - screen_info.srWindow.Left 1;// 设置屏幕缓冲区的大小SetConsoleScreenBufferSize(hOutput, {width, height});3.3 获取标准输入
首先获取输入句柄同时清空之前的消息。从控制台读取一个事件记录。 注意所有的控制台读写函数都是阻塞的因此可以通过GetNumberOfConsoleInputEvents 获取当前输入缓冲区中的事件数。 HANDLE hInput GetStdHandle(STD_INPUT_HANDLE);FlushConsoleInputBuffer(hInput);INPUT_RECORD record;common::ulong number;if (ReadConsoleInput(hInput, record, 1, number)) {// 判断是否键盘输入且是按下按键操作if (record.EventType KEY_EVENT record.Event.KeyEvent.bKeyDown) {key record.Event.KeyEvent.wVirtualKeyCode;}}3.4 数据输出到屏幕
清楚指定位置的屏幕同时在指定位置打印数据。
void Clear(COORD target) {common::ulong length 0;// 使用空格字符覆盖指定的行长度为窗口大小FillConsoleOutputCharacterA(hOutput, 0x20, width 1, target, length);
}void Print(const char* str, common::ulong len, COORD target) {common::ulong length 0;// 清除旧数据Clear(target);// 从指定位置开始打印字符串WriteConsoleOutputCharacterA(hOutput, str, len, target, length);
}4 完整示例
Window 平台实现简单的进程信息查看。simple_taskmgr