Thursday, November 6, 2008

Console Output from a GUI APP



I recently needed the functionality to enable text output to the console (if run from a command line) for a non-console (standard GUI) application. Sounds easy, right?

Standard text output (e.g. cout, printf) are redirected to the bit-bucket in the sky for a GUI application, so those don't work in this case(1).

According to the API documentation, AttachConsole(ATTACH_PARENT_PROCESS) should do what I needed, but it has its quirks, namely that the output gets dumped to the console at the current caret position which leads to something like (presuming my intended output is "Hello, world!":

C:\Source\TestApp>test.exe -console

C:\Source\TestApp>Hello, World!
_

Not exactly the formatting that is wanted. Even though the text is output after the prompt, it isn't considered part of the input, i.e., hitting return ignores the line and displays the prompt.

Anyway, I want the text to be on its own line, just like you'd expect from a standard console application. After much fiddling, I found the following seems to work most(2) of the time:

AllocConsole(ATTACH_PARENT_PROCESS);
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsole(hConsole, szOutput, lstrlen(szOutput), NULL, NULL);
// etc.
FlushFileBuffers(hConsole);
FreeConsole();

With the above, I get the expected output:

C:\Source\TestApp>test.exe -console
Hello, World!
C:\Source\TestApp>_


Notes:
1) There are ways to initialize the CRT output handles using the the handle retrieved from GetStdHandle() if you want to use printf, cout, etc. Search the net for various implementations.
2) I've found that this method works most of the time. Occasionally, the text is still output in the old screwy format for unknown reasons. In this case, it was good enough for government work.

No comments: