英文:
How to get the "output" (console screen buffer) Handle for GetConsoleMode() in Windows?
问题
我想在输入和输出上都使用 GetConsoleMode(),因为我想要更改一些标志。
输入部分相对来说比较简单:
HANDLE hStdin;
DWORD fdwSaveOldMode;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hStdin, &fdwSaveOldMode);
然而,输出部分似乎不那么简单。人们可能会认为只需使用 STD_OUTPUT_HANDLE 就足够了,但"帮助"页面提到需要创建和设置自己的缓冲区。
此外,有一篇关于句柄的页面提到:
在调用 CreateFile 时,使用 CONOUT$ 值来打开控制台的活动屏幕缓冲区的句柄。
这听起来像一个线索,但坦白地说,我不确定这是什么意思。有人能向我展示如何正确操作吗?为什么输出与输入如此不同?
谢谢!
英文:
I want to do GetConsoleMode() on both input and output because I want to change some flags.
Input is pretty straightforward:
HANDLE hStdin;
DWORD fdwSaveOldMode;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
GetConsoleMode(hStdin, &fdwSaveOldMode)
The output, on the other hand, doesn't seem as easy. One would think that just putting STD_OUTPUT_HANDLE would be enough, but the "help" pages talk about having to make and set your own buffer.
This, and a page about handles mention:
> Specify the CONOUT$ value in a call to CreateFile to open a handle to a console's active screen buffer.
Sounds like a clue, but frankly, I'm unsure what this even means. Can someone show me how to do it properly? Why is output so different than input?
Thank you!
答案1
得分: 1
一个人可能会认为只需使用STD_OUTPUT_HANDLE
就足够了。
确实如此。"清屏示例" (https://learn.microsoft.com/en-us/windows/console/clearing-the-screen) 中有一个代码片段演示了如何设置控制台输出模式,它使用了GetStdHandle()
:
HANDLE hStdOut;
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// 获取现有的控制台模式,以便正确添加一个标志而不关闭其他标志
DWORD mode = 0;
if (!GetConsoleMode(hStdOut, &mode))
{
return ::GetLastError();
}
// 保留原始模式,以便在退出时还原,以便与其他命令行应用程序协作
const DWORD originalMode = mode;
mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
// 尝试设置模式
if (!SetConsoleMode(hStdOut, mode))
{
return ::GetLastError();
}
在某些情况下,GetStdHandle
与特定于控制台的函数一起使用可能不起作用,这些情况包括应用程序不是控制台模式(您可以通过调用AllocConsole
在 GUI 模式应用程序中获取控制台),或者 stdout
被重定向。
在这些情况下,您需要通过CreateFile
打开一个控制台句柄,使用特殊的文件名"CONOUT$"
。这将始终访问一个控制台,如果与您的进程关联了一个控制台,即使stdout
未映射到该控制台。
英文:
> One would think that just putting STD_OUTPUT_HANDLE
would be enough
It is. The "Clearing the Screen" example has a snippet demonstrating setting console output modes, and it uses GetStdHandle()
:
> HANDLE hStdOut;
>
> hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
>
> // Fetch existing console mode so we correctly add a flag and not turn off others
> DWORD mode = 0;
> if (!GetConsoleMode(hStdOut, &mode))
> {
> return ::GetLastError();
> }
>
> // Hold original mode to restore on exit to be cooperative with other command-line apps.
> const DWORD originalMode = mode;
> mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
>
> // Try to set the mode.
> if (!SetConsoleMode(hStdOut, mode))
> {
> return ::GetLastError();
> }
Some cases where GetStdHandle
wouldn't work together with console-specific functions would be if the application isn't console-mode (you can get a console in a GUI-mode application by calling AllocConsole
) or if stdout
was redirected.
In those cases, you'd need to open a console handle via CreateFile
and the special filename "CONOUT$"
. That will always access a console, if one is associated with your process, even in case stdout
is not mapped to that console.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论