c++ SetConsoleMode函数与GetConsoleMode


前言

我前面写了一个关于禁用点击、Ctrl+C暂停程序的代码
这里面出现了一个SetConsoleMode函数
那么他是什么意思呢?

SetConsoleMode

在C++中,SetConsoleMode 函数是一个Windows API函数,用于设置控制台窗口的输入或输出模式。这个函数对于处理键盘输入(如启用或禁用Ctrl+C处理)、控制输出格式(如是否将换行符转换为回车加换行对)等场景非常有用。

构造

BOOL SetConsoleMode(
  HANDLE hConsoleHandle,
  DWORD  dwMode
);
  • hConsoleHandle:控制台输入或输出句柄。通常,你可以通过GetStdHandle函数获取标准输入(STD_INPUT_HANDLE)、标准输出(STD_OUTPUT_HANDLE)或标准错误(STD_ERROR_HANDLE)的句柄。
  • dwMode:指定要设置的模式。这个参数是一个位掩码,可以包含多个标志,用于控制控制台的行为。

GetConsoleMode

刚才的是SetConsoelModeSet是设置控制台模式
顾名思义,GetConsoleMode获取控制台模式

构造

bool GetConsoleMode(  
  HANDLE hConsoleHandle,  
  LPDWORD lpMode  
);
  • hConsoleHandle:是控制台输入或输出句柄的句柄。上面已经说过了。
  • lpMode:是一个指向 DWORD 变量的指针,该变量接收当前的控制台模式。

示例

这是一个禁用Ctrl+C暂停程序的事例

#include <windows.h>
#include <iostream>

int main() {
    HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
    DWORD mode;

    // 获取当前控制台输入模式
    if (!GetConsoleMode(hStdin, &mode)) {
        std::cerr << "GetConsoleMode failed" << std::endl;
        return 1;
    }

    // 禁用Ctrl+C处理
    mode &= ~ENABLE_PROCESSED_INPUT;

    // 设置新的控制台输入模式
    if (!SetConsoleMode(hStdin, mode)) {
        std::cerr << "SetConsoleMode failed" << std::endl;
        return 1;
    }

    // 现在,Ctrl+C将不会被处理为中断信号
    // ...

    return 0;
}

更多的dwMode的标志码

这些标志位控制着控制台窗口的多种行为,如是否处理Ctrl+C作为中断信号、是否支持虚拟终端序列等。
以下是一些常用的dwMode标志位:

  • ENABLE_PROCESSED_INPUT:如果设置了此模式,控制台会处理Ctrl+C作为中断信号(通常会导致程序终止)。如果未设置,Ctrl+C等组合键将不会被自动处理,程序需要自行处理这些按键事件。

  • ENABLE_LINE_INPUT:如果设置了此模式,输入函数(如ReadConsoleReadFile在控制台模式下)会将输入视为行输入,即直到接收到换行符(Enter键)为止,输入才会被处理。如果未设置,输入将被视为字符输入,每个字符都可以立即被读取。

  • ENABLE_ECHO_INPUT:如果设置了此模式,输入的字符将在屏幕上回显(即用户输入的字符会显示在控制台上)。如果未设置,输入的字符将不会回显。

  • ENABLE_WINDOW_INPUT:此标志位通常与鼠标输入相关,但在较新版本的Windows中,它可能已被其他机制(如ENABLE_VIRTUAL_TERMINAL_INPUT)所取代。

  • ENABLE_VIRTUAL_TERMINAL_INPUT:从Windows 10 1607(版本14393)开始,此模式允许控制台窗口接收虚拟终端输入序列(如ANSI转义序列)。这对于支持颜色输出、光标控制等高级文本控制功能非常有用。

  • ENABLE_VIRTUAL_TERMINAL_PROCESSING:与ENABLE_VIRTUAL_TERMINAL_INPUT类似,但此模式应用于输出流。当设置此模式时,控制台窗口将解释ANSI转义序列,从而允许程序控制文本颜色、光标位置等。

  • ENABLE_EXTENDED_FLAGS:启用或禁用扩展的输入模式标志。这个标志本身不改变任何行为,但它必须与其他输入模式标志(如ENABLE_QUICK_EDIT_MODE)一起使用,以启用或禁用这些扩展功能。
  • ENABLE_INSERT_MODE:如果启用,则输入的文本将插入到当前光标位置,而不是覆盖该位置后面的文本。如果禁用(默认情况),则输入的文本会覆盖光标位置后面的文本。
  • ENABLE_QUICK_EDIT_MODE:如果启用,则用户可以使用鼠标选择和编辑控制台窗口中的文本。这通常与ENABLE_EXTENDED_FLAGS一起使用。
  • ENABLE_MOUSE_INPUT:如果启用,则鼠标事件(如鼠标移动和按钮点击)将被放入输入缓冲区,并可通过ReadConsoleInput等函数读取。

输出模式标志位

  • ENABLE_WRAP_AT_EOL_OUTPUT:如果启用(默认情况),则当输出到达控制台窗口的右边界时,文本将自动换行到下一行。如果禁用,则文本可能会继续在同一行上滚动,直到遇到换行符或控制台窗口大小改变。
  • ENABLE_VIRTUAL_TERMINAL_PROCESSING:如前所述,启用对虚拟终端序列(如ANSI转义序列)的支持,允许程序控制文本颜色、光标位置等。

注意事项

  • 并非所有标志位都适用于所有版本的Windows。例如,ENABLE_VIRTUAL_TERMINAL_PROCESSINGENABLE_VIRTUAL_TERMINAL_INPUT是在较新版本的Windows中引入的。
  • 某些标志位可能相互冲突或依赖于其他设置。因此,在修改控制台模式时,请务必了解每个标志位的作用和它们之间的相互作用。
  • 使用SetConsoleMode函数时,请确保传入的句柄是有效的,并且具有适当的访问权限。如果函数失败,请检查GetLastError函数返回的错误代码以获取更多信息。

请注意,这些标志位是位掩码,因此可以通过按位或(|)运算符组合多个标志位,通过按位与(&)和按位非(~)运算符修改标志位。

在Windows操作系统中,`GetConsoleMode`函数用于获取指定控制台流的当前控制模式,而`COORD`是一个结构体,常用于表示屏幕坐标的大小。如果你想通过这些函数消除控制台的输入提示,你需要做的是调整控制台的模式,禁止其显示行号和光标等提示信息。 首先,你需要包含必要的头文件: ```cpp #include <windows.h> #include <conio.h> ``` 然后,创建一个`COORD`结构体实例,定义你想要的新控制模式: ```cpp COORD new_mode = {0, 0}; // 禁止行号和光标显示 ``` 接下来,调用`GetConsoleMode`函数获取当前控制模式,再设置新的模式: ```cpp DWORD old_mode; if (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &old_mode)) { SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), old_mode | ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT); SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), old_mode & ~ENABLE_LaggedRedraw); // 关闭自动滚屏等特性 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 8 | 7); // 设置文本颜色和背景色,通常选择白色背景黑色文本 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), new_mode); // 移动到原点,隐藏光标 } ``` 最后记得在完成后恢复原来的控制模式,以防止对后续程序造成影响: ```cpp SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), old_mode); ``` 注意,这种方法适用于命令行应用,对于图形化界面或跨平台应用可能不适用。并且,频繁修改控制台模式可能会影响其他依赖于控制台特性的部分程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值