+// 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