X-Git-Url: https://gitweb.ps.run/autorec/blobdiff_plain/2986e5896e745a6b49160f682569e0f9976034bf..3ec9dfbe56f54f699f2d5efb4e3a4be96e157bc0:/src/win.h 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 -#include +#include #include -using std::string; - -namespace win { -namespace _ { -using CallbackFn = std::function; -std::map> handlers; -std::map 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; +// std::map> handlers; +// std::map 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 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>> 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 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 cb) + { + onClickHandlers.push_back(cb); + } + private: + std::vector> 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