在主win32窗口中创建窗口控制台

时间:2011-02-21 16:21:18

标签: c++ winapi console

我有一个win32应用程序,需要在按下波浪符号时打开像游戏一样的控制台。我认为最好的解决方案是使用CreateWindow函数。这是正确的吗?我怎么能让它重叠主窗口并在再次按下波浪线时隐藏它?谢谢大家

4 个答案:

答案 0 :(得分:3)

这是一些非常古老的代码,甚至没有真正看过它。希望这是你需要的。如果你只需要一个非常简单的,你也可以只调用AllocConsole();

void DevConsole::Create(){

  CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
  int consoleHandleR, consoleHandleW ;
  long stdioHandle;
  FILE *fptr;

  AllocConsole();
  std::wstring strW = L"Dev Console";
  SetConsoleTitle( strW.c_str() );

  EnableMenuItem(GetSystemMenu(GetConsoleWindow(), FALSE), SC_CLOSE , MF_GRAYED);
  DrawMenuBar(GetConsoleWindow());

  GetConsoleScreenBufferInfo( GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo );

  stdioHandle = (long)GetStdHandle( STD_INPUT_HANDLE );
  consoleHandleR = _open_osfhandle( stdioHandle, _O_TEXT );
  fptr = _fdopen( consoleHandleR, "r" );
  *stdin = *fptr;
  setvbuf( stdin, NULL, _IONBF, 0 );

  stdioHandle = (long) GetStdHandle( STD_OUTPUT_HANDLE );
  consoleHandleW = _open_osfhandle( stdioHandle, _O_TEXT );
  fptr = _fdopen( consoleHandleW, "w" );
  *stdout = *fptr;
  setvbuf( stdout, NULL, _IONBF, 0 );

  stdioHandle = (long)GetStdHandle( STD_ERROR_HANDLE );
  *stderr = *fptr;
  setvbuf( stderr, NULL, _IONBF, 0 );

}

答案 1 :(得分:3)

在您的应用中使用控制台窗口(使用AllocConsole)通常很诱人,但它绝对不是标准的可重用Windows控件。它具有许多特殊的行为和特征,使其在典型的窗口中独一无二。

出于这个原因,我同意你的直觉,反对使用真正的“控制台”窗口。使用文本编辑器创建自己的窗口,就像开发任何其他UI组件(如HUD)一样。

您是否应该使用CreateWindow很难说:您如何使用其他GUI?的DirectX? GDI?一些工具包?您使用的是其他标准Windows控件吗?

答案 2 :(得分:3)

此处的解决方案无效,因为较新版本的Windows SDK通过以下方式定义FILE结构:

#ifndef _FILE_DEFINED
    #define _FILE_DEFINED
    typedef struct _iobuf
    {
        void* _Placeholder;
    } FILE;
#endif

尝试使用=运算符覆盖stdin / out FILE结构时,只会复制一个指针。要复制整个FILE结构,必须在windows.h包含之前定义FILE结构:

#ifndef _FILE_DEFINED
struct _iobuf {
        char *_ptr;
        int   _cnt;
        char *_base;
        int   _flag;
        int   _file;
        int   _charbuf;
        int   _bufsiz;
        char *_tmpfname;
        };
typedef struct _iobuf FILE;
#define _FILE_DEFINED
#endif

#include <Windows.h>

如果这对您来说不可能,您仍然可以将自己的FILE结构定义为FILE_COMPLETE并使用此代码片段:

#include <Windows.h>
#include <io.h>
#include <fcntl.h>

AllocConsole();
SetConsoleTitleA("ConsoleTitle");
typedef struct { char* _ptr; int _cnt; char* _base; int _flag; int _file; int _charbuf; int _bufsiz; char* _tmpfname; } FILE_COMPLETE;
*(FILE_COMPLETE*)stdout = *(FILE_COMPLETE*)_fdopen(_open_osfhandle((long)GetStdHandle(STD_OUTPUT_HANDLE), _O_TEXT), "w");
*(FILE_COMPLETE*)stderr = *(FILE_COMPLETE*)_fdopen(_open_osfhandle((long)GetStdHandle(STD_ERROR_HANDLE), _O_TEXT), "w");
*(FILE_COMPLETE*)stdin = *(FILE_COMPLETE*)_fdopen(_open_osfhandle((long)GetStdHandle(STD_INPUT_HANDLE), _O_TEXT), "r");
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);

答案 3 :(得分:0)

我发现这个小教程/代码示例很有用。 http://www.halcyon.com/~ast/dload/guicon.htm

它创建一个控制台并将STD_IN和STD_OUT重定向到控制台。 所以你可以轻松使用std :: cin和std :: cout等流。