From: Vadim Zeitlin on
On Wed, 16 Apr 2008 11:16:31 +0200 Fabian Cenedese <Cenedese(a)indel.ch> wrote:

FC> I haven't tried this code, but when I once tried to create such an app
FC> I was told that it's not possible on windows because the linker decides
FC> the type of application with /SUBSYSTEM:WINDOWS or CONSOLE.
FC>
FC> So how would this hybrid app now be created? Would it still have a
FC> console attached even when using a GUI?

Good question, I forgot about this issue to be honest. There is indeed a
problem with this under MSW because console applications always have a
console and while it can be explicitly destroyed with FreeConsole() it is
still visible on startup. And while Windows applications can be run from
the console, they don't have any console of their own. I thought that doing
::AttachConsole(ATTACH_PARENT_PROCESS) could help here but this function
fails for me (Windows 2003) with "invalid handle" error and, anyhow, it's
XP and later only. And in fact even allocating a new console doesn't work
(the console does appear but printf() still does nothing).

So it unfortunately seems that the usefulness of this method under Windows
is indeed limited to console applications which sometimes need to show GUI.

Regards,
VZ

--
TT-Solutions: wxWidgets consultancy and technical support
http://www.tt-solutions.com/

From: Thibault Genessay on
Hi Guys

> ::AttachConsole(ATTACH_PARENT_PROCESS) could help here but this function
> fails for me (Windows 2003) with "invalid handle" error and, anyhow, it's
> XP and later only. And in fact even allocating a new console doesn't work
> (the console does appear but printf() still does nothing).
>
> So it unfortunately seems that the usefulness of this method under Windows
> is indeed limited to console applications which sometimes need to show GUI.

Attached is a bunch of code that creates a console for a process that
was linked with the /SUBSYSTEM:WINDOWS. I use it on Win XP and it
works as expected. Not so broken, after all.

Regards

Thibault


void allocateConsole()
{
int hConHandle;

HANDLE stdHandle;

CONSOLE_SCREEN_BUFFER_INFO coninfo;

FILE *fp;

// allocate a console for this app
AllocConsole();

// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE),
&coninfo);
coninfo.dwSize.Y = 300;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
coninfo.dwSize);


// redirect unbuffered STDOUT to the console
stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );


// redirect unbuffered STDIN to the console
stdHandle = GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle((intptr_t)stdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );

// redirect unbuffered STDERR to the console
stdHandle = GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle((intptr_t)stdHandle, _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();
}