2013-11-06 22:52:00 +01:00
|
|
|
#include "WindowShell.h"
|
|
|
|
#include <vector>
|
2013-12-12 09:33:59 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <io.h>
|
|
|
|
#include <fcntl.h>
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
|
|
|
|
|
|
#pragma region Declarations
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
#define WINDOW_SHELL_CLASS_NAME L"MainWindowShellClassName"
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
struct _PrivateDataContainer
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
|
|
|
HINSTANCE hIns;
|
|
|
|
HWND hWnd;
|
2013-12-12 09:33:59 +01:00
|
|
|
HWND parent;
|
|
|
|
bool consoleWindow;
|
|
|
|
WNDPROC callback;
|
|
|
|
const wchar_t* windowClassName;
|
|
|
|
_PrivateDataContainer()
|
|
|
|
: hIns(0)
|
|
|
|
, hWnd(0)
|
|
|
|
, parent(0)
|
|
|
|
, consoleWindow(0)
|
|
|
|
{ }
|
|
|
|
~_PrivateDataContainer() { if(this->consoleWindow) FreeConsole(); }
|
|
|
|
|
|
|
|
} __windowShellData;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
|
|
#pragma endregion
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
LRESULT CALLBACK DefaultWindowCallback(HWND h, UINT m, WPARAM w, LPARAM l)
|
|
|
|
{
|
|
|
|
PAINTSTRUCT ps;
|
|
|
|
HDC hdc;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
switch (m)
|
|
|
|
{
|
|
|
|
case WM_PAINT:
|
|
|
|
hdc = BeginPaint(h, &ps);
|
|
|
|
EndPaint(h, &ps);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_DESTROY:
|
|
|
|
PostQuitMessage(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WM_KEYDOWN:
|
|
|
|
switch(w)
|
|
|
|
{
|
|
|
|
case VK_ESCAPE:
|
|
|
|
PostQuitMessage(0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DefWindowProc(h, m, w, l);
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
HINSTANCE WindowShell::GetHINSTANCE()
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
return __windowShellData.hIns;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
2013-12-12 09:33:59 +01:00
|
|
|
HWND WindowShell::GetHWND()
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
return __windowShellData.hWnd;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
2013-12-12 09:33:59 +01:00
|
|
|
HWND WindowShell::GetParent()
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
return __windowShellData.parent;
|
|
|
|
}
|
|
|
|
bool WindowShell::CreateWin(WINDOW_INIT_DESC &desc)
|
|
|
|
{
|
|
|
|
if(__windowShellData.hWnd) return false;
|
|
|
|
if(!desc.windowProcCallback) desc.windowProcCallback = DefaultWindowCallback;
|
|
|
|
if(!desc.hInstance) desc.hInstance = GetModuleHandle(0);
|
|
|
|
if(desc.windowSize.x <= 0) desc.windowSize.x = 50;
|
|
|
|
if(desc.windowSize.y <= 0) desc.windowSize.y = 50;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
|
|
|
|
__windowShellData.parent = desc.parent;
|
|
|
|
__windowShellData.hIns = desc.hInstance;
|
2014-01-07 10:26:09 +01:00
|
|
|
__windowShellData.windowClassName = WINDOW_SHELL_CLASS_NAME;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
|
|
#pragma region Register
|
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
WNDCLASSEXW wc;
|
|
|
|
wc.cbSize = sizeof(WNDCLASSEXW);
|
2013-11-06 22:52:00 +01:00
|
|
|
wc.hIconSm = NULL;
|
2013-12-04 15:59:44 +01:00
|
|
|
wc.style = desc.windowClassStyle;
|
2013-11-06 22:52:00 +01:00
|
|
|
wc.lpfnWndProc = desc.windowProcCallback;
|
|
|
|
wc.cbClsExtra = 0;
|
|
|
|
wc.cbWndExtra = 0;
|
2013-12-12 09:33:59 +01:00
|
|
|
wc.hInstance = __windowShellData.hIns;
|
|
|
|
wc.hIcon = desc.icon;
|
|
|
|
wc.hCursor = desc.cursor;
|
|
|
|
wc.hbrBackground = desc.background;
|
|
|
|
wc.lpszMenuName = NULL;
|
|
|
|
wc.lpszClassName = __windowShellData.windowClassName;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2014-01-07 10:26:09 +01:00
|
|
|
if( !RegisterClassExW(&wc) )
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
|
|
|
MessageBox(0, L"Failed to register class", L"Initialization error", 0);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
|
|
|
|
#pragma region Create window
|
|
|
|
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
RECT rectW;
|
|
|
|
int width;
|
|
|
|
int height;
|
|
|
|
DWORD style = desc.windowStyle;
|
|
|
|
bool windowed = false;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
width = desc.windowSize.x + GetSystemMetrics(SM_CXFIXEDFRAME)*2;
|
|
|
|
height = desc.windowSize.y + GetSystemMetrics(SM_CYFIXEDFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
rectW.left=(GetSystemMetrics(SM_CXSCREEN)-width)/2;
|
|
|
|
rectW.top=(GetSystemMetrics(SM_CYSCREEN)-height)/2;
|
|
|
|
rectW.right=rectW.left+width;
|
|
|
|
rectW.bottom=rectW.top+height;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
if(__windowShellData.parent)
|
|
|
|
{
|
|
|
|
rectW.left = 0;
|
|
|
|
rectW.top = 0;
|
|
|
|
rectW.right = desc.windowSize.x;
|
|
|
|
rectW.bottom = desc.windowSize.y;
|
|
|
|
style = WS_CHILD | WS_VISIBLE;
|
|
|
|
windowed = true;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
if(windowed)
|
|
|
|
{
|
2014-01-07 10:26:09 +01:00
|
|
|
__windowShellData.hWnd = CreateWindowExW(
|
2013-12-12 09:33:59 +01:00
|
|
|
0,
|
|
|
|
__windowShellData.windowClassName ,
|
|
|
|
desc.windowName,
|
|
|
|
style,
|
|
|
|
rectW.left,
|
|
|
|
rectW.top,
|
|
|
|
rectW.right - rectW.left,
|
|
|
|
rectW.bottom - rectW.top,
|
|
|
|
__windowShellData.parent,
|
|
|
|
NULL,
|
|
|
|
__windowShellData.hIns,
|
|
|
|
NULL
|
|
|
|
);
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-07 10:26:09 +01:00
|
|
|
__windowShellData.hWnd = CreateWindowExW(
|
2013-12-12 09:33:59 +01:00
|
|
|
0,
|
|
|
|
__windowShellData.windowClassName ,
|
|
|
|
desc.windowName,
|
|
|
|
style,
|
|
|
|
desc.windowPosition.x,
|
|
|
|
desc.windowPosition.y,
|
|
|
|
desc.windowSize.x,
|
|
|
|
desc.windowSize.y,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
__windowShellData.hIns,
|
|
|
|
0
|
|
|
|
);
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
2013-12-12 09:33:59 +01:00
|
|
|
|
|
|
|
if( !__windowShellData.hWnd )
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
printf("Failed to create window handle : Code ( %ul )", GetLastError());
|
|
|
|
//MessageBox(0, L"Failed to create window", L"Error!", 0);
|
|
|
|
return false;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
#pragma endregion
|
|
|
|
|
|
|
|
|
|
|
|
//Show and update window
|
|
|
|
ShowWindow(__windowShellData.hWnd, SW_SHOW);
|
|
|
|
UpdateWindow(__windowShellData.hWnd);
|
|
|
|
|
|
|
|
return true;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
2013-12-12 09:33:59 +01:00
|
|
|
bool WindowShell::CreateConsoleWindow(bool redirectStdOut, const wchar_t* title)
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
// allocate a console for this app
|
|
|
|
if(AllocConsole() == FALSE) return false;
|
|
|
|
|
|
|
|
if(redirectStdOut)
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
// redirect unbuffered STDOUT to the console
|
|
|
|
HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
|
|
int fileDescriptor = _open_osfhandle((intptr_t)consoleHandle, _O_TEXT);
|
|
|
|
FILE *fp = _fdopen( fileDescriptor, "w" );
|
|
|
|
*stdout = *fp;
|
|
|
|
setvbuf( stdout, NULL, _IONBF, 0 );
|
|
|
|
|
|
|
|
|
|
|
|
// give the console window a bigger buffer size
|
|
|
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
|
|
|
if ( GetConsoleScreenBufferInfo(consoleHandle, &csbi) )
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2013-12-12 09:33:59 +01:00
|
|
|
COORD bufferSize;
|
|
|
|
bufferSize.X = csbi.dwSize.X;
|
|
|
|
bufferSize.Y = 50;
|
|
|
|
SetConsoleScreenBufferSize(consoleHandle, bufferSize);
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
// give the console window a nicer title
|
|
|
|
SetConsoleTitle(title);
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
return true;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|
2013-12-18 13:07:10 +01:00
|
|
|
unsigned int WindowShell::GetWidth()
|
|
|
|
{
|
|
|
|
if(!__windowShellData.hWnd) return -1;
|
|
|
|
|
|
|
|
RECT rect;
|
|
|
|
GetWindowRect(__windowShellData.hWnd, &rect);
|
|
|
|
|
|
|
|
return (rect.right - rect.left);
|
|
|
|
}
|
|
|
|
unsigned int WindowShell::GetHeight()
|
|
|
|
{
|
|
|
|
if(!__windowShellData.hWnd) return -1;
|
|
|
|
|
|
|
|
RECT rect;
|
|
|
|
GetWindowRect(__windowShellData.hWnd, &rect);
|
|
|
|
|
|
|
|
return (rect.bottom - rect.top);
|
|
|
|
}
|
2013-12-12 09:33:59 +01:00
|
|
|
bool WindowShell::Frame()
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2014-01-07 10:26:09 +01:00
|
|
|
if(!__windowShellData.hWnd) return true;
|
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
MSG msg = {0};
|
|
|
|
while (true)
|
2013-11-06 22:52:00 +01:00
|
|
|
{
|
2014-01-07 10:26:09 +01:00
|
|
|
if(!__windowShellData.parent) //Parent takes care of this
|
2013-12-12 09:33:59 +01:00
|
|
|
{
|
|
|
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
|
|
{
|
|
|
|
if (msg.message == WM_QUIT) return false;
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
DispatchMessage(&msg);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
break;
|
|
|
|
}
|
2013-11-06 22:52:00 +01:00
|
|
|
|
2013-12-12 09:33:59 +01:00
|
|
|
return true;
|
2013-11-06 22:52:00 +01:00
|
|
|
}
|