我正在编写一个简单的程序,以字符/行的形式输出控制台的正确(和当前)宽度和高度。
#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。我感到自己可能要么烦躁不安,要么正在努力做一些特定于系统的事情。
在此先感谢您提供任何解决方案/替代方案。
答案 0 :(得分:1)
STD_INPUT_HANDLE通常连接到终端键盘。 通常将STD_OUTPUT_HANDLE和STD_ERROR_HANDLE用作控制台。因此,可以说“ GetConsoleScreenBufferInfo()”无法将STD_INPUT_HANDLE标识为“控制台句柄”。您可以使用“ 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");
}
答案 1 :(得分:0)
虽然Drake Wu的回答是一个很好的提示...哦,我在说什么,这个问题是相同的很好的提示。德雷克的答案是没有答案。
几天来我一直在遭受这个问题的困扰,并且找到了解决方案和原因。
问题在于该功能的GetConsoleBufferInfo的MSDN文档不佳。再也没有人关心控制台在其他地方讨论它了。 Android是内置物,它为控制台和终端提供了中指。
MSDN声明该句柄必须是控制台输出句柄。它没有告诉您如何获取该句柄。
HANDLE h_out = CreateFile("CONOUT$",GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
OR
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拧开端子。
PS:Microsoft控制台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