开发者

Create window console inside main win32 window

I have a win32 application that need to open a console like the games when tilde is pressed. I tought that the best solution is to use the CreateWindow function. Is this right? How could I make it overlapping the main window and hiding it when tilde is开发者_StackOverflow社区 pressed again? Thank you all


The solutions here won't work because newer versions of the Windows SDK define the FILE structure by:

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

When trying to overwrite the stdin/out FILE structures with the = operator, only one pointer will be copied. To copy the whole FILE struct, you have to define the FILE structure before your windows.h include:

#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>

If this is somehow not possible for you, you can still define your own FILE structure as FILE_COMPLETE and use this codesnippet:

#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);


It's often tempting to use a console window in your app (using AllocConsole), but it is definitely NOT a standard reusable Windows control. It has a lot of special behaviors and features which make it unique from a typical window.

For this reason, I would agree with your instinct, against using a true 'Console' window. Make your own window with a text editor in it, as you would develop any other UI component like a HUD.

Whether you should use CreateWindow is hard to say: how are you doing the rest of your GUI? DirectX? GDI? Some toolkit? Are you using other standard windows controls?


This is some pretty old code, haven't even really looked over it. Hopefully it's what you need. If you just need a very simple one you can also just make a call to 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 );

}


I found this little tutorial / code samples useful. http://www.halcyon.com/~ast/dload/guicon.htm

It creates a console and redirects STD_IN and STD_OUT to the console. So you can easily use std::cin and std::cout etc streams.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜