C++WinAPI-GetConsoleScreenBufferInfo总是因无效句柄而失败(返回0)



我正在编写一个简单的程序,以字符/行的形式输出控制台的正确(和当前(宽度和高度。

#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_INPUT_HANDLE), &csbiInfo);
cout << csbiInfo.dwSize.X;
cout << csbiInfo.srWindow.Bottom - csbiInfo.srWindow.Top;
system("PAUSE");
}

但是,当GetStdHandle未返回INVALID_HANDLE_VALUE时,GetConsoleScreenBufferInfo失败(返回0(,错误代码为0x6(无效句柄(

我还尝试过使用GetConsoleWindow((;代替GetStdHandle无效。

我使用的是windows 10和VS2017。我有一种感觉,我可能会不知所措,或者急于做一些过于系统化的事情。

提前感谢您提供任何解决方案/替代方案。

STD_INPUT_HANDLE通常连接到终端键盘。STD_OUTPUT_HANDLE和STD_ERROR_HANDLE通常用作控制台。假设STD_INPUT_HANDLE不能被"GetConsoleScreenBufferInfo(("标识为"控制台句柄"。您可以使用"STD_OUTPUT_HANDLE"来获取控制台句柄。

#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbiInfo);
cout << csbiInfo.dwSize.X;
cout << csbiInfo.srWindow.Bottom - csbiInfo.srWindow.Top;
system("PAUSE");
}

虽然吴的回答是一个很好的提示。。。哦,我在说什么,这个问题也是一个很好的暗示。德雷克的回答是否定的。

我被这个问题困扰了好几天,并且有了解决办法和理由。

问题是MSDN对此函数GetConsoleBufferInfo的文档不完善。再也没有人关心控制台了,而是在其他地方讨论它。安卓系统是主流,它为控制台和终端提供了中指。

MSDN声明句柄必须是控制台输出句柄。它不会告诉你如何处理。

HANDLE h_out = CreateFile("CONOUT$",GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

HANDLE h_out = GetStdHandle(STD_OUTPUT_HANDLE);

然后它说句柄必须具有GENERIC_READ访问权限。见鬼!!!控制台输入是否应该具有GENERIC_READ访问权限???哦他们可以同时拥有这两种访问权限。

HANDLE h_out = CreateFile("CONOUT$",GENERIC_WRITE|GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);

分配给STD_OUTPUT_HANDLE的操作类似。以下是如何使GetConsoleBufferInfo接受您的句柄。

但是很好,很棒!!!一个控制台句柄可以同时具有两个访问权限。我将使用一个手柄,而不是使用两个手柄!!!就像posix一样。

char buf[90];
HANDLE fhandle = CreateFile("CONOUT$",GENERIC_WRITE|GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
WriteFile(fhandle,"I am not accepting input from this handle",90,NULL,0);
// ReadFile fails
ReadFile(fhandle,buf,90,NULL,0);

这太糟糕了。那么,为什么CONOUT具有GENERIC_READ访问权限呢?你知道吗?用CreateFile拧开端子。

附言:微软控制台api的麻烦比它的价值还大。posix函数_open、_read、_write你应该坚持;除非你需要或想做某些事情,比如巧妙地改变文本和背景的颜色。控制台api的一个大问题是在读取大量请求时失败。

Read/WriteFile(handle,buf,65000 bytes!,0,0)  // fails

然而

_read/_write(fd,buf,100000 more bytes) // doesnt fail, plus it has less parameters

PS^2自从我开始学习Cpp以来,我一直在设计实用程序库。这就是我目前支持Win32和Linux的文件库。我现在想把它们提供给更广泛的公众,如果它们在帮助我解决问题时有用的话。我的电子邮件地址是d.master51@yahoo.com

最新更新