( Index )
Month

Brief Information about the April '02 CSIG Meeting

GuiCon - A Win32 App calling a Console Debug Window

C Plus Plus

This month I will discuss a article that appeared in the Windows Developer's Journal, December 1997. It's written by Andrew Tucker and provides and interesting tool for debuging code.

Windows Developer's Journal

Adding Console I/O to a Win32 GUI App

Andrew Tucker

Many programmers don't know that a Win32 console application can call all the same functions (CreateWindow(), MessageBox(), etc.) as a GUI Win32 application. Conversely, a GUI Win32 application can create a console window and read and write to it – a handy feature if you ever need a line-oriented debugging window. This article shows how to add a console window to your GUI application on the fly, and redirect standard I/O to use that window.

One of the common misconceptions surrounding Win32 programming is that you must decide early in the design process whether your application will be a console or GUI application. In reality, console applications can create windows and have a message loop just like a GUI application (see "Adding Graphics to Console Applications" by Michael Covington, Visual Developer, June/July 1997). Alternatively, graphical applications can create and use a console. Although Win32 provides functions for communicating with a console, they are a little clumsy to use and require parameters that are unnecessary for simple text I/O. This article shows how to use standard C/C++ I/O with consoles, and how to work around specific problems in the Visual C++ I/O library.

Sample Code

void RedirectIOToConsole()
{
    int                        hConHandle;
    long                       lStdHandle;
    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 = MAX_CONSOLE_LINES;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), 
                               coninfo.dwSize);

    // 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
    ios::sync_with_stdio();
}


"Random Access" questions start at 7:30 Tuesday night.

SOURCE CODE

Source Code Files

For help, email me at b a r n o l d @ i e e e . o r g
Back to C++ Main Page