简体   繁体   中英

stdout output doesn't display on console in Windows MFC dialog-based app

What I'm trying to do

I'm using Visual Studio to write a simple dialog based program. It performs its primary function as it should. Then I added support for running the app from a command prompt. It still works well when I invoke the program from a command line prompt, but any messages written to stdout or stderr are simply not displayed.

What I've tried

I've tried multiple variations of _tprintf() , _ftprintf(stdout, etc) and so on. No matter what, I don't get any output on the console.

How it decides whether to display the dialog

When the command line contains at least two arguments, the program bypasses the dialog and goes straight for executing the program's primary logic, which is embodied in the Go(arg1, arg2) function. When the command line doesn't have enough arguments, the dialog is used instead.

My Code

This is a very trimmed-down example. Much of what is left was generated by Visual Studio, and I've just added a few lines of my own code. This example won't actually compile, as there are unresolved external references.

BOOL CCNCSplineApp::InitInstance()
{
    // InitCommonControlsEx() is required on Windows XP if an application
    // manifest specifies use of ComCtl32.dll version 6 or later to enable
    // visual styles.  Otherwise, any window creation will fail.
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // Set this to include all the common control classes you want to use
    // in your application.
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);
    std::time_t* p_clock = &time_now;

    CWinApp::InitInstance();
    AfxEnableControlContainer();

    // Create the shell manager, in case the dialog contains
    // any shell tree view or shell list view controls.
    CShellManager *pShellManager = new CShellManager;

    // Standard initialization
    SetRegistryKey(_T("MyCompany"));

    LPCTSTR cmdline = ::GetCommandLineW();
    int argc;
    LPWSTR* argv = ::CommandLineToArgvW(cmdline, &argc);
    if (2 < argc)
    {
        FILE*tgt = _tfopen(argv[2], _T("w"));
        if (0 == tgt)
        {
            _tprintf(L"Unable to open output file \"%s\"\n", argv[2]);
            exit(-1);
        }
        CString inputFileName = argv[1];
        Go(inputFileName, tgt);
        CString status = StatusText();
        if (status.GetLength() > 0)
        {
            _tprintf(_T("%s\n"), (LPCTSTR)status);
        }
        return FALSE;
    }

    MyDialog dlg;
    m_pMainWnd = &dlg;
    dlg.DoModal();

    // Delete the shell manager created above.
    if (pShellManager != NULL)
    {
        delete pShellManager;
    }

    // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application'time_doa message pump.
    return FALSE;
}

The Question

What do I need to change in this code to get the various _tprintf() calls to display text on the console?

Insert this code somewhere in InitInstance() , after that printf() , std::cout etc. should work:

if( AttachConsole( ATTACH_PARENT_PROCESS ) )
{
    freopen( "CONIN$",  "rb", stdin );   // reopen stdin handle as console window input
    freopen( "CONOUT$", "wb", stdout );  // reopen stdout handle as console window output
    freopen( "CONOUT$", "wb", stderr );  // reopen stderr handle as console window output
}

You might also want to call _setmode(_fileno(stdout), _O_U16TEXT) (same for stderr ) to enable Unicode output to the console .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM