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

时间:2018-11-12 05:31:28

标签: c++ windows winapi

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

#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。我感到自己可能要么烦躁不安,要么正在努力做一些特定于系统的事情。

在此先感谢您提供任何解决方案/替代方案。

2 个答案:

答案 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