Files
kwa.fr/sdi_toolBox_1.0.x/toolBox/sdi_toolBox/console/msw/win32Console.h
2026-03-12 16:31:18 +01:00

125 lines
3.5 KiB
C++

/*
{{copyright}}
*/
/*
{{version}}
*/
/*
{{license}}
*/
#pragma once
#ifdef _WIN32
# include <Windows.h>
#endif // defined WIN32
#include <iostream>
#include <memory>
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<Win32Console> 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<Win32Console>(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