[Qt-interest] stdout of MSWin GUI application run from console

Graeme Gill graeme2 at argyllcms.com
Thu Apr 14 04:35:20 CEST 2011


For those interested, here's the current state of this code as an
add-on to main(). Probably better to create a library function
in the long term if you want to use this approach.

Also attached is a patch for Qt 4.7.2 to fix this behaviour in Qt itself,
so that no extra application code is needed, and there is then better similarity
of cross platform behaviour.

Graeme Gill.

-------------------------------------------------------------------
#include <QApplication>
#include <stdio.h>
#include "tdialog.hpp"

#ifdef Q_WS_WIN
#include <windows.h>

void winConsoleMsgHandler(QtMsgType t, const char* str) {
         fprintf(stderr, "%s\n", str);
         fflush(stderr);
}
#endif // Q_WS_WIN

int main(int argc, char *argv[]) {

#ifdef Q_WS_WIN
     {
         BOOL (WINAPI *AttachConsole)(DWORD dwProcessId);

         AttachConsole = (BOOL (WINAPI*)(DWORD))
             GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole");

             if (AttachConsole != NULL && AttachConsole(((DWORD)-1))) {
                 if (_fileno(stdout) == -1)
                     freopen("CONOUT$","wb",stdout);
                 if (_fileno(stderr) == -1)
                     freopen("CONOUT$","wb",stderr);
                 if (_fileno(stdin) == -1)
                     freopen("CONIN$","rb",stdin);

                 // Fix C++
                 std::ios::sync_with_stdio();

                 // Fix messages
                 qInstallMsgHandler(winConsoleMsgHandler);
             }
     }
#endif // Q_WS_WIN

     printf("This is stdout\n");
     fprintf(stderr,"This is stderr\n");
     qDebug("This is a qDebug message");

     QApplication app(argc, argv);
     TDialog *dialog = new TDialog;
     dialog->show();

     qDebug("This is another qDebug message");

     return app.exec();
}

-------------------------------------------------------------------
*** src/corelib/kernel/qcoreapplication_win.cpp Thu Apr 14 11:17:48 2011
--- src/corelib/kernel/qcoreapplication_win.cpp Thu Apr 14 12:14:09 2011
*************** void qWinMain(HINSTANCE instance, HINSTA
*** 181,191 ****
           qWarning("Qt: Internal error: qWinMain should be called only once");
           return;
       }
       already_called = true;
-     usingWinMain = true;

!     // Install default debug handler
!     qInstallMsgHandler(qWinMsgHandler);

       // Create command line
       argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc);
--- 181,214 ----
           qWarning("Qt: Internal error: qWinMain should be called only once");
           return;
       }
+
       already_called = true;

! #ifdef Q_WS_WIN
!   // Re-attach stdio if application was started from a console
!   BOOL (WINAPI *pAttachConsole)(DWORD dwProcessId);
!
!   pAttachConsole = (BOOL (WINAPI*)(DWORD))
!       GetProcAddress(LoadLibraryA("kernel32.dll"), "AttachConsole");
!
!   if (pAttachConsole != NULL && pAttachConsole(((DWORD)-1))) {
!       if (_fileno(stdout) == -1)
!           freopen("CONOUT$","wb",stdout);
!       if (_fileno(stderr) == -1)
!           freopen("CONOUT$","wb",stderr);
!       if (_fileno(stdin) == -1)
!           freopen("CONIN$","rb",stdin);
!
!       // Fix C++
!       std::ios::sync_with_stdio();
!   } else
! #endif // Q_WS_WIN
!   {
!       usingWinMain = true;    // Reset to qWinMsgHandler on qInstallMsgHandler(0)
!
!       // Install default debug handler
!       qInstallMsgHandler(qWinMsgHandler);
!   }

       // Create command line
       argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc);



More information about the Qt-interest-old mailing list