From 8d2244aefe172b5b1e15a32ad23991945d128f3a Mon Sep 17 00:00:00 2001 From: Patrick Schönberger Date: Sat, 8 Jan 2022 12:34:02 +0100 Subject: ws connect works --- src/win.h | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 329 insertions(+) create mode 100644 src/win.h (limited to 'src/win.h') diff --git a/src/win.h b/src/win.h new file mode 100644 index 0000000..65f2595 --- /dev/null +++ b/src/win.h @@ -0,0 +1,329 @@ +#pragma comment(linker, "\"/manifestdependency:type='win32' \ +name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ +processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + +#include +#include + +#include "layout.h" + +#include +#include +#include + +using std::string; + +namespace win { +struct Length +{ + int pixel; + float percent; +}; +struct Size +{ + Length x, y, w, h; + int getX(HWND hwnd) + { + RECT rect; + GetClientRect(hwnd, &rect); + return x.percent * (rect.right - rect.left) + x.pixel; + } + int getY(HWND hwnd) + { + RECT rect; + GetClientRect(hwnd, &rect); + return y.percent * (rect.bottom - rect.top) + y.pixel; + } + int getW(HWND hwnd) + { + RECT rect; + GetClientRect(hwnd, &rect); + return w.percent * (rect.right - rect.left) + w.pixel; + } + int getH(HWND hwnd, int _w, int _h) + { + RECT rect; + GetWindowRect(hwnd, &rect); + return h.percent * (rect.bottom - rect.top) + h.pixel; + } +}; + +namespace _ { +using CallbackFn = std::function; +std::map> handlers; +std::map lIds; + +NOTIFYICONDATA niData = { 0 }; + +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) { + ShowWindow(hwnd, false); + SetForegroundWindow(hwnd); + SetActiveWindow(hwnd); + } + 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) + ShowWindow(hwnd, 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; + } + default: + return DefWindowProc(hwnd, msg, wParam, lParam); + } + return 0; +} +} + +void +ShowNotificationIcon(HINSTANCE hInstance, HWND hwnd) +{ + _::niData.cbSize = sizeof(_::niData); + _::niData.uID = 12345; + _::niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + _::niData.hIcon = LoadIconA(nullptr, IDI_WINLOGO); + _::niData.hWnd = hwnd; + _::niData.uCallbackMessage = WM_APP+1; + _::niData.uVersion = NOTIFYICON_VERSION_4; + + Shell_NotifyIconA(NIM_ADD, &_::niData); + Shell_NotifyIconA(NIM_SETVERSION, &_::niData); +} + +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); + lay_set_margins_ltrb(&_::ctx, _::root, 5, 5, 5, 5); + + return CreateWindowA(className.c_str(), + title.c_str(), + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + nullptr, + nullptr, + hInstance, + nullptr); +} + +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 +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)); +} +} \ No newline at end of file -- cgit v1.2.3