Created
May 20, 2020 10:19
-
-
Save davepkennedy/0d580748d3322b21b569abd29167fc2a to your computer and use it in GitHub Desktop.
Some Windowing snippets
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Application.h" | |
#include "BaseWindow.h" | |
Application::Application(BaseWindow* window) | |
: _window(window) | |
{ | |
} | |
Application::~Application() | |
{ | |
} | |
void Application::Run() const | |
{ | |
MSG msg; | |
_window->Create(); | |
_window->Show(); | |
_window->Update(); | |
ZeroMemory(&msg, sizeof(MSG)); | |
while (true) { | |
if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { | |
if (msg.message == WM_QUIT) { | |
break; | |
} | |
TranslateMessage(&msg); | |
DispatchMessage(&msg); | |
} | |
_window->Idle(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class BaseWindow; | |
class Application | |
{ | |
private: | |
BaseWindow* _window; | |
public: | |
Application(BaseWindow* window); | |
~Application(); | |
void Run() const; | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "framework.h" | |
#include "BaseWindow.h" | |
#include "Logger.h" | |
LRESULT CALLBACK BaseWindow::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) | |
{ | |
BaseWindow* window = nullptr; | |
if (msg == WM_CREATE) { | |
LPCREATESTRUCT lpCreateStruct = (LPCREATESTRUCT)lParam; | |
window = (BaseWindow*)lpCreateStruct->lpCreateParams; | |
window->_hwnd = hWnd; | |
SetWindowLongPtr(hWnd, GWLP_USERDATA, (LONG_PTR)window); | |
} | |
else { | |
window = (BaseWindow*)GetWindowLongPtr(hWnd, GWLP_USERDATA); | |
} | |
if (window) { | |
window->Invoke(msg, wParam, lParam); | |
} | |
return DefWindowProc(hWnd, msg, wParam, lParam); | |
} | |
bool BaseWindow::Register() | |
{ | |
WNDCLASSEX wcx; | |
::ZeroMemory(&wcx, sizeof(WNDCLASSEX)); | |
if (GetClassInfoEx(GetModuleHandle(nullptr), ClassName(), &wcx)) { | |
return true; | |
} | |
wcx.cbSize = sizeof(WNDCLASSEX); | |
wcx.hbrBackground = Background(); | |
wcx.hCursor = LoadCursor(nullptr, IDC_ARROW); | |
wcx.hIcon = LoadIcon(nullptr, IDI_APPLICATION); | |
wcx.hIconSm = wcx.hIcon; | |
wcx.hInstance = GetModuleHandle(nullptr); | |
wcx.lpfnWndProc = WndProc; | |
wcx.lpszClassName = ClassName(); | |
wcx.lpszMenuName = nullptr; | |
wcx.style = ClassStyle(); | |
return RegisterClassEx(&wcx) != 0; | |
} | |
BaseWindow::BaseWindow() | |
: _hwnd(nullptr) | |
{ | |
} | |
BaseWindow::~BaseWindow() | |
{ | |
Close(); | |
Destroy(); | |
} | |
void BaseWindow::Create(HWND parent) | |
{ | |
ATOM atom = Register(); | |
if (!atom) { | |
OutputLogger::LOGGER.FailLastError(); | |
} | |
if (!CreateWindow(ClassName(), WindowName(), WindowStyle(), | |
CW_USEDEFAULT, CW_USEDEFAULT, | |
CW_USEDEFAULT, CW_USEDEFAULT, | |
parent, nullptr, GetModuleHandle(nullptr), this)) { | |
OutputLogger::LOGGER.FailLastError(); | |
} | |
Observe(WM_CLOSE, [](WPARAM, LPARAM) {PostQuitMessage(0); }); | |
} | |
void BaseWindow::Close() | |
{ | |
if (_hwnd) { | |
CloseWindow(_hwnd); | |
} | |
} | |
void BaseWindow::Destroy() | |
{ | |
if (_hwnd) { | |
DestroyWindow(_hwnd); | |
_hwnd = nullptr; | |
} | |
} | |
void BaseWindow::Size(int cx, int cy) | |
{ | |
SIZE sz = { cx, cy }; | |
Size(sz); | |
} | |
void BaseWindow::Size(SIZE sz) | |
{ | |
RECT rect{ 0, 0, sz.cx, sz.cy }; | |
/* | |
DWORD style = GetWindowLong(_hwnd, GWL_STYLE); | |
DWORD exStyle = GetWindowLong(_hwnd, GWL_EXSTYLE); | |
AdjustWindowRectExForDpi(&rect , style, false, exStyle, GetDpiForWindow(_hwnd)); | |
ClientToScreen(_hwnd, (LPPOINT)&rect.left); | |
ClientToScreen(_hwnd, (LPPOINT)&rect.right); | |
SetWindowPos(_hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOREPOSITION); | |
*/ | |
SetBounds(rect, SWP_NOZORDER | SWP_NOREPOSITION); | |
} | |
void BaseWindow::Position(int x, int y) | |
{ | |
POINT pt{ x, y }; | |
Position(pt); | |
} | |
void BaseWindow::Position(POINT pt) | |
{ | |
SIZE sz = Size(); | |
//SetWindowPos(_hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER|SWP_NOSIZE); | |
//MoveWindow(*this, pt.x, pt.y, sz.cx, sz.cy, true); | |
RECT rect = { pt.x, pt.y, 0, 0 }; | |
SetBounds(rect, SWP_NOZORDER | SWP_NOSIZE); | |
} | |
void BaseWindow::SetBounds(RECT rect, UINT flags) | |
{ | |
DWORD style = GetWindowLong(_hwnd, GWL_STYLE); | |
DWORD exStyle = GetWindowLong(_hwnd, GWL_EXSTYLE); | |
AdjustWindowRectExForDpi(&rect, style, false, exStyle, GetDpiForWindow(_hwnd)); | |
//ClientToScreen(_hwnd, (LPPOINT)& rect.left); | |
//ClientToScreen(_hwnd, (LPPOINT)& rect.right); | |
SetWindowPos(_hwnd, HWND_TOP, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags); | |
} | |
SIZE BaseWindow::Size() const | |
{ | |
RECT rect; | |
SIZE size = { 0, 0 }; | |
/* | |
if (GetWindowRect(_hwnd, &rect)) { | |
size.cx = rect.right - rect.left; | |
size.cy = rect.bottom - rect.top; | |
} | |
*/ | |
if (GetClientRect(_hwnd, &rect)) { | |
size.cx = rect.right - rect.left; | |
size.cy = rect.bottom - rect.top; | |
} | |
return size; | |
} | |
POINT BaseWindow::Position() const | |
{ | |
RECT rect; | |
POINT pt = { 0, 0 }; | |
if (GetWindowRect(_hwnd, &rect)) { | |
pt.x = rect.left; | |
pt.y = rect.right; | |
} | |
return pt; | |
} | |
void BaseWindow::Text(LPCTSTR text) | |
{ | |
SetWindowText(_hwnd, text); | |
} | |
void BaseWindow::Show(int show) | |
{ | |
ShowWindow(_hwnd, show); | |
} | |
void BaseWindow::Update() | |
{ | |
UpdateWindow(_hwnd); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <Windows.h> | |
#include "Observable.h" | |
#define BIND_HANDLER(x) (std::bind(&x, this, std::placeholders::_1, std::placeholders::_2)) | |
class BaseWindow : public Observable<UINT, WPARAM, LPARAM> | |
{ | |
private: | |
HWND _hwnd; | |
private: | |
static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); | |
void SetBounds(RECT rect, UINT flags); | |
protected: | |
operator HWND() const { return _hwnd; } | |
bool Register(); | |
public: | |
BaseWindow(); | |
~BaseWindow(); | |
void Create(HWND parent = nullptr); | |
void Close(); | |
virtual void Destroy(); | |
virtual void Size(int cx, int cy); | |
virtual void Size(SIZE sz); | |
virtual void Position(int x, int y); | |
virtual void Position(POINT pt); | |
SIZE Size() const; | |
POINT Position() const; | |
void Text(LPCTSTR text); | |
virtual LPCTSTR ClassName() { return TEXT("BaseWindow"); } | |
virtual LPCTSTR WindowName() { return ClassName(); } | |
virtual UINT ClassStyle() { return CS_HREDRAW | CS_VREDRAW; } | |
virtual UINT WindowStyle() { return WS_OVERLAPPEDWINDOW; } | |
virtual HBRUSH Background() { return (HBRUSH)(COLOR_WINDOW + 1); } | |
void Show(int show = SW_SHOW); | |
void Update(); | |
virtual void Idle() {}; | |
}; | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <map> | |
#include <functional> | |
#include <vector> | |
template <typename MSG, typename ... ARGS> | |
class Observable | |
{ | |
protected: | |
std::map<MSG, std::vector<std::function<void(ARGS...)>>> _callbacks; | |
public: | |
void Observe(MSG msg, std::function<void(ARGS...)> callback) { | |
//_callbacks[msg] = callback; | |
_callbacks[msg].push_back(callback); | |
} | |
void Invoke(MSG msg, ARGS... args) { | |
if (_callbacks.find(msg) != _callbacks.end()) { | |
//_callbacks[msg](std::forward<ARGS>(args)...); | |
for (auto f : _callbacks[msg]) { | |
f(std::forward<ARGS>(args)...); | |
} | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment