Pelles C forum

C language => Beginner questions => Topic started by: golite on October 05, 2013, 06:48:25 AM

Title: Closing console window
Post by: golite on October 05, 2013, 06:48:25 AM
I have a console window that starts up and runs with my Windows app.
I currently have to close the windows app and then close the console also.
Is there a way to close the console window through the WM_CLOSE command?

I am interested in learning how Pelles makes the console stay active. I used to have to cause the console to stay open by using some kind of read or get command.
Title: Re: Closing console window
Post by: jj2007 on October 05, 2013, 08:30:02 AM
If I build a standard GUI app (subsystem windows) and insert
   AllocConsole();
somewhere at the beginning of main(), the console window closes when I close the GUI window.

How do you get the console window?
Title: Re: Closing console window
Post by: TimoVJL on October 05, 2013, 09:13:41 AM
Quote from: golite on October 05, 2013, 06:48:25 AM
I have a console window that starts up and runs with my Windows app.
I currently have to close the windows app and then close the console also.
Is there a way to close the console window through the WM_CLOSE command?

I am interested in learning how Pelles makes the console stay active. I used to have to cause the console to stay open by using some kind of read or get command.
This happens only in PellesC IDE ?, (IDE feature to commandline programs)

Quote from: jj2007 on October 05, 2013, 08:30:02 AM
How do you get the console window?
Just use this in GUI program (UNICODE)...
#pragma comment(linker, "-subsystem:console")
#pragma comment(linker, "-entry:wWinMainCRTStartup")
...
Title: Re: Closing console window
Post by: jj2007 on October 05, 2013, 10:02:55 AM
Quote from: timovjl on October 05, 2013, 09:13:41 AM
Just use this in GUI program (UNICODE)...
#pragma comment(linker, "-subsystem:console")
#pragma comment(linker, "-entry:wWinMainCRTStartup")
...

Yes, this works fine, but it produces the behaviour the OP didn't want, i.e. the console remains open until you press a key. AllocConsole behaves better in this respect, but of course, you need an alternative to printf:
   AllocConsole();
   WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), "Hello", 5, 0, 0);
Title: Re: Closing console window
Post by: golite on October 06, 2013, 03:41:52 AM
I now have removed the pragma statements and I only need the AllocConsole() and the WriteConsole() to achieve my intentions. This does the trick well.

Thanks Again.
Title: Re: Closing console window
Post by: TimoVJL on October 06, 2013, 09:27:43 AM
In that way you loose that log in new console.
Simple TRACE macro:
#ifndef NDEBUG
//#define TRACE(x) OutputDebugString(x)
#define TRACE(x) WriteStdOut((x))
void __cdecl WriteStdOut(TCHAR *szTxt)
{
static HANDLE hStdOut = 0;
if (!hStdOut) {
AllocConsole();
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
}
WriteConsole(hStdOut, szTxt, lstrlen(szTxt), 0, 0);
}
#else
#define TRACE(x)
#endif
Usage:TRACE("My TRACE comment\n");
Title: Re: Closing console window
Post by: czerny on April 14, 2014, 11:55:17 AM
This is an example I have found on the net. printf() is working.

Only problem I see so far is scanf(). It looses the first character of the input. 123 gives 23. 'Test' gives 'est'.
Title: Re: Closing console window
Post by: frankie on April 14, 2014, 01:12:42 PM
Add a flush of stdin:

// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT | _O_RDONLY);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
fflush(stdin); //Add Flush
Title: Re: Closing console window
Post by: czerny on April 14, 2014, 03:10:13 PM
Thanks!
Title: Re: Closing console window
Post by: aardvajk on April 14, 2014, 08:39:35 PM
You don't need 6 lines to redirect a stream, 3 will do them all, without having to employ the undefined behaviour of fflush(stdin)

freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
Title: Re: Closing console window
Post by: frankie on April 15, 2014, 11:05:12 AM
Quote from: aardvajk on April 14, 2014, 08:39:35 PM
You don't need 6 lines to redirect a stream, 3 will do them all, without having to employ the undefined behaviour of fflush(stdin)
Yes you're right :), for std-C the statement has an undefined behaviour. But in WINNT it is an extension to the standard.
From MS here (http://msdn.microsoft.com/en-us/library/9yky46tz.aspx)

   // You must flush the input buffer before using gets.
   // fflush on input stream is an extension to the C standard


Quote from: aardvajk on April 14, 2014, 08:39:35 PM

freopen("CONIN$", "r", stdin);
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);

This doesn't work.
freopen works when stdin, stdout and stderr already  refers to valid opened streams, that is true when you start a console program, but fails when allocating a console in a GUI subsystem.
When you allocate a console from a GUI program the standard streams don't point to valid files while the allocated console have opened its own streams.
The long code scope is then to collect the actual OS file handle and associate it to C-runtime streams stdin, stdout, stderr.
This tecnique is MS original as showed here (http://support.microsoft.com/kb/105305/en-us)