1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
// 6 april 2015
#include "uipriv_windows.h"
// TODOs:
// - child not set to fit initial size
struct uiWindow {
HWND hwnd;
uiControl *child;
BOOL shownOnce;
int (*onClosing)(uiWindow *, void *);
void *onClosingData;
};
#define uiWindowClass L"uiWindowClass"
static LRESULT CALLBACK uiWindowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
uiWindow *w;
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
LRESULT lResult;
WINDOWPOS *wp = (WINDOWPOS *) lParam;
RECT r;
w = (uiWindow *) GetWindowLongPtrW(hwnd, GWLP_USERDATA);
if (w == NULL) {
if (uMsg == WM_CREATE)
SetWindowLongPtrW(hwnd, GWLP_USERDATA, (LONG_PTR) (cs->lpCreateParams));
// fall through to DefWindowProc() anyway
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
if (sharedWndProc(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
return lResult;
switch (uMsg) {
case WM_WINDOWPOSCHANGING:
if (w->child == NULL)
break;
if ((wp->flags & SWP_NOSIZE) != 0)
break;
if (GetClientRect(w->hwnd, &r) == 0)
logLastError("error getting window client rect for resize in uiWindowWndProc()");
resize(w->child, w->hwnd, r);
return 0;
case WM_CLOSE:
if (!(*(w->onClosing))(w, w->onClosingData))
return 0;
break; // fall through to DefWindowProcW()
case WM_DESTROY:
if (w->child != NULL)
uiControlDestroy(w->child);
uiFree(w);
break; // fall through to DefWindowProcW()
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
ATOM registerWindowClass(HICON hDefaultIcon, HCURSOR hDefaultCursor)
{
WNDCLASSW wc;
ZeroMemory(&wc, sizeof (WNDCLASSW));
wc.lpszClassName = uiWindowClass;
wc.lpfnWndProc = uiWindowWndProc;
wc.hInstance = hInstance;
wc.hIcon = hDefaultIcon;
wc.hCursor = hDefaultCursor;
wc.hbrBackground = (HBRUSH) (COLOR_BTNFACE + 1);
return RegisterClassW(&wc);
}
#define exstyle 0
#define style WS_OVERLAPPEDWINDOW
static int defaultOnClosing(uiWindow *w, void *data)
{
return 1;
}
uiWindow *uiNewWindow(char *title, int width, int height)
{
uiWindow *w;
RECT adjust;
WCHAR *wtitle;
w = uiNew(uiWindow);
// TODO move other cases of default events here relative
w->onClosing = defaultOnClosing;
adjust.left = 0;
adjust.top = 0;
adjust.right = width;
adjust.bottom = height;
if (AdjustWindowRectEx(&adjust, style, FALSE, exstyle) == 0)
logLastError("error getting real window coordinates in uiWindow()");
wtitle = toUTF16(title);
w->hwnd = CreateWindowExW(exstyle,
uiWindowClass, wtitle,
style,
CW_USEDEFAULT, CW_USEDEFAULT,
adjust.right - adjust.left, adjust.bottom - adjust.top,
NULL, NULL, hInstance, w);
if (w->hwnd == NULL)
logLastError("error creating window in uiWindow()");
uiFree(wtitle);
return w;
}
void uiWindowDestroy(uiWindow *w)
{
DestroyWindow(w->hwnd);
}
uintptr_t uiWindowHandle(uiWindow *w)
{
return (uintptr_t) (w->hwnd);
}
// TODO titles
void uiWindowShow(uiWindow *w)
{
if (w->shownOnce) {
ShowWindow(w->hwnd, SW_SHOW);
return;
}
w->shownOnce = TRUE;
ShowWindow(w->hwnd, nCmdShow);
if (UpdateWindow(w->hwnd) == 0)
logLastError("error calling UpdateWindow() after showing uiWindow for the first time");
}
void uiWindowHide(uiWindow *w)
{
ShowWindow(w->hwnd, SW_HIDE);
}
void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
{
w->onClosing = f;
w->onClosingData = data;
}
void uiWindowSetChild(uiWindow *w, uiControl *c)
{
w->child = c;
(*(w->child->setParent))(w->child, (uintptr_t) (w->hwnd));
}
|