1 #include <windows.h>
2 #include <uxtheme.h>
3 #include <stdlib.h>
4 #include <tchar.h>
5 #include "resource.h"
6
7 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
8
9 HICON hico;
10 HBITMAP hbmp;
11 HIMAGELIST himl;
12 POINT scPos;
13
14 HBRUSH hbrNULL;
15 HBRUSH hbrRed;
16 HBRUSH hbrGreen;
17 HBRUSH hbrBlue;
18 HBRUSH hbrCyan;
19 HBRUSH hbrYellow;
20
21 HBRUSH hbrCtlColorStatic;
22 HBRUSH hbrCtlColorBtn;
23 HBRUSH hbrPrintClientClear;
24 HBRUSH hbrErase;
25
26 BOOL bSkipErase;
27 BOOL bSkipPaint;
28
RegisterMyClass(HINSTANCE hInst)29 static void RegisterMyClass(HINSTANCE hInst)
30 {
31 WNDCLASSEXW wcex;
32
33 wcex.cbSize = sizeof(WNDCLASSEX);
34
35 wcex.style = CS_HREDRAW | CS_VREDRAW;
36 wcex.lpfnWndProc = WndProc;
37 wcex.cbClsExtra = 0;
38 wcex.cbWndExtra = 0;
39 wcex.hInstance = hInst;
40 wcex.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
41 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
42 wcex.hbrBackground = NULL;
43 wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_MENU);
44 wcex.lpszClassName = L"ButtonTests";
45 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
46
47 RegisterClassExW(&wcex);
48 }
49
50 #define TOP_MARGIN 50
51 #define LEFT_MARGIN 160
52 #define X_GAP 10
53 #define Y_GAP 10
54 #define Y_HEIGHT 40
55 #define X_WIDTH 150
56
CreateWnd(HWND hWnd,LPCWSTR Class,LPCWSTR Text,LONG style,int i,int j)57 static HWND CreateWnd(HWND hWnd, LPCWSTR Class, LPCWSTR Text, LONG style, int i, int j)
58 {
59 return CreateWindowW(Class,
60 Text,
61 style | WS_CHILD | WS_VISIBLE,
62 LEFT_MARGIN + (X_GAP + X_WIDTH) * i,
63 TOP_MARGIN + ((Y_GAP + Y_HEIGHT) *j),
64 X_WIDTH,
65 Y_HEIGHT,
66 hWnd, NULL, NULL, NULL);
67 }
68
CreateBtn(HWND hWnd,LPCWSTR Text,LONG style,int i,int j)69 static HWND CreateBtn(HWND hWnd, LPCWSTR Text, LONG style, int i, int j)
70 {
71 WCHAR buffer[100];
72 SIZE s;
73
74 HWND ret = CreateWnd(hWnd, L"Button", Text, style, i, j);
75 if (GetWindowLongW(ret, GWL_STYLE) != (style | WS_CHILD | WS_VISIBLE))
76 {
77 swprintf(buffer, L"expected 0x%x got 0x%x", (style | WS_CHILD | WS_VISIBLE), GetWindowLongW(ret, GWL_STYLE));
78 MessageBox(0, buffer, L"error", MB_OK);
79 }
80
81 if (SendMessageW(ret, BCM_GETIDEALSIZE, 0, (LPARAM)&s))
82 {
83 swprintf(buffer, L"%s (%d, %d)", Text, s.cx, s.cy);
84 SendMessageW(ret, WM_SETTEXT, 0, (LPARAM)buffer);
85 }
86 return ret;
87 }
88
CreateButtonSet(HWND hwndParent,HWND * ahwnd,int i,int j,DWORD style)89 static void CreateButtonSet(HWND hwndParent, HWND *ahwnd, int i, int j, DWORD style)
90 {
91 ahwnd[0] = CreateBtn(hwndParent, L"TestButton", style, i, j + 0);
92 ahwnd[1] = CreateBtn(hwndParent, L"TestButton1", style, i, j + 1);
93 ahwnd[2] = CreateBtn(hwndParent, L"TestButton2", style, i, j + 2);
94 ahwnd[3] = CreateBtn(hwndParent, L"TestButton3", style | BS_BITMAP, i, j + 3);
95 ahwnd[4] = CreateBtn(hwndParent, L"TestButton4", style | BS_ICON, i, j + 4);
96
97 SendMessageW(ahwnd[1], BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
98 SendMessageW(ahwnd[2], BM_SETIMAGE, IMAGE_ICON, (LPARAM)hico);
99
100 SendMessageW(ahwnd[3], BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hbmp);
101 SendMessageW(ahwnd[4], BM_SETIMAGE, IMAGE_ICON, (LPARAM)hico);
102 }
103
wWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPWSTR lpCmdLine,_In_ int nCmdShow)104 int WINAPI wWinMain(_In_ HINSTANCE hInstance,
105 _In_opt_ HINSTANCE hPrevInstance,
106 _In_ LPWSTR lpCmdLine,
107 _In_ int nCmdShow)
108 {
109 HWND hwnd[200];
110 HANDLE hActCtx;
111 ULONG_PTR cookie;
112 BOOL bActivated;
113
114 ACTCTXW actctx = { sizeof(actctx) };
115 actctx.hModule = hInstance;
116 actctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID| ACTCTX_FLAG_HMODULE_VALID;
117 actctx.lpResourceName = MAKEINTRESOURCEW(500);
118 hActCtx = CreateActCtxW(&actctx);
119
120 hico = LoadIconW(hInstance, MAKEINTRESOURCEW(IDI_WIN32PROJECT1));
121 hbmp = LoadBitmapW(hInstance, MAKEINTRESOURCEW(IDB_BITMAP1));
122
123 scPos.x = 0;
124 scPos.y = 0;
125
126 hbrNULL = (HBRUSH)GetStockObject (NULL_BRUSH);
127 hbrRed = CreateSolidBrush(0x00000FF);
128 hbrGreen = CreateSolidBrush(0x0000FF00);
129 hbrBlue = CreateSolidBrush(0x00FF0000);
130 hbrCyan = CreateSolidBrush(0x00FFFF00);
131 hbrYellow = CreateSolidBrush(0x0000FFFF);
132
133 hbrCtlColorStatic = hbrRed;
134 hbrCtlColorBtn = hbrCyan;
135 hbrPrintClientClear = hbrYellow;
136 hbrErase = hbrGreen;
137
138 bSkipErase = FALSE;
139 bSkipPaint = FALSE;
140
141 RegisterMyClass(hInstance);
142
143 HWND hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, L"ButtonTests", L"Button tests", WS_OVERLAPPEDWINDOW| WS_HSCROLL| WS_VSCROLL,
144 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
145
146 CreateWnd(hWnd, L"Static", L"no images", 0, -1, 0);
147 CreateWnd(hWnd, L"Static", L"with BM_SETIMAGE", 0, -1, 1);
148 CreateWnd(hWnd, L"Static", L"with BM_SETIMAGE", 0, -1, 2);
149 CreateWnd(hWnd, L"Static", L"with BM_SETIMAGE and BS_BITMAP", 0, -1, 3);
150 CreateWnd(hWnd, L"Static", L"with BM_SETIMAGE and BS_ICON", 0, -1, 4);
151
152 CreateWnd(hWnd, L"Static", L"Button V5", 0, 0, -1);
153 CreateButtonSet(hWnd, &hwnd[0], 0, 0, BS_PUSHBUTTON);
154 CreateButtonSet(hWnd, &hwnd[5], 1, 0, BS_DEFPUSHBUTTON);
155 CreateButtonSet(hWnd, &hwnd[10], 0, 5, BS_PUSHBUTTON|WS_DISABLED);
156 CreateButtonSet(hWnd, &hwnd[15], 1, 5, BS_GROUPBOX);
157 CreateButtonSet(hWnd, &hwnd[20], 0, 10, BS_CHECKBOX);
158 CreateButtonSet(hWnd, &hwnd[25], 1, 10, BS_RADIOBUTTON);
159
160 bActivated = ActivateActCtx(hActCtx, &cookie);
161 LoadLibraryW(L"comctl32.dll");
162
163 himl = ImageList_LoadImageW(hInstance, MAKEINTRESOURCEW(IDB_BITMAP2), 16, 0, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION);
164 BUTTON_IMAGELIST btniml = {himl, {1,1,1,1}, BUTTON_IMAGELIST_ALIGN_LEFT};
165
166 CreateWnd(hWnd, L"Static", L"Button V6 without themes", 0, 2, -1);
167 CreateButtonSet(hWnd, &hwnd[30], 2, 0, BS_PUSHBUTTON);
168 CreateButtonSet(hWnd, &hwnd[35], 3, 0, BS_DEFPUSHBUTTON);
169 CreateButtonSet(hWnd, &hwnd[40], 2, 5, BS_PUSHBUTTON|WS_DISABLED);
170 CreateButtonSet(hWnd, &hwnd[55], 3, 5, BS_GROUPBOX);
171 CreateButtonSet(hWnd, &hwnd[50], 2, 10, BS_CHECKBOX);
172 CreateButtonSet(hWnd, &hwnd[55], 3, 10, BS_RADIOBUTTON);
173
174 CreateWnd(hWnd, L"Static", L"Button V6 with imagelist and no themes", 0, 4, -1);
175 CreateButtonSet(hWnd, &hwnd[60], 4, 0, BS_PUSHBUTTON);
176 CreateButtonSet(hWnd, &hwnd[65], 5, 0, BS_DEFPUSHBUTTON);
177 CreateButtonSet(hWnd, &hwnd[70], 4, 5, BS_PUSHBUTTON|WS_DISABLED);
178 CreateButtonSet(hWnd, &hwnd[75], 5, 5, BS_GROUPBOX);
179 CreateButtonSet(hWnd, &hwnd[80], 4, 10, BS_CHECKBOX);
180 CreateButtonSet(hWnd, &hwnd[85], 5, 10, BS_RADIOBUTTON);
181
182 for (int i = 30; i < 90; i++)
183 SetWindowTheme(hwnd[i], L"", L"");
184
185 for (int i = 60; i< 90; i++)
186 SendMessageW(hwnd[i], BCM_SETIMAGELIST, 0, (LPARAM)&btniml);
187
188 CreateWnd(hWnd, L"Static", L"Button V6 with themes and imagelist", 0, 6, -1);
189 CreateButtonSet(hWnd, &hwnd[120], 6, 0, BS_PUSHBUTTON);
190 CreateButtonSet(hWnd, &hwnd[125], 7, 0, BS_DEFPUSHBUTTON);
191 CreateButtonSet(hWnd, &hwnd[130], 6, 5, BS_PUSHBUTTON|WS_DISABLED);
192 CreateButtonSet(hWnd, &hwnd[135], 7, 5, BS_GROUPBOX);
193 CreateButtonSet(hWnd, &hwnd[140], 6, 10, BS_CHECKBOX);
194 CreateButtonSet(hWnd, &hwnd[145], 7, 10, BS_RADIOBUTTON);
195
196 CreateWnd(hWnd, L"Static", L"Button V6 with themes", 0, 8, -1);
197 CreateButtonSet(hWnd, &hwnd[90], 8, 0, BS_PUSHBUTTON);
198 CreateButtonSet(hWnd, &hwnd[95], 9, 0, BS_DEFPUSHBUTTON);
199 CreateButtonSet(hWnd, &hwnd[100], 8, 5, BS_PUSHBUTTON|WS_DISABLED);
200 CreateButtonSet(hWnd, &hwnd[105], 9, 5, BS_GROUPBOX);
201 CreateButtonSet(hWnd, &hwnd[110], 8, 10, BS_CHECKBOX);
202 CreateButtonSet(hWnd, &hwnd[115], 9, 10, BS_RADIOBUTTON);
203
204 for (int i = 120; i< 150; i++)
205 SendMessageW(hwnd[i], BCM_SETIMAGELIST, 0, (LPARAM)&btniml);
206
207 if (bActivated) DeactivateActCtx(0, cookie);
208
209 SCROLLINFO vsi = {sizeof(SCROLLINFO), SIF_ALL, 0, 2 * TOP_MARGIN + 10 * (Y_GAP + Y_HEIGHT), Y_HEIGHT, 0, 0};
210 SCROLLINFO hsi = {sizeof(SCROLLINFO), SIF_ALL, 0, 2 * LEFT_MARGIN + 13 * (X_GAP + X_WIDTH), X_WIDTH, 0, 0};
211
212 SetScrollInfo(hWnd, SB_HORZ, &hsi, FALSE);
213 SetScrollInfo(hWnd, SB_VERT, &vsi, FALSE);
214
215 ShowScrollBar(hWnd, SB_HORZ, TRUE);
216 ShowScrollBar(hWnd, SB_VERT, TRUE);
217
218 ShowWindow(hWnd, nCmdShow);
219 UpdateWindow(hWnd);
220
221 MSG msg;
222 while (GetMessage(&msg, NULL, 0, 0))
223 {
224 TranslateMessage(&msg);
225 DispatchMessage(&msg);
226 }
227
228 return (int) msg.wParam;
229 }
230
231 static VOID
OnScroll(HWND hwnd,INT nBar,WORD sbCode)232 OnScroll(HWND hwnd, INT nBar, WORD sbCode)
233 {
234 RECT rect;
235
236 SCROLLINFO sInfo;
237 INT oldPos, Maximum;
238 PLONG pOriginXY;
239
240 //ASSERT(nBar == SB_HORZ || nBar == SB_VERT);
241
242 GetClientRect(hwnd, &rect);
243
244 if (nBar == SB_HORZ)
245 {
246 Maximum =1000;//pData->cxMin - (rect.right-rect.left) /* pData->cxOld */;
247 pOriginXY = &scPos.x;
248 }
249 else // if (nBar == SB_VERT)
250 {
251 Maximum = 1000;//pData->cyMin - (rect.bottom-rect.top) /* pData->cyOld */;
252 pOriginXY = &scPos.y;
253 }
254
255 /* Set scrollbar sizes */
256 sInfo.cbSize = sizeof(sInfo);
257 sInfo.fMask = SIF_RANGE | SIF_POS | SIF_PAGE | SIF_TRACKPOS;
258
259 if (!GetScrollInfo(hwnd, nBar, &sInfo))
260 return;
261
262 oldPos = sInfo.nPos;
263
264 switch (sbCode)
265 {
266 case SB_LINEUP: // SB_LINELEFT:
267 sInfo.nPos--;
268 break;
269
270 case SB_LINEDOWN: // SB_LINERIGHT:
271 sInfo.nPos++;
272 break;
273
274 case SB_PAGEUP: // SB_PAGELEFT:
275 sInfo.nPos -= sInfo.nPage;
276 break;
277
278 case SB_PAGEDOWN: // SB_PAGERIGHT:
279 sInfo.nPos += sInfo.nPage;
280 break;
281
282 case SB_THUMBTRACK:
283 sInfo.nPos = sInfo.nTrackPos;
284 break;
285
286 case SB_THUMBPOSITION:
287 sInfo.nPos = sInfo.nTrackPos;
288 break;
289
290 case SB_TOP: // SB_LEFT:
291 sInfo.nPos = sInfo.nMin;
292 break;
293
294 case SB_BOTTOM: // SB_RIGHT:
295 sInfo.nPos = sInfo.nMax;
296 break;
297
298 default:
299 break;
300 }
301
302 sInfo.nPos = min(max(sInfo.nPos, 0), Maximum);
303
304 if (oldPos != sInfo.nPos)
305 {
306 POINT scOldPos = scPos;
307
308 /* We now modify scPos */
309 *pOriginXY = sInfo.nPos;
310
311 ScrollWindowEx(hwnd,
312 (scOldPos.x - scPos.x),
313 (scOldPos.y - scPos.y),
314 NULL,
315 NULL,
316 NULL,
317 NULL,
318 SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN);
319
320 sInfo.fMask = SIF_POS;
321 SetScrollInfo(hwnd, nBar, &sInfo, TRUE);
322 }
323 }
324
WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)325 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
326 {
327 RECT rc = {0,0,5000,5000};
328 switch (message)
329 {
330 case WM_DESTROY:
331 PostQuitMessage(0);
332 break;
333 case WM_CTLCOLORSTATIC:
334 return (LRESULT)hbrCtlColorStatic;
335 case WM_CTLCOLORBTN:
336 return (LRESULT)hbrCtlColorBtn;
337 case WM_ERASEBKGND:
338 FillRect((HDC)wParam, &rc, hbrErase);
339 return TRUE;
340 case WM_PRINTCLIENT:
341 FillRect((HDC)wParam, &rc, hbrPrintClientClear);
342 break;
343 case WM_HSCROLL:
344 OnScroll(hWnd, SB_HORZ, LOWORD(wParam));
345 break;
346 case WM_VSCROLL:
347 OnScroll(hWnd, SB_VERT, LOWORD(wParam));
348 break;
349 case WM_DRAWITEM :
350 {
351 DRAWITEMSTRUCT* di = (DRAWITEMSTRUCT*)lParam;
352 INT oldBkMode;
353 INT state = (di->itemState == ODS_SELECTED) ? DFCS_BUTTONPUSH|DFCS_PUSHED : DFCS_BUTTONPUSH;
354 DrawFrameControl( di->hDC, &di->rcItem, DFC_BUTTON, state );
355 oldBkMode = SetBkMode(di->hDC, TRANSPARENT);
356 DrawTextW(di->hDC, L"Ownder drawn text", -1, &di->rcItem, DT_VCENTER | DT_CENTER);
357 SetBkMode(di->hDC, oldBkMode);
358 break;
359 }
360 case WM_NOTIFY:
361 {
362 NMHDR* phdr = (NMHDR*)lParam;
363 if (phdr->code == NM_CUSTOMDRAW)
364 {
365 LPNMCUSTOMDRAW lpNMCustomDraw = (LPNMCUSTOMDRAW) lParam;
366 if (lpNMCustomDraw->dwDrawStage == CDDS_PREERASE && bSkipErase)
367 return CDRF_SKIPDEFAULT;
368 else if (lpNMCustomDraw->dwDrawStage == CDDS_PREPAINT && bSkipPaint)
369 return CDRF_SKIPDEFAULT;
370 return CDRF_DODEFAULT;
371 }
372 }
373 case WM_COMMAND:
374 {
375 UINT id = LOWORD(wParam);
376 switch(id)
377 {
378 case IDM_NULL_WIN: hbrErase = hbrNULL; break;
379 case IDM_RED_WIN: hbrErase = hbrRed; break;
380 case IDM_GREEN_WIN: hbrErase = hbrGreen; break;
381 case IDM_BLUE_WIN: hbrErase = hbrBlue; break;
382 case IDM_YELLOW_WIN: hbrErase = hbrYellow; break;
383 case IDM_CYAN_WIN: hbrErase = hbrCyan; break;
384
385 case IDM_NULL_STATIC: hbrCtlColorStatic = hbrNULL; break;
386 case IDM_RED_STATIC: hbrCtlColorStatic = hbrRed; break;
387 case IDM_GREEN_STATIC: hbrCtlColorStatic = hbrGreen; break;
388 case IDM_BLUE_STATIC: hbrCtlColorStatic = hbrBlue; break;
389 case IDM_YELLOW_STATIC: hbrCtlColorStatic = hbrYellow; break;
390 case IDM_CYAN_STATIC: hbrCtlColorStatic = hbrCyan; break;
391
392 case IDM_NULL_BTN: hbrCtlColorBtn = hbrNULL; break;
393 case IDM_RED_BTN: hbrCtlColorBtn = hbrRed; break;
394 case IDM_GREEN_BTN: hbrCtlColorBtn = hbrGreen; break;
395 case IDM_BLUE_BTN: hbrCtlColorBtn = hbrBlue; break;
396 case IDM_YELLOW_BTN: hbrCtlColorBtn = hbrYellow; break;
397 case IDM_CYAN_BTN: hbrCtlColorBtn = hbrCyan; break;
398
399 case IDM_NULL_PRINTCLNT: hbrPrintClientClear = hbrNULL; break;
400 case IDM_RED_PRINTCLNT: hbrPrintClientClear = hbrRed; break;
401 case IDM_GREEN_PRINTCLNT: hbrPrintClientClear = hbrGreen; break;
402 case IDM_BLUE_PRINTCLNT: hbrPrintClientClear = hbrBlue; break;
403 case IDM_YELLOW_PRINTCLNT: hbrPrintClientClear = hbrYellow; break;
404 case IDM_CYAN_PRINTCLNT: hbrPrintClientClear = hbrCyan; break;
405
406 case IDM_SKIP_ERASE: bSkipErase = !bSkipErase; break;
407 case IDM_SKIP_PAINT: bSkipPaint = !bSkipPaint; break;
408 default:
409 return 0;
410 }
411
412 InvalidateRect(hWnd, NULL, TRUE);
413 break;
414 }
415 default:
416 return DefWindowProc(hWnd, message, wParam, lParam);
417 }
418 return 0;
419 }
420