/* {{copyright}} */ /* {{version}} */ /* {{license}} */ #pragma once #ifdef _WIN32 # include #endif // defined WIN32 #include #include namespace sdi_toolBox::logs { //-------------------------------------------------------------- class Win32Console { public: static void initConsole(); // Init application console and attach debug console under MSW static void releaseConsole(); // Release application console public: virtual ~Win32Console(); // Default destructor Win32Console(const Win32Console &obj) = delete; // Copy constructor Win32Console(Win32Console &&obj) noexcept = delete; // Move constructor Win32Console &operator=(const Win32Console &obj) = delete; // Copy assignment operator Win32Console &operator=(Win32Console &&obj) noexcept = delete; // Move assignment operator static bool hasAttachedConsole(); // Returns true if console is attached, false otherwise protected: static inline std::unique_ptr m_singleton; Win32Console(); // Default constructor FILE *m_stdoutFile; // Reopened stdout file pointer FILE *m_stderrFile; // Reopened stderr file pointer }; //-------------------------------------------------------------- /* Init application console and attach debug console under MSW */ inline void Win32Console::initConsole() { #ifndef _WIN32 # error This calss is only available under Windows systems #endif if (!m_singleton) m_singleton = std::unique_ptr(new Win32Console()); } //-------------------------------------------------------------- /* Release application console */ inline void Win32Console::releaseConsole() { if (m_singleton) m_singleton.reset(); } //-------------------------------------------------------------- /* Default constructor */ inline Win32Console::Win32Console() { #ifdef _WIN32 bool consoleIsCreated = false; // Try to attach application to the current console AttachConsole(ATTACH_PARENT_PROCESS); if (!GetConsoleWindow()) // No console was available { // Create console and attach application to it if (!AllocConsole()) throw std::logic_error("Unable to attach application to debug console"); // Error during creating console consoleIsCreated = true; } // Reopen stdout and stderr streams to console window if (freopen_s(&m_stdoutFile, "CONOUT$", "w", stdout) != 0) throw std::logic_error("Unable to reopen stdout"); // Error during reopen on stdout if (freopen_s(&m_stderrFile, "CONOUT$", "w", stderr) != 0) throw std::logic_error("Unable to reopen stderr"); // Error during reopen on stderr std::cout.clear(); std::cerr.clear(); if (!consoleIsCreated) std::cout << std::endl; // Add a new line if console was already existing #endif } //-------------------------------------------------------------- /* Default destructor */ inline Win32Console::~Win32Console() { #ifdef _WIN32 std::cout.clear(); std::cerr.clear(); // Free console FreeConsole(); // Close reopened stdout and stderr streams (void)fclose(m_stdoutFile); (void)fclose(m_stderrFile); #endif } //-------------------------------------------------------------- /* Returns true if console is attached, false otherwise */ inline bool Win32Console::hasAttachedConsole() { #ifdef _WIN32 if (GetConsoleWindow()) return true; #endif return false; } //-------------------------------------------------------------- } // namespace sdi_toolBox::logs