From 79faa46da0b8da1d346a2eaf34a07889312021a5 Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 1 Sep 2015 20:05:38 +0200 Subject: [PATCH] added method to activate stdout/stderr for GUI app on Windows --- application/argumentparser.cpp | 6 ++++- application/commandlineutils.cpp | 44 +++++++++++++++++++++++++++++++- application/commandlineutils.h | 7 +++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/application/argumentparser.cpp b/application/argumentparser.cpp index 8776a90..222ffe6 100644 --- a/application/argumentparser.cpp +++ b/application/argumentparser.cpp @@ -1,4 +1,5 @@ #include "argumentparser.h" +#include "commandlineutils.h" #include "failure.h" #include "../conversion/stringconversion.h" @@ -652,7 +653,10 @@ void ArgumentParser::parseArgs(int argc, char *argv[]) HelpArgument::HelpArgument(ArgumentParser &parser) : Argument("help", "h", "shows this information") { - setCallback([&parser] (const StringVector &) {parser.printHelp(cout);}); + setCallback([&parser] (const StringVector &) { + CMD_UTILS_START_CONSOLE; + parser.printHelp(cout); + }); } } diff --git a/application/commandlineutils.cpp b/application/commandlineutils.cpp index c883778..dbcd0f9 100644 --- a/application/commandlineutils.cpp +++ b/application/commandlineutils.cpp @@ -3,10 +3,18 @@ #include #include +#ifdef PLATFORM_WINDOWS +#include +#include +#endif + using namespace std; namespace ApplicationUtilities { +/*! + * \brief Prompts for confirmation displaying the specified \a message. + */ bool confirmPrompt(const char *message, Response defaultResponse) { cout << message; @@ -28,5 +36,39 @@ bool confirmPrompt(const char *message, Response defaultResponse) } } -} // namespace ApplicationUtilities +/*! + * \brief Starts the console. + * \remarks This method is only available on Windows and used to start + * a console from a GUI application. + */ +void startConsole() +{ + AttachConsole(ATTACH_PARENT_PROCESS); + CONSOLE_SCREEN_BUFFER_INFO coninfo; + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); + coninfo.dwSize.X = 200; + coninfo.dwSize.Y = 500; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); + // redirect stdout + auto stdHandle = reinterpret_cast(GetStdHandle(STD_OUTPUT_HANDLE)); + auto conHandle = _open_osfhandle(stdHandle, _O_TEXT); + auto fp = _fdopen(conHandle, "w"); + *stdout = *fp; + setvbuf(stdout, NULL, _IONBF, 0); + // redirect stdin + stdHandle = reinterpret_cast(GetStdHandle(STD_INPUT_HANDLE)); + conHandle = _open_osfhandle(stdHandle, _O_TEXT); + fp = _fdopen(conHandle, "r"); + *stdin = *fp; + setvbuf(stdin, NULL, _IONBF, 0); + // redirect stderr + stdHandle = reinterpret_cast(GetStdHandle(STD_ERROR_HANDLE)); + conHandle = _open_osfhandle(stdHandle, _O_TEXT); + fp = _fdopen(conHandle, "w"); + *stderr = *fp; + setvbuf(stderr, NULL, _IONBF, 0); + // sync + ios::sync_with_stdio(true); +} +} // namespace ApplicationUtilities diff --git a/application/commandlineutils.h b/application/commandlineutils.h index ec23009..71b50c5 100644 --- a/application/commandlineutils.h +++ b/application/commandlineutils.h @@ -14,6 +14,13 @@ enum class Response bool LIB_EXPORT confirmPrompt(const char *message, Response defaultResponse = Response::None); +#ifdef PLATFORM_WINDOWS +void LIB_EXPORT startConsole(); +#define CMD_UTILS_START_CONSOLE ::ApplicationUtilities::startConsole(); +#else +#define CMD_UTILS_START_CONSOLE +#endif + } // namespace ApplicationUtilities #endif // APPLICATIONUTILITIES_COMMANDLINEUTILS_H