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

时间:2022-11-27 20:48:31

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 pressed again? Thank you all

我有一个win32应用程序,需要打开一个控制台,比如当tilde被按压时的游戏。我认为最好的解决方案是使用CreateWindow函数。这是正确的吗?我怎么能让它与主窗口重叠,然后在再次按下tilde时隐藏它呢?谢谢大家

4 个解决方案

#1


3  

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.

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

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.

出于这个原因,我同意你的直觉,反对使用真正的“控制台”窗口。使用文本编辑器创建自己的窗口,因为您将开发任何其他UI组件,如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?

您是否应该使用CreateWindow还很难说:您如何完成GUI的其余部分?举吗?GDI吗?一些工具包?您是否正在使用其他标准的windows控件?

#2


3  

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

这是一些很旧的代码,甚至还没有仔细检查过。希望这是你需要的。如果只需要一个非常简单的函数,也可以调用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 );

}

#3


2  

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

这里的解决方案不起作用,因为Windows SDK的新版本通过以下方式定义文件结构:

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

当试图用=操作符覆盖stdin/out文件结构时,只复制一个指针。要复制整个文件结构,必须在windows之前定义文件结构。h包括:

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

如果这对您来说是不可能的,您仍然可以将自己的文件结构定义为FILE_COMPLETE,并使用这个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);

#4


0  

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

我发现这个小教程/代码示例很有用。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.

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

#1


3  

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.

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

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.

出于这个原因,我同意你的直觉,反对使用真正的“控制台”窗口。使用文本编辑器创建自己的窗口,因为您将开发任何其他UI组件,如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?

您是否应该使用CreateWindow还很难说:您如何完成GUI的其余部分?举吗?GDI吗?一些工具包?您是否正在使用其他标准的windows控件?

#2


3  

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

这是一些很旧的代码,甚至还没有仔细检查过。希望这是你需要的。如果只需要一个非常简单的函数,也可以调用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 );

}

#3


2  

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

这里的解决方案不起作用,因为Windows SDK的新版本通过以下方式定义文件结构:

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

当试图用=操作符覆盖stdin/out文件结构时,只复制一个指针。要复制整个文件结构,必须在windows之前定义文件结构。h包括:

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

如果这对您来说是不可能的,您仍然可以将自己的文件结构定义为FILE_COMPLETE,并使用这个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);

#4


0  

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

我发现这个小教程/代码示例很有用。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.

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