treesummaryrefslogcommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.cmd3
-rw-r--r--src/main.cpp122
-rw-r--r--src/win.h884
3 files changed, 642 insertions, 367 deletions
diff --git a/build.cmd b/build.cmd
index d9e6d4f..c559480 100644
--- a/build.cmd
+++ b/build.cmd
@@ -1,6 +1,7 @@
+@echo off
REM cl src/mongoose.c -c
REM rc res/res.rc
-cl /EHsc src/main.cpp mongoose.obj /link user32.lib gdi32.lib shell32.lib Shlwapi.lib ws2_32.lib res/res.res
+cl /EHsc /Zi src/main.cpp mongoose.obj /link user32.lib gdi32.lib shell32.lib Shlwapi.lib ws2_32.lib res/res.res
mt -manifest .\main.exe.manifest -outputresource:main.exe;1 \ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
index a590411..805932d 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -87,60 +87,48 @@ checkForegroundProcess(std::string exeName)
bool recording = false;
HANDLE process = NULL;
-int WINAPI
-WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
+// int WINAPI
+// WinMain(HINSTANCE hInstance,
+// HINSTANCE hPrevInstance,
+// LPSTR lpCmdLine,
+// int nCmdShow)
+int main(int argc, char **argv)
{
- HWND window = win::Window("Title", "MyWindowClass", hInstance);
-
- lay_id row1 = lay_item(&win::_::ctx);
- lay_insert(&win::_::ctx, win::_::root, row1);
- lay_set_size_xy(&win::_::ctx, row1, 0, 25);
- lay_set_behave(&win::_::ctx, row1, LAY_LEFT);
- lay_set_contain(&win::_::ctx, row1, LAY_ROW);
- lay_set_margins_ltrb(&win::_::ctx, row1, 5, 5, 5, 5);
- lay_id row2 = lay_item(&win::_::ctx);
- lay_insert(&win::_::ctx, win::_::root, row2);
- lay_set_size_xy(&win::_::ctx, row2, 0, 0);
- lay_set_behave(&win::_::ctx, row2, LAY_FILL);
- lay_set_contain(&win::_::ctx, row2, LAY_ROW);
- lay_set_margins_ltrb(&win::_::ctx, row2, 5, 5, 5, 5);
- lay_id col1 = lay_item(&win::_::ctx);
- lay_set_size_xy(&win::_::ctx, col1, 80, 0);
- lay_set_behave(&win::_::ctx, col1, LAY_VCENTER);
- lay_set_contain(&win::_::ctx, col1, LAY_COLUMN);
- lay_set_margins_ltrb(&win::_::ctx, col1, 5, 0, 5, 0);
-
- HWND cbWindowTitle = win::CheckBox(window, "Window Title", row1, 100, 25, 0, 0);
- HWND cbFullscreenWindow = win::CheckBox(window, "Any Fullscreen Application", row1, 200, 25, 0, 0);
-
- HWND btnConnect = win::Button(window, "Connect", row1, 100, 25, 0, 0);
- win::Callback(btnConnect, BN_CLICKED, [&]() {
- ws::connect("ws://127.0.0.1:4444");
- });
+ //win::Window window("Title", "MyWindowClass", hInstance);
+ win::Window window("Title", "MyWindowClass", GetModuleHandle(0));
- win::Callback(cbWindowTitle, BN_CLICKED, [&]() {
- SendMessageA(cbWindowTitle, BM_SETCHECK, SendMessageA(cbWindowTitle, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0);
- });
- win::Callback(cbFullscreenWindow, BN_CLICKED, [&]() {
- SendMessageA(cbFullscreenWindow, BM_SETCHECK, SendMessageA(cbFullscreenWindow, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0);
+ lay_context *ctx = &window.ctx;
+ lay_id root = window.lId;
+
+ win::Hwnd row1(&window, &window, 0, 0, 0, 25, LAY_ROW, LAY_LEFT);
+ lay_set_margins_ltrb(ctx, row1.lId, 5, 5, 5, 5);
+ win::Hwnd row2(&window, &window, 0, 0, 0, 0, LAY_ROW, LAY_FILL);
+ lay_set_margins_ltrb(ctx, row2.lId, 5, 5, 5, 5);
+
+ win::CheckBox cbWindowTitle(&window, &row1, "Window Title", 100, 25, 0, 0);
+ win::CheckBox cbFullscreenWindow(&window, &row1, "Any Fullscreen Application", 200, 25, 0, 0);
+
+ win::Button btnConnect(&window, &row1, "Connect", 100, 25, 0, 0);
+ btnConnect.onClick([&]() {
+ ws::connect("ws://127.0.0.1:4444");
});
- HWND lstActiveProcesses = win::ListView(window, row2, 0, 0, 0, LAY_FILL);
- lay_insert(&win::_::ctx, row2, col1);
- HWND lstMonitoredProcesses = win::ListBox(window, row2, 0, 0, 0, LAY_FILL);
- win::AddStyle(lstActiveProcesses, WS_VSCROLL);
- win::AddStyle(lstMonitoredProcesses, WS_VSCROLL);
-
- HWND btnUpdateWindows = win::Button(window, "Update", col1, 85, 25, 0, 0);
- HWND btnStartMonitoringName = win::Button(window, "Exe name >>", col1, 85, 25, 0, 0);
- HWND btnStartMonitoringPath = win::Button(window, "Full path >>", col1, 85, 25, 0, 0);
- HWND btnStopMonitoring = win::Button(window, "Remove", col1, 85, 25, 0, 0);
- win::Callback(btnUpdateWindows, BN_CLICKED, [&]() {
- win::ListClear(lstActiveProcesses);
+ win::ListBox lstActiveProcesses(&window, &row2, 0, 0, 0, LAY_FILL);
+
+ win::Hwnd col1(&window, &row2, 0, 0, 80, 0, LAY_COLUMN, LAY_VCENTER);
+ lay_set_margins_ltrb(ctx, col1.lId, 5, 0, 5, 0);
+
+ win::ListBox lstMonitoredProcesses(&window, &row2, 0, 0, 0, LAY_FILL);
+ lstActiveProcesses.addStyle(WS_VSCROLL);
+ lstMonitoredProcesses.addStyle(WS_VSCROLL);
+
+ win::Button btnUpdateWindows(&window, &col1, "Update", 85, 25, 0, 0);
+ win::Button btnStartMonitoringName(&window, &col1, "Exe name >>", 85, 25, 0, 0);
+ win::Button btnStartMonitoringPath(&window, &col1, "Full path >>", 85, 25, 0, 0);
+ win::Button btnStopMonitoring(&window, &col1, "Remove", 85, 25, 0, 0);
+ btnUpdateWindows.onClick([&]() {
+ lstActiveProcesses.clear();
for (HWND hwnd = GetTopWindow(NULL); hwnd != nullptr;
hwnd = GetNextWindow(hwnd, GW_HWNDNEXT)) {
if (!IsWindowVisible(hwnd))
@@ -151,44 +139,44 @@ WinMain(HINSTANCE hInstance,
char str[1024];
if (GetModuleFileNameExA(getHwndProcess(hwnd), 0, str, 1024) != 0 &&
- win::ListFindString(lstActiveProcesses, str) == LB_ERR) {
- win::ListAddString(lstActiveProcesses, str);
+ lstActiveProcesses.findString(str) == LB_ERR) {
+ lstActiveProcesses.addString(str);
}
}
});
- win::Callback(btnStartMonitoringName, BN_CLICKED, [&]() {
- int sel = win::ListGetSelectedIndex(lstActiveProcesses);
+ btnStartMonitoringName.onClick([&]() {
+ int sel = lstActiveProcesses.getSelectedIndex();
if (sel < 0) return;
- std::string selStr = win::ListGetText(lstActiveProcesses, sel);
+ std::string selStr = lstActiveProcesses.getText(sel);
char *filename = new char[selStr.size()];
std::memcpy(filename, selStr.c_str(), selStr.size());
PathStripPathA(filename);
- if (win::ListFindString(lstMonitoredProcesses, std::string(filename)) == LB_ERR)
- win::ListAddString(lstMonitoredProcesses, std::string(filename));
+ if (lstMonitoredProcesses.findString(std::string(filename)) == LB_ERR)
+ lstMonitoredProcesses.addString(std::string(filename));
delete[] filename;
});
- win::Callback(btnStartMonitoringPath, BN_CLICKED, [&]() {
- int sel = win::ListGetSelectedIndex(lstActiveProcesses);
+ btnStartMonitoringPath.onClick([&]() {
+ int sel = lstActiveProcesses.getSelectedIndex();
if (sel < 0) return;
- std::string selStr = win::ListGetText(lstActiveProcesses, sel);
- if (win::ListFindString(lstMonitoredProcesses, selStr) == LB_ERR)
- win::ListAddString(lstMonitoredProcesses, selStr);
+ std::string selStr = lstActiveProcesses.getText(sel);
+ if (lstMonitoredProcesses.findString(selStr) == LB_ERR)
+ lstMonitoredProcesses.addString(selStr);
});
- win::Callback(btnStopMonitoring, BN_CLICKED, [&]() {
- int sel = win::ListGetSelectedIndex(lstMonitoredProcesses);
+ btnStopMonitoring.onClick([&]() {
+ int sel = lstMonitoredProcesses.getSelectedIndex();
if (sel < 0) return;
- win::ListRemove(lstMonitoredProcesses, sel);
+ lstMonitoredProcesses.remove(sel);
});
- win::ShowWindow(window);
+ window.show();
ws::init();
- SetTimer(window, 10123, 100, [](HWND, UINT, UINT_PTR, DWORD) {
+ SetTimer(window.hwnd, 10123, 100, [](HWND, UINT, UINT_PTR, DWORD) {
if (!recording) {
if (checkForegroundProcess("League of Legends.exe")) {
recording = true;
@@ -204,7 +192,7 @@ WinMain(HINSTANCE hInstance,
}
});
- while (win::UpdateWindow(window)) {
+ while (window.update()) {
ws::update();
}
}
diff --git a/src/win.h b/src/win.h
index 167e162..fe58ebe 100644
--- a/src/win.h
+++ b/src/win.h
@@ -10,320 +10,606 @@ processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "layout.h"
#include <functional>
-#include <map>
+#include <unordered_map>
#include <string>
-using std::string;
-
-namespace win {
-namespace _ {
-using CallbackFn = std::function<void()>;
-std::map<HWND, std::map<WORD, CallbackFn>> handlers;
-std::map<HWND, lay_id> lIds;
-
-NOTIFYICONDATA niData = { 0 };
-void
-ShowNotificationIcon()
-{
- Shell_NotifyIconA(NIM_ADD, &_::niData);
- Shell_NotifyIconA(NIM_SETVERSION, &_::niData);
-}
-
-void
-HideNotificationIcon()
-{
- Shell_NotifyIconA(NIM_DELETE, &_::niData);
-}
-
-lay_context ctx;
-lay_id root;
-
-LRESULT CALLBACK
-WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+// namespace wnin {
+// namespace _ {
+// using CallbackFn = std::function<void()>;
+// std::map<HWND, std::map<WORD, CallbackFn>> handlers;
+// std::map<HWND, lay_id> lIds;
+
+// NOTIFYICONDATA niData = { 0 };
+// void
+// ShowNotificationIcon()
+// {
+// Shell_NotifyIconA(NIM_ADD, &_::niData);
+// Shell_NotifyIconA(NIM_SETVERSION, &_::niData);
+// }
+
+// void
+// HideNotificationIcon()
+// {
+// Shell_NotifyIconA(NIM_DELETE, &_::niData);
+// }
+
+// lay_context ctx;
+// lay_id root;
+
+// LRESULT CALLBACK
+// WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+// {
+// switch (msg) {
+// case WM_CLOSE:
+// DestroyWindow(hwnd);
+// break;
+// case WM_DESTROY:
+// Shell_NotifyIconA(NIM_DELETE, &niData);
+// lay_destroy_context(&ctx);
+// PostQuitMessage(0);
+// break;
+// case WM_SIZE:
+// if (wParam == SIZE_MINIMIZED) {
+// ShowNotificationIcon();
+// ShowWindow(hwnd, false);
+// }
+// else {
+// lay_set_size_xy(&_::ctx, _::root, LOWORD(lParam), HIWORD(lParam));
+// lay_run_context(&_::ctx);
+
+// for (auto &lId : lIds) {
+// lay_vec4 rect = lay_get_rect(&_::ctx, lId.second);
+// SetWindowPos(lId.first, HWND_TOP,
+// rect[0],
+// rect[1],
+// rect[2],
+// rect[3],
+// SWP_NOZORDER
+// );
+// }
+// RedrawWindow(hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
+// }
+// break;
+// case WM_COMMAND:
+// if (handlers.find((HWND)lParam) != handlers.end()) {
+// auto handler = handlers[(HWND)lParam];
+// if (handler.find(HIWORD(wParam)) != handler.end()) {
+// auto cb = handler[HIWORD(wParam)];
+// cb();
+// }
+// }
+// break;
+// case WM_NOTIFY:
+// break;
+// case WM_APP + 1:
+// if (LOWORD(lParam) == NIN_SELECT) {
+// HideNotificationIcon();
+// ShowWindow(hwnd, true);
+// SetForegroundWindow(hwnd);
+// SetActiveWindow(hwnd);
+// }
+// break;
+// case WM_CTLCOLORSTATIC:
+// return (LONG)GetStockObject(WHITE_BRUSH);
+// case WM_GETMINMAXINFO: {
+// MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;
+// mmInfo->ptMinTrackSize.x = 400;
+// mmInfo->ptMinTrackSize.y = 200;
+// break;
+// }
+// default:
+// return DefWindowProc(hwnd, msg, wParam, lParam);
+// }
+// return 0;
+// }
+// }
+
+
+// void
+// Callback(HWND hwnd, WORD ev, std::function<void()> cb)
+// {
+// _::handlers[hwnd][ev] = cb;
+// }
+
+// HWND
+// Window(string title, string className, HINSTANCE hInstance)
+// {
+// WNDCLASSEX wc;
+// wc.cbSize = sizeof(WNDCLASSEX);
+// wc.style = 0;
+// wc.lpfnWndProc = _::WndProc;
+// wc.cbClsExtra = 0;
+// wc.cbWndExtra = 0;
+// wc.hInstance = hInstance;
+// wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
+// wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
+// wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+// wc.lpszMenuName = nullptr;
+// wc.lpszClassName = className.c_str();
+// wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
+// RegisterClassEx(&wc);
+
+// lay_init_context(&_::ctx);
+// _::root = lay_item(&_::ctx);
+// lay_set_contain(&_::ctx, _::root, LAY_COLUMN);
+
+// HWND result = CreateWindowA(className.c_str(),
+// title.c_str(),
+// WS_OVERLAPPEDWINDOW,
+// CW_USEDEFAULT,
+// CW_USEDEFAULT,
+// CW_USEDEFAULT,
+// CW_USEDEFAULT,
+// nullptr,
+// nullptr,
+// hInstance,
+// nullptr);
+
+// _::niData.cbSize = sizeof(_::niData);
+// _::niData.uID = 12345;
+// _::niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+// _::niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_MY_ICON));
+// _::niData.hWnd = result;
+// _::niData.uCallbackMessage = WM_APP+1;
+// _::niData.uVersion = NOTIFYICON_VERSION_4;
+
+// return result;
+// }
+
+// bool
+// UpdateWindow(HWND hwnd)
+// {
+// MSG msg;
+// if (GetMessage(&msg, nullptr, 0, 0) > 0) {
+// TranslateMessage(&msg);
+// DispatchMessage(&msg);
+// return true;
+// }
+// return false;
+// }
+
+// void
+// ShowWindow(HWND hwnd)
+// {
+// ShowWindow(hwnd, true);
+
+// EnumChildWindows(
+// hwnd,
+// [](HWND hwnd, LPARAM lParam) -> BOOL {
+// HFONT guiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+// SendMessage(hwnd, WM_SETFONT, (WPARAM)guiFont, MAKELPARAM(TRUE, 0));
+// return TRUE;
+// },
+// 0);
+// }
+
+// HWND
+// Button(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+// {
+// lay_id lId = lay_item(&_::ctx);
+// lay_insert(&_::ctx, parent, lId);
+// lay_set_size_xy(&_::ctx, lId, w, h);
+// lay_set_contain(&_::ctx, lId, contain);
+// lay_set_behave(&_::ctx, lId, behave);
+
+// HWND result = CreateWindowExA(0,
+// WC_BUTTONA,
+// title.c_str(),
+// WS_VISIBLE | WS_CHILD,
+// 0, 0, 0, 0,
+// hwnd,
+// nullptr,
+// nullptr,
+// nullptr);
+// _::lIds[result] = lId;
+// return result;
+// }
+
+// HWND
+// ListBox(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+// {
+// lay_id lId = lay_item(&_::ctx);
+// lay_insert(&_::ctx, parent, lId);
+// lay_set_size_xy(&_::ctx, lId, w, h);
+// lay_set_contain(&_::ctx, lId, contain);
+// lay_set_behave(&_::ctx, lId, behave);
+
+// HWND result = CreateWindowExA(0,
+// WC_LISTBOXA,
+// "",
+// WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
+// 0, 0, 0, 0,
+// hwnd,
+// nullptr,
+// nullptr,
+// nullptr);
+// _::lIds[result] = lId;
+// return result;
+// }
+
+// void
+// ListAddString(HWND hwnd, string str)
+// {
+// SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)str.c_str());
+// }
+
+// int
+// ListGetSelectedIndex(HWND hwnd)
+// {
+// int sel = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
+// return sel;
+// }
+
+// int ListFindString(HWND hwnd, string str)
+// {
+// return SendMessageA(hwnd, LB_FINDSTRINGEXACT, -1, (LPARAM)str.c_str());
+// }
+
+// string
+// ListGetText(HWND hwnd, int index)
+// {
+// char buffer[1024];
+// SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)buffer);
+// return string(buffer);
+// }
+
+// void
+// ListClear(HWND hwnd)
+// {
+// SendMessageA(hwnd, LB_RESETCONTENT, 0, 0);
+// }
+
+// void ListRemove(HWND hwnd, int index)
+// {
+// SendMessageA(hwnd, LB_DELETESTRING, index, 0);
+// }
+
+// HWND
+// ListView(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+// {
+// lay_id lId = lay_item(&_::ctx);
+// lay_insert(&_::ctx, parent, lId);
+// lay_set_size_xy(&_::ctx, lId, w, h);
+// lay_set_contain(&_::ctx, lId, contain);
+// lay_set_behave(&_::ctx, lId, behave);
+
+// HWND result = CreateWindowExA(0,
+// WC_LISTVIEWA,
+// "",
+// WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
+// 0, 0, 0, 0,
+// hwnd,
+// nullptr,
+// nullptr,
+// nullptr);
+// _::lIds[result] = lId;
+// return result;
+// }
+
+// HWND
+// CheckBox(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+// {
+// lay_id lId = lay_item(&_::ctx);
+// lay_insert(&_::ctx, parent, lId);
+// lay_set_size_xy(&_::ctx, lId, w, h);
+// lay_set_contain(&_::ctx, lId, contain);
+// lay_set_behave(&_::ctx, lId, behave);
+
+// HWND result = CreateWindowExA(0,
+// WC_BUTTONA,
+// title.c_str(),
+// WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
+// 0, 0, 0, 0,
+// hwnd,
+// nullptr,
+// nullptr,
+// nullptr);
+// _::lIds[result] = lId;
+// return result;
+// }
+
+// void SetStyle(HWND hwnd, DWORD style)
+// {
+// SetWindowLongPtrA(hwnd, GWL_STYLE, style);
+// }
+// DWORD GetStyle(HWND hwnd)
+// {
+// return GetWindowLongPtrA(hwnd, GWL_STYLE);
+// }
+// void AddStyle(HWND hwnd, DWORD style)
+// {
+// SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) | style);
+// }
+// void RemoveStyle(HWND hwnd, DWORD style)
+// {
+// SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) & (~style));
+// }
+// }
+
+
+
+
+namespace win
{
- switch (msg) {
- case WM_CLOSE:
- DestroyWindow(hwnd);
- break;
- case WM_DESTROY:
- Shell_NotifyIconA(NIM_DELETE, &niData);
- lay_destroy_context(&ctx);
- PostQuitMessage(0);
- break;
- case WM_SIZE:
- if (wParam == SIZE_MINIMIZED) {
- ShowNotificationIcon();
- ShowWindow(hwnd, false);
- }
- else {
- lay_set_size_xy(&_::ctx, _::root, LOWORD(lParam), HIWORD(lParam));
- lay_run_context(&_::ctx);
-
- for (auto &lId : lIds) {
- lay_vec4 rect = lay_get_rect(&_::ctx, lId.second);
- SetWindowPos(lId.first, HWND_TOP,
- rect[0],
- rect[1],
- rect[2],
- rect[3],
- SWP_NOZORDER
- );
- }
- RedrawWindow(hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- break;
- case WM_COMMAND:
- if (handlers.find((HWND)lParam) != handlers.end()) {
- auto handler = handlers[(HWND)lParam];
- if (handler.find(HIWORD(wParam)) != handler.end()) {
- auto cb = handler[HIWORD(wParam)];
- cb();
+ struct Window;
+ struct Hwnd
+ {
+ HWND hwnd;
+ lay_id lId;
+ Window *window;
+
+ Hwnd() {}
+ Hwnd(Window *window, Hwnd *parent, LPCSTR className, LPCSTR windowName, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave);
+
+ void setStyle(DWORD style)
+ {
+ SetWindowLongPtrA(hwnd, GWL_STYLE, style);
+ }
+ DWORD getStyle()
+ {
+ return GetWindowLongPtrA(hwnd, GWL_STYLE);
+ }
+ void addStyle(DWORD style)
+ {
+ SetWindowLongPtrA(hwnd, GWL_STYLE, getStyle() | style);
+ }
+ void removeStyle(DWORD style)
+ {
+ SetWindowLongPtrA(hwnd, GWL_STYLE, getStyle() & (~style));
+ }
+ };
+ struct Window : Hwnd
+ {
+ private:
+ NOTIFYICONDATAA niData = { 0 };
+
+ static LRESULT CALLBACK
+ WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+ {
+ Window *window = (Window*)GetWindowLongPtrA(hwnd, 0);
+ if (window == nullptr)
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+
+ bool defaultHandler = false;
+
+ switch (msg) {
+ case WM_CLOSE:
+ DestroyWindow(hwnd);
+ break;
+ case WM_DESTROY:
+ Shell_NotifyIconA(NIM_DELETE, &window->niData);
+ lay_destroy_context(&window->ctx);
+ PostQuitMessage(0);
+ break;
+ case WM_SIZE:
+ if (wParam == SIZE_MINIMIZED) {
+ //TODO: auslagen
+ //ShowNotificationIcon();
+ ShowWindow(hwnd, false);
+ }
+ else {
+ lay_set_size_xy(&window->ctx, window->lId, LOWORD(lParam), HIWORD(lParam));
+ lay_run_context(&window->ctx);
+
+ //RedrawWindow(hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
+ }
+ break;
+ case WM_NOTIFY:
+ break;
+ case WM_APP + 1:
+ if (LOWORD(lParam) == NIN_SELECT) {
+ //TODO: auslagern
+ //HideNotificationIcon();
+ ShowWindow(hwnd, true);
+ SetForegroundWindow(hwnd);
+ SetActiveWindow(hwnd);
+ }
+ break;
+ case WM_CTLCOLORSTATIC:
+ return (LONG)GetStockObject(WHITE_BRUSH);
+ case WM_GETMINMAXINFO: {
+ MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;
+ mmInfo->ptMinTrackSize.x = 400;
+ mmInfo->ptMinTrackSize.y = 200;
+ break;
}
+ default:
+ defaultHandler = true;
+ break;
}
- break;
- case WM_NOTIFY:
- break;
- case WM_APP + 1:
- if (LOWORD(lParam) == NIN_SELECT) {
- HideNotificationIcon();
- ShowWindow(hwnd, true);
- SetForegroundWindow(hwnd);
- SetActiveWindow(hwnd);
+
+ for (auto handler : window->handlers[msg])
+ handler(hwnd, msg, wParam, lParam);
+
+ if (defaultHandler)
+ return DefWindowProc(hwnd, msg, wParam, lParam);
+ else
+ return 0;
+ }
+ public:
+ lay_context ctx;
+ std::unordered_map<UINT,
+ std::vector<
+ std::function<void(HWND, UINT, WPARAM, LPARAM)>>> handlers;
+
+ Window(std::string title, std::string className, HINSTANCE hInstance)
+ {
+ WNDCLASSEXA wc;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = 0;
+ wc.lpfnWndProc = WndProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = sizeof(Window*);
+ wc.hInstance = hInstance;
+ wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
+ wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
+ wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ wc.lpszMenuName = nullptr;
+ wc.lpszClassName = className.c_str();
+ wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
+ RegisterClassExA(&wc);
+
+ lay_init_context(&ctx);
+ lId = lay_item(&ctx);
+ lay_set_contain(&ctx, lId, LAY_COLUMN);
+
+ hwnd = CreateWindowA(className.c_str(),
+ title.c_str(),
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ nullptr,
+ nullptr,
+ hInstance,
+ nullptr);
+
+ SetWindowLongPtrA(hwnd, 0, (LONG_PTR)this);
+
+
+ niData.cbSize = sizeof(niData);
+ niData.uID = 12345;
+ niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
+ niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_MY_ICON));
+ niData.hWnd = hwnd;
+ niData.uCallbackMessage = WM_APP+1;
+ niData.uVersion = NOTIFYICON_VERSION_4;
+ }
+ bool update()
+ {
+ MSG msg;
+ if (GetMessage(&msg, nullptr, 0, 0) > 0) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ return true;
}
- break;
- case WM_CTLCOLORSTATIC:
- return (LONG)GetStockObject(WHITE_BRUSH);
- case WM_GETMINMAXINFO: {
- MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;
- mmInfo->ptMinTrackSize.x = 400;
- mmInfo->ptMinTrackSize.y = 200;
- break;
+ return false;
+ }
+ void show()
+ {
+ ShowWindow(hwnd, true);
+
+ EnumChildWindows(
+ hwnd,
+ [](HWND hwnd, LPARAM lParam) -> BOOL {
+ HFONT guiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
+ SendMessage(hwnd, WM_SETFONT, (WPARAM)guiFont, MAKELPARAM(TRUE, 0));
+ return TRUE;
+ },
+ 0);
+ }
+ };
+
+ struct Button : Hwnd
+ {
+ Button(Window *window, Hwnd *parent, std::string title, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+ : Hwnd(window, parent, WC_BUTTONA, title.c_str(), w, h, contain, behave)
+ {
+ window->handlers[WM_COMMAND].push_back([&](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ if ((HWND)lParam == this->hwnd && HIWORD(wParam) == BN_CLICKED)
+ for (auto handler : this->onClickHandlers)
+ handler();
+ });
}
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return 0;
-}
-}
-
-
-void
-Callback(HWND hwnd, WORD ev, std::function<void()> cb)
-{
- _::handlers[hwnd][ev] = cb;
-}
-
-HWND
-Window(string title, string className, HINSTANCE hInstance)
-{
- WNDCLASSEX wc;
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = 0;
- wc.lpfnWndProc = _::WndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = hInstance;
- wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
- wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wc.lpszMenuName = nullptr;
- wc.lpszClassName = className.c_str();
- wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
- RegisterClassEx(&wc);
-
- lay_init_context(&_::ctx);
- _::root = lay_item(&_::ctx);
- lay_set_contain(&_::ctx, _::root, LAY_COLUMN);
-
- HWND result = CreateWindowA(className.c_str(),
- title.c_str(),
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- CW_USEDEFAULT,
- nullptr,
- nullptr,
- hInstance,
- nullptr);
-
- _::niData.cbSize = sizeof(_::niData);
- _::niData.uID = 12345;
- _::niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
- _::niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_MY_ICON));
- _::niData.hWnd = result;
- _::niData.uCallbackMessage = WM_APP+1;
- _::niData.uVersion = NOTIFYICON_VERSION_4;
-
- return result;
-}
-
-bool
-UpdateWindow(HWND hwnd)
-{
- MSG msg;
- if (GetMessage(&msg, nullptr, 0, 0) > 0) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- return true;
- }
- return false;
-}
-
-void
-ShowWindow(HWND hwnd)
-{
- ShowWindow(hwnd, true);
-
- EnumChildWindows(
- hwnd,
- [](HWND hwnd, LPARAM lParam) -> BOOL {
- HFONT guiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
- SendMessage(hwnd, WM_SETFONT, (WPARAM)guiFont, MAKELPARAM(TRUE, 0));
- return TRUE;
- },
- 0);
-}
-
-HWND
-Button(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
-{
- lay_id lId = lay_item(&_::ctx);
- lay_insert(&_::ctx, parent, lId);
- lay_set_size_xy(&_::ctx, lId, w, h);
- lay_set_contain(&_::ctx, lId, contain);
- lay_set_behave(&_::ctx, lId, behave);
-
- HWND result = CreateWindowExA(0,
- WC_BUTTONA,
- title.c_str(),
- WS_VISIBLE | WS_CHILD,
- 0, 0, 0, 0,
- hwnd,
- nullptr,
- nullptr,
- nullptr);
- _::lIds[result] = lId;
- return result;
-}
-
-HWND
-ListBox(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
-{
- lay_id lId = lay_item(&_::ctx);
- lay_insert(&_::ctx, parent, lId);
- lay_set_size_xy(&_::ctx, lId, w, h);
- lay_set_contain(&_::ctx, lId, contain);
- lay_set_behave(&_::ctx, lId, behave);
-
- HWND result = CreateWindowExA(0,
- WC_LISTBOXA,
- "",
- WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
- 0, 0, 0, 0,
- hwnd,
- nullptr,
- nullptr,
- nullptr);
- _::lIds[result] = lId;
- return result;
-}
-
-void
-ListAddString(HWND hwnd, string str)
-{
- SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)str.c_str());
-}
-int
-ListGetSelectedIndex(HWND hwnd)
-{
- int sel = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
- return sel;
-}
+ void onClick(std::function<void()> cb)
+ {
+ onClickHandlers.push_back(cb);
+ }
+ private:
+ std::vector<std::function<void()>> onClickHandlers;
+ };
+
+ struct CheckBox : Hwnd
+ {
+ CheckBox(Window *window, Hwnd *parent, std::string title, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+ : Hwnd(window, parent, WC_BUTTONA, title.c_str(), w, h, contain, behave)
+ {
+ addStyle(BS_CHECKBOX);
+ window->handlers[WM_COMMAND].push_back([&](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ if ((HWND)lParam == this->hwnd && HIWORD(wParam) == BN_CLICKED)
+ SendMessageA(this->hwnd, BM_SETCHECK, SendMessageA(this->hwnd, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0);
+ });
+ }
+ };
+
+ struct ListBox : Hwnd
+ {
+ ListBox(Window *window, Hwnd *parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
+ : Hwnd(window, parent, WC_LISTBOXA, "", w, h, contain, behave)
+ {
+ addStyle(WS_BORDER);
+ addStyle(WS_VSCROLL);
+ }
-int ListFindString(HWND hwnd, string str)
-{
- return SendMessageA(hwnd, LB_FINDSTRINGEXACT, -1, (LPARAM)str.c_str());
-}
+ void addString(std::string str)
+ {
+ SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)str.c_str());
+ }
-string
-ListGetText(HWND hwnd, int index)
-{
- char buffer[1024];
- SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)buffer);
- return string(buffer);
-}
+ int getSelectedIndex()
+ {
+ return SendMessage(hwnd, LB_GETCURSEL, 0, 0);
+ }
-void
-ListClear(HWND hwnd)
-{
- SendMessageA(hwnd, LB_RESETCONTENT, 0, 0);
-}
+ int findString(std::string str)
+ {
+ return SendMessageA(hwnd, LB_FINDSTRINGEXACT, -1, (LPARAM)str.c_str());
+ }
-void ListRemove(HWND hwnd, int index)
-{
- SendMessageA(hwnd, LB_DELETESTRING, index, 0);
-}
+ std::string getText(int index)
+ {
+ int len = SendMessageA(hwnd, LB_GETTEXTLEN, index, 0);
+ std::string result;
+ result.reserve(len);
+ SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)result.data());
+ return result;
+ }
-HWND
-ListView(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
-{
- lay_id lId = lay_item(&_::ctx);
- lay_insert(&_::ctx, parent, lId);
- lay_set_size_xy(&_::ctx, lId, w, h);
- lay_set_contain(&_::ctx, lId, contain);
- lay_set_behave(&_::ctx, lId, behave);
-
- HWND result = CreateWindowExA(0,
- WC_LISTVIEWA,
- "",
- WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
- 0, 0, 0, 0,
- hwnd,
- nullptr,
- nullptr,
- nullptr);
- _::lIds[result] = lId;
- return result;
-}
+ void clear()
+ {
+ SendMessageA(hwnd, LB_RESETCONTENT, 0, 0);
+ }
-HWND
-CheckBox(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
-{
- lay_id lId = lay_item(&_::ctx);
- lay_insert(&_::ctx, parent, lId);
- lay_set_size_xy(&_::ctx, lId, w, h);
- lay_set_contain(&_::ctx, lId, contain);
- lay_set_behave(&_::ctx, lId, behave);
-
- HWND result = CreateWindowExA(0,
- WC_BUTTONA,
- title.c_str(),
- WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
- 0, 0, 0, 0,
- hwnd,
- nullptr,
- nullptr,
- nullptr);
- _::lIds[result] = lId;
- return result;
+ void remove(int index)
+ {
+ SendMessageA(hwnd, LB_DELETESTRING, index, 0);
+ }
+ };
}
-void SetStyle(HWND hwnd, DWORD style)
+win::Hwnd::Hwnd(Window *window, Hwnd *parent, LPCSTR className, LPCSTR windowName, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
{
- SetWindowLongPtrA(hwnd, GWL_STYLE, style);
-}
-DWORD GetStyle(HWND hwnd)
-{
- return GetWindowLongPtrA(hwnd, GWL_STYLE);
-}
-void AddStyle(HWND hwnd, DWORD style)
-{
- SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) | style);
-}
-void RemoveStyle(HWND hwnd, DWORD style)
-{
- SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) & (~style));
-}
+ this->window = window;
+
+ lId = lay_item(&window->ctx);
+ lay_insert(&window->ctx, parent->lId, lId);
+ lay_set_size_xy(&window->ctx, lId, w, h);
+ lay_set_contain(&window->ctx, lId, contain);
+ lay_set_behave(&window->ctx, lId, behave);
+
+ hwnd = CreateWindowExA(0,
+ className,
+ windowName,
+ WS_VISIBLE | WS_CHILD,
+ 0,
+ 0,
+ 0,
+ 0,
+ window->hwnd,
+ nullptr,
+ nullptr,
+ nullptr);
+
+ window->handlers[WM_SIZE].push_back([this](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
+ lay_vec4 rect = lay_get_rect(&this->window->ctx, this->lId);
+ SetWindowPos(this->hwnd, HWND_TOP,
+ rect[0],
+ rect[1],
+ rect[2],
+ rect[3],
+ SWP_NOZORDER
+ );
+ });
} \ No newline at end of file