Code:
#include <windows.h>
#include <windowsx.h>
#include <iostream>
#include <streambuf>
class winoutbuf: public std::streambuf
{
public:
winoutbuf(int startX, int y):m_startX(startX),m_X(startX),m_Y(y),m_hwnd(0){}
void SetHandle(HWND hwnd) { m_hwnd = hwnd; }
private:
int m_startX,m_X,m_Y;
HWND m_hwnd;
protected:
virtual int_type overflow(int_type c)
{
//single char output
if (c != EOF)
{
HDC hdc = GetDC(m_hwnd);
char z = c;
if (z=='\n')
{
m_X = m_startX; //reset position
return c;
}
SIZE size;
if(!GetTextExtentPoint32(hdc,&z,1,&size)) //get text width
return EOF;
if (!TextOut(hdc,m_X, m_Y, &z, 1))
return EOF;
m_X+=size.cx; //update position based on width of char
ReleaseDC(m_hwnd,hdc);
}
return c;
}
virtual std::streamsize xsputn(const char* s, std::streamsize num)
{
/*
Do outputting for more than one char
*/
return num;
}
};
class winostream: public std::ostream
{
protected:
winoutbuf buf;
public:
winostream():buf(10,10), std::ostream(&buf) {}
void SetHandle(HWND hwnd) { buf.SetHandle(hwnd); }
};
winostream g_out;
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
WNDCLASS wc;
MSG msg;
wc.style = CS_VREDRAW | CS_HREDRAW;
wc.lpfnWndProc = MainWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH) (COLOR_SCROLLBAR + 1);
wc.lpszMenuName = 0;
wc.lpszClassName = "WinClassName";
if (!RegisterClass (&wc))
return 0;
HWND hwnd;
hwnd = CreateWindow ("WinClassName",
"Redirect cout",
WS_OVERLAPPEDWINDOW|WS_VISIBLE,
20,20,400,400,
NULL,NULL,hInstance,NULL);
g_out.SetHandle(hwnd);
if (!hwnd)
return 0;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg);
DispatchMessage (&msg);
}
return 0;
}
LRESULT CALLBACK MainWindowProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
std::cout.rdbuf(g_out.rdbuf()); //redirect cout to custom stream
break;
case WM_MOUSEMOVE:
{
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
std::cout<<'('<<x<<','<<y<<')'<<'\n';
}
break;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
Not a perfect example, but you get the idea