Based on the accepted answer from ProXicT link with a few modifications. The following code works for std::cout. The other methods won't work on 64bit with Visual Studio 2015:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <Windows.h>
// For debugging
#include <io.h>
#include <fcntl.h>
#define UNUSED(x) (void)(x) // Unused param (C compatible - not applicable to expressions)
class outbuf : public std::streambuf {
public:
outbuf() {
setp(0, 0);
}
virtual int_type overflow(int_type c = traits_type::eof()) {
return fputc(c, stdout) == EOF ? traits_type::eof() : c;
}
};
int CALLBACK
WinMain (HINSTANCE hInstance,
HINSTANCE /*hPrevInst*/, // Unused param (C++ only)
LPSTR lpCmdLine,
int (nShowCmd))
{
UNUSED(hInstance);
// UNUSED(hPrevInst);
UNUSED(lpCmdLine);
UNUSED(nShowCmd); // This param is used
// create the console
if (AllocConsole()) {
FILE* pCout;
freopen_s(&pCout, "CONOUT$", "w", stdout);
SetConsoleTitle(L"Debug Console");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
}
// set std::cout to use my custom streambuf
outbuf ob;
std::streambuf *sb = std::cout.rdbuf(&ob);
// do some work here
printf("Hello!\n");
std::cout << "nShowCmd = " << nShowCmd << std::endl;
std::cout << "Now making my first Windows window!" << std::endl;
// make sure to restore the original so we don't get a crash on close!
std::cout.rdbuf(sb);
MessageBoxW (NULL,
L"Hello World!",
L"hello",
MB_OK | MB_ICONINFORMATION);
return 0;
}
EDIT:
The same stuff as above but with colors for completeness:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <Windows.h>
// For debugging
#include <io.h>
#include <fcntl.h>
#define UNUSED(x) (void)(x) // Unused param (C compatible - not applicable to expressions)
class outbuf : public std::streambuf {
public:
outbuf() {
setp(0, 0);
}
virtual int_type overflow(int_type c = traits_type::eof()) {
return fputc(c, stdout) == EOF ? traits_type::eof() : c;
}
};
int CALLBACK
WinMain (HINSTANCE hInstance,
HINSTANCE /*hPrevInst*/, // Unused param (C++ only)
LPSTR lpCmdLine,
int (nShowCmd))
{
UNUSED(hInstance);
// UNUSED(hPrevInst);
UNUSED(lpCmdLine);
UNUSED(nShowCmd); // This param is used
// create the console
if (AllocConsole()) {
FILE* pCout;
freopen_s(&pCout, "CONOUT$", "w", stdout);
SetConsoleTitle(L"Debug Console");
}
// set std::cout to use my custom streambuf
outbuf ob;
std::streambuf *sb = std::cout.rdbuf(&ob);
// do some work here
printf("Hello!\n");
HANDLE stdHandle = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
WORD defaultConsoleTextAttributes;
GetConsoleScreenBufferInfo(stdHandle, &consoleInfo);
defaultConsoleTextAttributes = consoleInfo.wAttributes;
WORD currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "nShowCmd = " << nShowCmd << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_BLUE;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_BLUE | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_RED;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_RED | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_BLUE;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_RED;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_BLUE | FOREGROUND_RED;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
currentConsoleTextAttributes = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY;
SetConsoleTextAttribute(stdHandle, currentConsoleTextAttributes);
std::cout << "Now making my first Windows window!" << std::endl;
// make sure to restore the original so we don't get a crash on close!
std::cout.rdbuf(sb);
Sleep(5000);
ShowWindow(GetConsoleWindow(), SW_HIDE);
FreeConsole();
MessageBoxW (NULL,
L"Hello World!",
L"hello",
MB_OK | MB_ICONINFORMATION);
return 0;
}
All that remains now is to make it into a complete logging class.