1 #pragma comment(linker, "\"/manifestdependency:type='win32' \
\r
2 name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
\r
3 processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
\r
6 #include <CommCtrl.h>
\r
8 #include "../res/resource.h"
\r
12 #include <functional>
\r
20 using CallbackFn = std::function<void()>;
\r
21 std::map<HWND, std::map<WORD, CallbackFn>> handlers;
\r
22 std::map<HWND, lay_id> lIds;
\r
24 NOTIFYICONDATA niData = { 0 };
\r
26 ShowNotificationIcon()
\r
28 Shell_NotifyIconA(NIM_ADD, &_::niData);
\r
29 Shell_NotifyIconA(NIM_SETVERSION, &_::niData);
\r
33 HideNotificationIcon()
\r
35 Shell_NotifyIconA(NIM_DELETE, &_::niData);
\r
42 WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
\r
46 DestroyWindow(hwnd);
\r
49 Shell_NotifyIconA(NIM_DELETE, &niData);
\r
50 lay_destroy_context(&ctx);
\r
54 if (wParam == SIZE_MINIMIZED) {
\r
55 ShowNotificationIcon();
\r
56 ShowWindow(hwnd, false);
\r
59 lay_set_size_xy(&_::ctx, _::root, LOWORD(lParam), HIWORD(lParam));
\r
60 lay_run_context(&_::ctx);
\r
62 for (auto &lId : lIds) {
\r
63 lay_vec4 rect = lay_get_rect(&_::ctx, lId.second);
\r
64 SetWindowPos(lId.first, HWND_TOP,
\r
72 RedrawWindow(hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
\r
76 if (handlers.find((HWND)lParam) != handlers.end()) {
\r
77 auto handler = handlers[(HWND)lParam];
\r
78 if (handler.find(HIWORD(wParam)) != handler.end()) {
\r
79 auto cb = handler[HIWORD(wParam)];
\r
87 if (LOWORD(lParam) == NIN_SELECT) {
\r
88 HideNotificationIcon();
\r
89 ShowWindow(hwnd, true);
\r
90 SetForegroundWindow(hwnd);
\r
91 SetActiveWindow(hwnd);
\r
94 case WM_CTLCOLORSTATIC:
\r
95 return (LONG)GetStockObject(WHITE_BRUSH);
\r
96 case WM_GETMINMAXINFO: {
\r
97 MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;
\r
98 mmInfo->ptMinTrackSize.x = 400;
\r
99 mmInfo->ptMinTrackSize.y = 200;
\r
103 return DefWindowProc(hwnd, msg, wParam, lParam);
\r
111 Callback(HWND hwnd, WORD ev, std::function<void()> cb)
\r
113 _::handlers[hwnd][ev] = cb;
\r
117 Window(string title, string className, HINSTANCE hInstance)
\r
120 wc.cbSize = sizeof(WNDCLASSEX);
\r
122 wc.lpfnWndProc = _::WndProc;
\r
125 wc.hInstance = hInstance;
\r
126 wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
\r
127 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
\r
128 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
\r
129 wc.lpszMenuName = nullptr;
\r
130 wc.lpszClassName = className.c_str();
\r
131 wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
\r
132 RegisterClassEx(&wc);
\r
134 lay_init_context(&_::ctx);
\r
135 _::root = lay_item(&_::ctx);
\r
136 lay_set_contain(&_::ctx, _::root, LAY_COLUMN);
\r
138 HWND result = CreateWindowA(className.c_str(),
\r
140 WS_OVERLAPPEDWINDOW,
\r
150 _::niData.cbSize = sizeof(_::niData);
\r
151 _::niData.uID = 12345;
\r
152 _::niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
\r
153 _::niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_MY_ICON));
\r
154 _::niData.hWnd = result;
\r
155 _::niData.uCallbackMessage = WM_APP+1;
\r
156 _::niData.uVersion = NOTIFYICON_VERSION_4;
\r
162 UpdateWindow(HWND hwnd)
\r
165 if (GetMessage(&msg, nullptr, 0, 0) > 0) {
\r
166 TranslateMessage(&msg);
\r
167 DispatchMessage(&msg);
\r
174 ShowWindow(HWND hwnd)
\r
176 ShowWindow(hwnd, true);
\r
180 [](HWND hwnd, LPARAM lParam) -> BOOL {
\r
181 HFONT guiFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
\r
182 SendMessage(hwnd, WM_SETFONT, (WPARAM)guiFont, MAKELPARAM(TRUE, 0));
\r
189 Button(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
191 lay_id lId = lay_item(&_::ctx);
\r
192 lay_insert(&_::ctx, parent, lId);
\r
193 lay_set_size_xy(&_::ctx, lId, w, h);
\r
194 lay_set_contain(&_::ctx, lId, contain);
\r
195 lay_set_behave(&_::ctx, lId, behave);
\r
197 HWND result = CreateWindowExA(0,
\r
200 WS_VISIBLE | WS_CHILD,
\r
206 _::lIds[result] = lId;
\r
211 ListBox(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
213 lay_id lId = lay_item(&_::ctx);
\r
214 lay_insert(&_::ctx, parent, lId);
\r
215 lay_set_size_xy(&_::ctx, lId, w, h);
\r
216 lay_set_contain(&_::ctx, lId, contain);
\r
217 lay_set_behave(&_::ctx, lId, behave);
\r
219 HWND result = CreateWindowExA(0,
\r
222 WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
\r
228 _::lIds[result] = lId;
\r
233 ListAddString(HWND hwnd, string str)
\r
235 SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)str.c_str());
\r
239 ListGetSelectedIndex(HWND hwnd)
\r
241 int sel = SendMessage(hwnd, LB_GETCURSEL, 0, 0);
\r
245 int ListFindString(HWND hwnd, string str)
\r
247 return SendMessageA(hwnd, LB_FINDSTRINGEXACT, -1, (LPARAM)str.c_str());
\r
251 ListGetText(HWND hwnd, int index)
\r
254 SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)buffer);
\r
255 return string(buffer);
\r
259 ListClear(HWND hwnd)
\r
261 SendMessageA(hwnd, LB_RESETCONTENT, 0, 0);
\r
264 void ListRemove(HWND hwnd, int index)
\r
266 SendMessageA(hwnd, LB_DELETESTRING, index, 0);
\r
270 ListView(HWND hwnd, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
272 lay_id lId = lay_item(&_::ctx);
\r
273 lay_insert(&_::ctx, parent, lId);
\r
274 lay_set_size_xy(&_::ctx, lId, w, h);
\r
275 lay_set_contain(&_::ctx, lId, contain);
\r
276 lay_set_behave(&_::ctx, lId, behave);
\r
278 HWND result = CreateWindowExA(0,
\r
281 WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL,
\r
287 _::lIds[result] = lId;
\r
292 CheckBox(HWND hwnd, string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
294 lay_id lId = lay_item(&_::ctx);
\r
295 lay_insert(&_::ctx, parent, lId);
\r
296 lay_set_size_xy(&_::ctx, lId, w, h);
\r
297 lay_set_contain(&_::ctx, lId, contain);
\r
298 lay_set_behave(&_::ctx, lId, behave);
\r
300 HWND result = CreateWindowExA(0,
\r
303 WS_VISIBLE | WS_CHILD | BS_CHECKBOX,
\r
309 _::lIds[result] = lId;
\r
313 void SetStyle(HWND hwnd, DWORD style)
\r
315 SetWindowLongPtrA(hwnd, GWL_STYLE, style);
\r
317 DWORD GetStyle(HWND hwnd)
\r
319 return GetWindowLongPtrA(hwnd, GWL_STYLE);
\r
321 void AddStyle(HWND hwnd, DWORD style)
\r
323 SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) | style);
\r
325 void RemoveStyle(HWND hwnd, DWORD style)
\r
327 SetWindowLongPtrA(hwnd, GWL_STYLE, GetStyle(hwnd) & (~style));
\r