Windows Applications that Have Access To Console Features


Click here for larger image


I always wanted to use cout, cin, cerr, printf, etc. in windows application if  I started it from command line. There was an article (, contributed Richard Eperjesi) about how the MSDEV can work in console mode (MSDEV /?) and in windows mode (MSDEV). That's a very great idea, and here is another tricky way.


Crete your MFC windows project and add the ConsoleWindowsApp.cpp or this source code to your project, and 
  • Do Define _CONSOLEWIN in your project settings, if you want your project to work like a console and windows application. The standard output, and input will be redirected to the parent console. You can use cout, cerr, cin, printf, etc.
  • Do not define _CONSOLEWIN in your project settings, and you will get a windows application. (Default)

Source code


//Set subsystem to console, just overwrites the default windows subsystem
#pragma comment ( linker, "/subsystem:console" )

BOOL WINAPI ConsoleWinHandlerRoutine( DWORD dwCtrlType )
    // Signal type
    switch( dwCtrlType )
    case CTRL_C_EVENT:
    // You can stop here gracefully:
    // AfxGetMainWnd()->SendMessage( WM_CLOSE, 0, 0 );
    // WaitForSingleObject( AfxGetThread(), INFINITE );

return TRUE;

// Console main function, this code is from WinMainCRTStartup()
int _tmain( DWORD, TCHAR**, TCHAR** )
#define SPACECHAR _T(' ')
#define DQUOTECHAR _T('\"')

    // Set the new handler
    SetConsoleCtrlHandler( ConsoleWinHandlerRoutine, TRUE );

    // Get command line
    LPTSTR lpszCommandLine = ::GetCommandLine();

    if(lpszCommandLine == NULL)
        return -1;

    // Skip past program name (first token in command line).
    // Check for and handle quoted program name.
    if(*lpszCommandLine == DQUOTECHAR)
        // Scan, and skip over, subsequent characters until
        // another double-quote or a null is encountered.
            lpszCommandLine = ::CharNext(lpszCommandLine);
        } while((*lpszCommandLine != DQUOTECHAR) && (*lpszCommandLine != _T('\0')));

        // If we stopped on a double-quote (usual case), skip over it.
        if(*lpszCommandLine == DQUOTECHAR)
            lpszCommandLine = ::CharNext(lpszCommandLine);
        while(*lpszCommandLine > SPACECHAR)
            lpszCommandLine = ::CharNext(lpszCommandLine);

    // Skip past any white space preceeding the second token.
    while(*lpszCommandLine && (*lpszCommandLine <= SPACECHAR))
        lpszCommandLine = ::CharNext(lpszCommandLine);

    STARTUPINFO StartupInfo;
    StartupInfo.dwFlags = 0;


    // Your original windows application will be started
    return _tWinMain(::GetModuleHandle(NULL), NULL, lpszCommandLine,
                (StartupInfo.dwFlags & STARTF_USESHOWWINDOW) ?
          StartupInfo.wShowWindow : SW_SHOWDEFAULT);


Download source code - 2 Kb