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
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.
Related
I have a winapi program that I wish to not open any windows if executed with command line arguments. I can attach to the parent console perfectly and WriteConsoleA() works, but when I try to redirect C I/O, std::cout, and std::cin to the console (following the methodology of several StackOverflow posts about this subject), these will not write to the attached console as expected.
main.c -
#include <windows.h>
#include <stdio.h>
#include "cmd_line.h"
#include "dialog.h"
#include "resource.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
if(__argc > 1)
{
RedirectIOToConsole(); // Attaches and redirects
// Temporary tests
HANDLE consoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
char a[] = "hi";
WriteConsoleA(consoleOut, &a, 2, NULL, NULL); // Prints
printf("hi\n"); // Does not print
// External C++ function which performs my command line option via lots of std::cout and cin
CmdLine(__argc, __argv); // Does not print
}
else
// External C++ function to handle my winapi dialog
return DialogBox(hInstance, MAKEINTRESOURCE(IDD_MAIN), NULL, DlgProc);
}
part of cmd_line.cpp which implements RedirectIOToConsole() -
void RedirectIOToConsole()
{
int hConHandle;
long lStdHandle;
FILE *fp;
AttachConsole(ATTACH_PARENT_PROCESS);
// STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
// C++ streams to console
std::ios_base::sync_with_stdio();
}
Could someone please help me with a proper, working way to redirect stdio and iostream to this console? Thank you!
This should work, but I didn't test it:
void RedirectIOConsole()
{
freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONERR$", "w", stderr);
}
You should use stdout = fp;, not *stdout = *fp. The same in the other two assignments.
If no arguments are given to the program it launches as a GUI application, if it is given args it is run through the command line. I was able to get visual studio to display and print to the console with Properties>Linker>SubSystem (Console/SUBSYSTEM:CONSOLE), but this makes it so that the console always displays when the application is launched, how can I selectively display the console so that when the app is run with the GUI it does not appear. I have looked through the site, but all I have found is how to set it to only be a windows application, and I need it to function as both
Thanks!!!
This works I guess:
#include <QtGui/QApplication>
#include <QtGui/QMainWindow>
int
main(int n_app_args, char **app_arg)
{
QCoreApplication * application = 0;
if ( n_app_args == 1 )
{
application = new QCoreApplication(n_app_args, app_arg);
}
else
{
application = new QApplication(n_app_args, app_arg);
QMainWindow * mainWindow = new QMainWindow();
mainWindow->show();
}
return application->exec();
}
Call it with an argument and you get a little (empty) window. Call it with no argument and no window.
Here's some code I had lying around that creates a console and attaches input and output to it:
#include <Windows.h>
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
void Console::createConsole()
{
AllocConsole();
SetConsoleTitle("Debug console");
int hConHandle;
long lStdHandle;
FILE *fp; // redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
}
I haven't used Qt but you should be able to stick that somewhere and make it work.
Edit: added the headers needed
You can have it using the windows subsystem, and calling AllocConsole when you need a console while the application has a gui as well.
I am using _popen to start a process to run a command and gather the output
This is my c++ code:
bool exec(string &cmd, string &result)
{
result = "";
FILE* pipe = _popen(cmd.c_str(), "rt");
if (!pipe)
return(false);
char buffer[128];
while(!feof(pipe))
{
if(fgets(buffer, 128, pipe) != NULL)
result += buffer;
}
_pclose(pipe);
return(true);
}
Is there any way of doing this without a console window opening (as it currently does at the _popen statement)?
On Windows, CreateProcess with a STARTUPINFO structure that has dwFlags to include STARTF_USESSHOWWINDOW. Then setting STARTUPINFO.dwFlags to SW_HIDE will cause the console window to be hidden when triggered. Example code (which may be poorly formatted, and contains a mix of C++ and WinAPI):
#include <windows.h>
#include <iostream>
#include <string>
using std::cout;
using std::endl;
void printError(DWORD);
int main()
{
STARTUPINFOA si = {0};
PROCESS_INFORMATION pi = { 0 };
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
BOOL result = ::CreateProcessA("c:/windows/system32/notepad.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
if(result == 0) {
DWORD error = ::GetLastError();
printError(error);
std::string dummy;
std::getline(std::cin, dummy);
return error;
}
LPDWORD retval = new DWORD[1];
::GetExitCodeProcess(pi.hProcess, retval);
cout << "Retval: " << retval[0] << endl;
delete[] retval;
cout << "Press enter to continue..." << endl;
std::string dummy;
std::getline(std::cin, dummy);
return 0;
}
void printError(DWORD error) {
LPTSTR lpMsgBuf = nullptr;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
cout << reinterpret_cast<char*>(lpMsgBuf) << endl;
LocalFree(lpMsgBuf);
}
As far as I know, you can't1: you are starting a console application (cmd.exe, that will run the specified command), and Windows always creates a console window when starting a console application.
although, you can hide the window after the process started, or even create it hidden if you pass the appropriate flags to CreateProcess; problem is, _popen do not pass these flags, so you have to use the Win32 APIs instead of _popen to create your pipe.
[Final Edit]
a similar SO question merges everything said above and gets you your output
C++ popen command without console
[Edited again]
erk. sorry I got excited about spawning processes. I reread your q. and apart from the extra window you're actually trying to get the processes's stdout/stderr. I'd just like to add that for that purpose, all my suggestions are sadly irrelevant. but I'll leave them here for reference.
[Edited]
For no good specific reason (except that "open" works for both windows and macs), I use ShellExecute for spawning processes rather than CreateProcess. I'll research that later..but here is my StartProcess function.
Hidden or Minimized seem to produce the same result. the cmd window does come into being but it is minimized and doesn't ever pop up on the desktop which might be your primary goal.
#if defined(PLATFORM_WIN32)
#include <Windows.h>
#include <shellapi.h>
#elif defined(PLATFORM_OSX)
#include <sys/param.h>
#endif
namespace LGSysUtils
{
// -----------------------------------------------------------------------
// pWindow : {Optional} - can be NULL
// pOperation : "edit", "explore", "find", "open", "print"
// pFile : url, local file to execute
// pParameters : {Optional} - can be NULL otherwise a string of args to pass to pFile
// pDirectory : {Optional} - set cwd for process
// type : kProcessWinNormal, kProcessWinMinimized, kProcessWinMaximized, kProcessHidden
//
bool StartProcess(void* pWindow, const char* pOperation, const char* pFile, const char* pParameters, const char* pDirectory, LGSysUtils::eProcessWin type)
{
bool rc = false;
#if defined(PLATFORM_WIN32)
int showCmd;
switch(type)
{
case kProcessWinMaximized:
showCmd = SW_SHOWMAXIMIZED;
break;
case kProcessWinMinimized:
showCmd = SW_SHOWMINIMIZED;
break;
case kProcessHidden:
showCmd = SW_HIDE;
break;
case kProcessWinNormal:
default:
showCmd = SW_NORMAL;
}
int shellRC = (int)ShellExecute(reinterpret_cast<HWND>(pWindow), pOperation,pFile,pParameters,pDirectory,showCmd);
//Returns a value greater than 32 if successful, or an error value that is less than or equal to 32 otherwise.
if( shellRC > 32 )
{
rc = true;
}
#elif defined(PLATFORM_OSX)
char cmd[1024];
sprintf(cmd, "%s %s", pOperation, pFile);
int sysrc = system( cmd );
dbPrintf("sysrc = %d", sysrc);
rc = true;
#endif
return rc;
}
}
[and previously mentioned]
If you are in control of the source code for the application that is launched, you could try adding this to the top of your main.cpp (or whatever you have named it)
// make this process windowless/aka no console window
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
You could also feed those options to the linker directly. The above is easier to play with for different build configurations imho.
my wxWidget Application does not make any std::cout << "xyz" ... on a windows console (Windows XP) when it is startet from a console by e.g.: "call MyApplication.exe". It will produce no output at all. The Application instead rises correctly and works fine. All Buttons and Widgets on the Frame have their functions working.
When I run my application from Eclipse, it produces its outputs as it should be to Eclipse' console.
So, why i can't see any output on windows console? What do i have to activate?
I've always been curious about this, so I followed the links provided in Bo Persson's answer and pieced together some code. To use it, just define a UseConsole object in main.
UseConsole.h:
class UseConsole
{
public:
UseConsole();
~UseConsole();
private:
bool m_good;
};
UseConsole.cpp:
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#include "UseConsole.h"
// The following function is taken nearly verbatim from
// http://www.halcyon.com/~ast/dload/guicon.htm
void RedirectIOToConsole()
{
int hConHandle;
long lStdHandle;
FILE *fp;
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
std::ios::sync_with_stdio();
}
UseConsole::UseConsole()
{
m_good = !!AttachConsole(ATTACH_PARENT_PROCESS);
if (m_good)
RedirectIOToConsole();
}
UseConsole::~UseConsole()
{
if (m_good)
FreeConsole();
}
A windowed application by default doesn't have a console. You can create one if you like to have one anyway.
See the answers to this question:
Visual C++ Enable Console
When running in an IDE, the IDE often does that for you.
If you already have a console window open, you can alternatively attach to the parent process' console using AttachConsole(ATTACH_PARENT_PROCESS).
http://msdn.microsoft.com/en-us/library/ms681952(v=vs.85).aspx
I am building a tool that can be both graphical or purely with a command line interface.
It's up to the user to decide with a command line option "--command_line_only". My IDE is Visual Studio 2008.
I can't seem to find the right project property to make sure
standard output prints are displayed when using the command line interface mode
no command line box is opened when using the tool in its graphical mode
Is there a way to do that ? Visual Studio's devenv seems to behave like this, so i am pretty sure it can be done !
EDIT: I seem to have answered your title, but on re reading your question I am not sure this is what you are asking. I leave the answer here as it might be useful to someone searching your title
Yes you can do this but in general visual studies doesn't make it very easy to separate code from gui (particuly from the hello world examples that are very bound). If you want to mix input then you really want to make sure this is done very well from the beginning.
My advice is to start with the command line options. If you are allowed to use boost (for lisencing reasons) then use boost::program_options.
Then once you have got that going you can add the gui on top. Also, I would recommonend using a gui library such as gtk++ as it is cross platform .
This is not an easy thing to do, IIRC. The problem is that on Windows the executable itself has a flag whether it is a GUI application or console application and e.g. cmd.exe behaves differently when executing one or the other. I suggest that you split the core functionality of your application into a library and build separate CLI and GUI front ends.
EDIT: If you really insist, this goes a long way towards the goal. The goto is there for historical reasons, it could be replaced by the if now:
static
bool
usable_handle (HANDLE h)
{
return h && h != INVALID_HANDLE_VALUE;
}
static
bool
try_reopen_std_handle (int dest_handle, DWORD os_handle_num, HANDLE os_handle,
int flags)
{
if (! usable_handle (os_handle))
return false;
int ret = SetStdHandle (os_handle_num, os_handle);
assert (ret);
if (! ret)
return false;
int base_flags = 0;
#if defined (UNICODE)
//base_flags = _O_WTEXT;
#endif
int opened_handle = _open_osfhandle (reinterpret_cast<intptr_t>(os_handle),
flags | base_flags);
assert (opened_handle != -1 && "_open_osfhandle");
if (opened_handle == -1)
return false;
int dupd_handle = _dup2 (opened_handle, dest_handle);
assert (dupd_handle != -1 && "_dup2");
return dupd_handle == 0;
}
static
bool
try_fdopen (FILE * f, int handle, char const * mode)
{
FILE * tmp = _fdopen (handle, mode);
if (tmp && f)
*f = *tmp;
return !! tmp;
}
static
HANDLE
try_dup_os_handle (HANDLE src)
{
if (! usable_handle (src))
return INVALID_HANDLE_VALUE;
HANDLE dest = INVALID_HANDLE_VALUE;
HANDLE const process = GetCurrentProcess ();
if (DuplicateHandle (process, src, process, &dest, 0, TRUE,
DUPLICATE_SAME_ACCESS))
return dest;
else
return INVALID_HANDLE_VALUE;
}
static
void
init_std_io ()
{
// Retrieve inherited standard handles. AttachConsole() will close
// the existing standard handles, so we duplicate them here first
// to keep them alive.
HANDLE os_stdin = try_dup_os_handle (GetStdHandle (STD_INPUT_HANDLE));
HANDLE os_stdout = try_dup_os_handle (GetStdHandle (STD_OUTPUT_HANDLE));
HANDLE os_stderr = try_dup_os_handle (GetStdHandle (STD_ERROR_HANDLE));
// Attach existing console or allocate a new one.
int ret = AttachConsole (ATTACH_PARENT_PROCESS);
if (ret)
OutputDebugString (_T("Attached existing console.\n"));
else
{
ret = AllocConsole ();
if (ret)
OutputDebugString (_T("Allocated new console.\n"));
else
OutputDebugString (_T("Failed to allocate new console.\n"));
assert (ret);
}
// Open a "POSIX" handle for each OS handle and then fdopen() a C stream
// for each such "POSIX" handle.
//
// Only use the standard handle provided by AttachConsole() if the standard
// handle from before AttachConsole() is not usable.
//
// Finally, re-open standard C stream.
if (! usable_handle (os_stdin))
os_stdin = GetStdHandle (STD_INPUT_HANDLE);
ret = try_reopen_std_handle (0, STD_INPUT_HANDLE, os_stdin, _O_RDONLY);
if (! ret)
goto do_stdout;
try_fdopen (stdin, 0, "r");
do_stdout:
if (! usable_handle (os_stdout))
os_stdout = GetStdHandle (STD_OUTPUT_HANDLE);
ret = try_reopen_std_handle (1, STD_OUTPUT_HANDLE, os_stdout, _O_WRONLY);
if (! ret)
goto do_stderr;
try_fdopen (stdout, 1, "w");
do_stderr:
if (! usable_handle (os_stderr))
os_stderr = GetStdHandle (STD_ERROR_HANDLE);
ret = try_reopen_std_handle (2, STD_ERROR_HANDLE, os_stderr, _O_WRONLY);
if (! ret)
goto done_stderr;
try_fdopen (stderr, 2, "w");
done_stderr:;
}
Build the application as a Win32 application (not a console application), and examine the parameters to decide whether or not to use the console window.
The following code is based on this.
To use a console; create a class called CConsoleAttacher. Use it as follows, basically if there are arguments then open a console which will connect to the CMD window if you started from that. Obviously with Win32 applications when you launch the main windows it detaches from the console so this needs to be handled early on before creating app windows (which is what you want to do anyway...)
CConsoleAttacher ca;
if (ca.hasArguments())
{
ca.ConnectToConsole();
}
printf ("Test output \n");
Create a class called CConsoleAttacher.
CConsoleAttacher.cpp
#include "StdAfx.h"
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>
#include "ConsoleAttacher.h"
#ifndef _USE_OLD_IOSTREAMS
using namespace std;
#endif
static const WORD MAX_CONSOLE_LINES = 500;
CConsoleAttacher::CConsoleAttacher(void)
{
argv = CommandLineToArgvW(GetCommandLineW(), &argc);
}
CConsoleAttacher::~CConsoleAttacher(void)
{
LocalFree(argv);
}
int CConsoleAttacher::getArgumentCount(void)
{
return argc;
}
CString CConsoleAttacher::getArgument(int id)
{
CString arg ;
if (id < argc)
{
arg = argv[id];
}
return arg;
}
bool CConsoleAttacher::hasArguments(void)
{
return argc > 1;
}
void CConsoleAttacher::ConnectToConsole(void)
{
int hConHandle;
HANDLE lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// allocate a console for this app
if (!AttachConsole(ATTACH_PARENT_PROCESS))
{
if (!AllocConsole())
return;
}
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),&coninfo);
coninfo.dwSize.Y = MAX_CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),coninfo.dwSize);
// redirect unbuffered STDOUT to the console
lStdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle((intptr_t)lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
ios::sync_with_stdio();
}
CConsoleAttacher.h
#pragma once
class CConsoleAttacher
{
private:
int argc;
wchar_t** argv;
public:
CConsoleAttacher(void);
~CConsoleAttacher(void);
int getArgumentCount(void);
CString CConsoleAttacher::getArgument(int id);
void ConnectToConsole(void);
bool hasArguments(void);
};