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
13 #include <unordered_map>
\r
27 Hwnd(Window *window, LPCSTR className, LPCSTR windowName, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave);
\r
29 void setStyle(DWORD style)
\r
31 SetWindowLongPtrA(hwnd, GWL_STYLE, style);
\r
35 return GetWindowLongPtrA(hwnd, GWL_STYLE);
\r
37 void addStyle(DWORD style)
\r
39 SetWindowLongPtrA(hwnd, GWL_STYLE, getStyle() | style);
\r
41 void removeStyle(DWORD style)
\r
43 SetWindowLongPtrA(hwnd, GWL_STYLE, getStyle() & (~style));
\r
46 struct Window : Hwnd
\r
49 NOTIFYICONDATAA niData = { 0 };
\r
51 static LRESULT CALLBACK
\r
52 WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
\r
54 Window *window = (Window*)GetWindowLongPtrA(hwnd, 0);
\r
55 if (window == nullptr)
\r
56 return DefWindowProc(hwnd, msg, wParam, lParam);
\r
58 bool defaultHandler = false;
\r
62 DestroyWindow(hwnd);
\r
65 Shell_NotifyIconA(NIM_DELETE, &window->niData);
\r
66 lay_destroy_context(&window->ctx);
\r
70 if (wParam == SIZE_MINIMIZED) {
\r
72 //ShowNotificationIcon();
\r
73 ShowWindow(hwnd, false);
\r
76 lay_set_size_xy(&window->ctx, window->lId, LOWORD(lParam), HIWORD(lParam));
\r
77 lay_run_context(&window->ctx);
\r
79 //RedrawWindow(hwnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
\r
85 if (LOWORD(lParam) == NIN_SELECT) {
\r
87 //HideNotificationIcon();
\r
88 ShowWindow(hwnd, true);
\r
89 SetForegroundWindow(hwnd);
\r
90 SetActiveWindow(hwnd);
\r
93 case WM_CTLCOLORSTATIC:
\r
94 return (LONG)GetStockObject(WHITE_BRUSH);
\r
95 case WM_GETMINMAXINFO: {
\r
96 MINMAXINFO *mmInfo = (MINMAXINFO*)lParam;
\r
97 mmInfo->ptMinTrackSize.x = 400;
\r
98 mmInfo->ptMinTrackSize.y = 200;
\r
102 defaultHandler = true;
\r
106 for (auto handler : window->handlers[msg])
\r
107 handler(hwnd, msg, wParam, lParam);
\r
109 if (defaultHandler)
\r
110 return DefWindowProc(hwnd, msg, wParam, lParam);
\r
116 std::unordered_map<UINT,
\r
118 std::function<void(HWND, UINT, WPARAM, LPARAM)>>> handlers;
\r
120 Window(std::string title, std::string className, HINSTANCE hInstance)
\r
123 wc.cbSize = sizeof(WNDCLASSEX);
\r
125 wc.lpfnWndProc = WndProc;
\r
127 wc.cbWndExtra = sizeof(Window*);
\r
128 wc.hInstance = hInstance;
\r
129 wc.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
\r
130 wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
\r
131 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
\r
132 wc.lpszMenuName = nullptr;
\r
133 wc.lpszClassName = className.c_str();
\r
134 wc.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
\r
135 RegisterClassExA(&wc);
\r
137 lay_init_context(&ctx);
\r
138 lId = lay_item(&ctx);
\r
139 lay_set_contain(&ctx, lId, LAY_COLUMN);
\r
141 hwnd = CreateWindowA(className.c_str(),
\r
143 WS_OVERLAPPEDWINDOW,
\r
153 SetWindowLongPtrA(hwnd, 0, (LONG_PTR)this);
\r
156 niData.cbSize = sizeof(niData);
\r
157 niData.uID = 12345;
\r
158 niData.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
\r
159 niData.hIcon = LoadIconA(hInstance, MAKEINTRESOURCEA(IDI_MY_ICON));
\r
160 niData.hWnd = hwnd;
\r
161 niData.uCallbackMessage = WM_APP+1;
\r
162 niData.uVersion = NOTIFYICON_VERSION_4;
\r
167 if (GetMessage(&msg, nullptr, 0, 0) > 0) {
\r
168 TranslateMessage(&msg);
\r
169 DispatchMessage(&msg);
\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 struct Button : Hwnd
\r
191 Button(Window *window, std::string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
192 : Hwnd(window, WC_BUTTONA, title.c_str(), parent, w, h, contain, behave)
\r
194 window->handlers[WM_COMMAND].push_back([&](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
\r
195 if ((HWND)lParam == this->hwnd && HIWORD(wParam) == BN_CLICKED)
\r
196 for (auto handler : this->onClickHandlers)
\r
201 void onClick(std::function<void()> cb)
\r
203 onClickHandlers.push_back(cb);
\r
206 std::vector<std::function<void()>> onClickHandlers;
\r
209 struct CheckBox : Hwnd
\r
211 CheckBox(Window *window, std::string title, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
212 : Hwnd(window, WC_BUTTONA, title.c_str(), parent, w, h, contain, behave)
\r
214 addStyle(BS_CHECKBOX);
\r
215 window->handlers[WM_COMMAND].push_back([&](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
\r
216 if ((HWND)lParam == this->hwnd && HIWORD(wParam) == BN_CLICKED)
\r
217 SendMessageA(this->hwnd, BM_SETCHECK, SendMessageA(this->hwnd, BM_GETCHECK, 0, 0) ? BST_UNCHECKED : BST_CHECKED, 0);
\r
222 struct ListBox : Hwnd
\r
224 ListBox(Window *window, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
225 : Hwnd(window, WC_LISTBOXA, "", parent, w, h, contain, behave)
\r
227 addStyle(WS_BORDER);
\r
228 //addStyle(WS_VSCROLL);
\r
231 void addString(std::string str)
\r
233 SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM)str.c_str());
\r
236 int getSelectedIndex()
\r
238 return SendMessage(hwnd, LB_GETCURSEL, 0, 0);
\r
241 int findString(std::string str)
\r
243 return SendMessageA(hwnd, LB_FINDSTRINGEXACT, -1, (LPARAM)str.c_str());
\r
246 std::string getText(int index)
\r
248 int len = SendMessageA(hwnd, LB_GETTEXTLEN, index, 0);
\r
249 std::string result(len, 0);
\r
250 SendMessage(hwnd, LB_GETTEXT, index, (LPARAM)result.data());
\r
256 SendMessageA(hwnd, LB_RESETCONTENT, 0, 0);
\r
259 void remove(int index)
\r
261 SendMessageA(hwnd, LB_DELETESTRING, index, 0);
\r
265 lay_id createLayId(lay_context *ctx, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
267 lay_id lId = lay_item(ctx);
\r
268 lay_insert(ctx, parent, lId);
\r
269 lay_set_size_xy(ctx, lId, w, h);
\r
270 lay_set_contain(ctx, lId, contain);
\r
271 lay_set_behave(ctx, lId, behave);
\r
279 win::Hwnd::Hwnd(Window *window, LPCSTR className, LPCSTR windowName, lay_id parent, lay_scalar w, lay_scalar h, uint32_t contain, uint32_t behave)
\r
281 this->window = window;
\r
283 lId = createLayId(&window->ctx, parent, w, h, contain, behave);
\r
285 hwnd = CreateWindowExA(0,
\r
288 WS_VISIBLE | WS_CHILD,
\r
298 window->handlers[WM_SIZE].push_back([this](HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
\r
299 lay_vec4 rect = lay_get_rect(&this->window->ctx, this->lId);
\r
300 SetWindowPos(this->hwnd, HWND_TOP,
\r