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