shlwapi: Beginning implementation of IUnknown_QueryServiceForWebBrowserApp.
[wine] / dlls / comctl32 / tests / rebar.c
1 /* Unit tests for rebar.
2  *
3  * Copyright 2007 Mikolaj Zalewski
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 /* make sure the structures work with a comctl32 v5.x */
21 #define _WIN32_WINNT 0x500
22 #define _WIN32_IE 0x500
23
24 #include <assert.h>
25 #include <stdarg.h>
26
27 #include <windows.h>
28 #include <commctrl.h>
29 #include <uxtheme.h>
30
31 #include "wine/test.h"
32
33 RECT height_change_notify_rect;
34 static HWND hMainWnd;
35 static HWND hRebar;
36
37
38 #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
39     val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
40     val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
41
42 #define check_rect_no_top(name, val, exp) { \
43         ok((val.bottom - val.top == exp.bottom - exp.top) && \
44             val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \
45             val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \
46     }
47
48 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
49
50 #define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format "  got " format "\n", (value), (ret)); }
51
52 static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
53 {
54     return 0;
55 }
56
57 static BOOL is_font_installed(const char *name)
58 {
59     HDC hdc = GetDC(0);
60     BOOL ret = FALSE;
61
62     if(!EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0))
63         ret = TRUE;
64
65     ReleaseDC(0, hdc);
66     return ret;
67 }
68
69 static void rebuild_rebar(HWND *hRebar)
70 {
71     if (*hRebar)
72         DestroyWindow(*hRebar);
73
74     *hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
75         hMainWnd, (HMENU)17, GetModuleHandle(NULL), NULL);
76     SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
77 }
78
79 static HWND build_toolbar(int nr, HWND hParent)
80 {
81     TBBUTTON btns[8];
82     HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
83         hParent, (HMENU)5, GetModuleHandle(NULL), NULL);
84     int iBitmapId = 0;
85     int i;
86
87     ok(hToolbar != NULL, "Toolbar creation problem\n");
88     ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
89     ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
90     ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
91
92     for (i=0; i<5+nr; i++)
93     {
94         btns[i].iBitmap = i;
95         btns[i].idCommand = i;
96         btns[i].fsStyle = BTNS_BUTTON;
97         btns[i].fsState = TBSTATE_ENABLED;
98         btns[i].iString = 0;
99     }
100
101     switch (nr)
102     {
103         case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
104         case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
105         case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
106     }
107     ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGES failed\n");
108     ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
109     return hToolbar;
110 }
111
112 static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
113 {
114     switch (msg)
115     {
116         case WM_NOTIFY:
117             {
118                 NMHDR *lpnm = (NMHDR *)lParam;
119                 if (lpnm->code == RBN_HEIGHTCHANGE)
120                     GetClientRect(hRebar, &height_change_notify_rect);
121             }
122             break;
123     }
124     return DefWindowProcA(hWnd, msg, wParam, lParam);
125 }
126
127 #if 0  /* use this to generate more tests*/
128
129 static void dump_sizes(HWND hRebar)
130 {
131     SIZE sz;
132     RECT r;
133     int count;
134     int i, h;
135
136     GetClientRect(hRebar, &r);
137     count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
138     printf("  { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
139         SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
140     if (count == 0)
141         printf("0, ");
142     for (i = 0; i < count; i++)  /* rows */
143         printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
144     printf("}, ");
145
146     count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
147     printf("%d, {", count);
148     if (count == 0)
149         printf("{{0, 0, 0, 0}, 0, 0},");
150     for (i=0; i<count; i++)
151     {
152         REBARBANDINFO rbi;
153         rbi.cbSize = REBARBANDINFOA_V6_SIZE;
154         rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
155         ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFO failed\n");
156         ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
157         printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n    " : ""), r.left, r.top, r.right, r.bottom,
158             rbi.fStyle, rbi.cx);
159     }
160     printf("\n  }, },\n");
161 }
162
163 #define check_sizes() dump_sizes(hRebar);
164 #define check_sizes_todo(todomask) dump_sizes(hRebar);
165
166 #else
167
168 typedef struct {
169     RECT rc;
170     DWORD fStyle;
171     INT cx;
172 } rbband_result_t;
173
174 typedef struct {
175     RECT rcClient;
176     int cyBarHeight;
177     int nRows;
178     int cyRowHeights[50];
179     int nBands;
180     rbband_result_t bands[50];
181 } rbsize_result_t;
182
183 rbsize_result_t rbsize_results[] = {
184   { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
185   }, },
186   { {0, 0, 672, 4}, 4, 1, {4, }, 1, {
187     { {  0,   0, 672,   4}, 0x00, 200},
188   }, },
189   { {0, 0, 672, 4}, 4, 1, {4, }, 2, {
190     { {  0,   0, 200,   4}, 0x00, 200}, { {200,   0, 672,   4}, 0x04, 200},
191   }, },
192   { {0, 0, 672, 30}, 30, 1, {30, }, 3, {
193     { {  0,   0, 200,  30}, 0x00, 200}, { {200,   0, 400,  30}, 0x04, 200},
194     { {400,   0, 672,  30}, 0x00, 200},
195   }, },
196   { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
197     { {  0,   0, 200,  34}, 0x00, 200}, { {200,   0, 400,  34}, 0x04, 200},
198     { {400,   0, 604,  34}, 0x00, 200}, { {604,   0, 672,  34}, 0x04, 68},
199   }, },
200   { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
201     { {  0,   0, 200,  34}, 0x00, 200}, { {200,   0, 400,  34}, 0x04, 200},
202     { {400,   0, 604,  34}, 0x00, 200}, { {604,   0, 672,  34}, 0x04, 68},
203   }, },
204   { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
205     { {  0,   0, 200,  34}, 0x00, 200}, { {202,   0, 402,  34}, 0x04, 200},
206     { {404,   0, 604,  34}, 0x00, 200}, { {606,   0, 672,  34}, 0x04, 66},
207   }, },
208   { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
209     { {  0,   0, 142,  34}, 0x00, 200}, { {144,   0, 557,  34}, 0x00, 200},
210     { {559,   0, 672,  34}, 0x04, 200}, { {  0,  36, 200,  70}, 0x00, 200},
211     { {202,  36, 672,  70}, 0x04, 66},
212   }, },
213   { {0, 0, 672, 34}, 34, 1, {34, }, 5, {
214     { {  0,   0, 167,  34}, 0x00, 200}, { {169,   0, 582,  34}, 0x00, 200},
215     { {559,   0, 759,  34}, 0x08, 200}, { {584,   0, 627,  34}, 0x00, 200},
216     { {629,   0, 672,  34}, 0x04, 66},
217   }, },
218   { {0, 0, 672, 34}, 34, 1, {34, }, 4, {
219     { {  0,   0, 167,  34}, 0x00, 200}, { {169,   0, 582,  34}, 0x00, 200},
220     { {584,   0, 627,  34}, 0x00, 200}, { {629,   0, 672,  34}, 0x04, 66},
221   }, },
222   { {0, 0, 672, 34}, 34, 1, {34, }, 3, {
223     { {  0,   0, 413,  34}, 0x00, 200}, { {415,   0, 615,  34}, 0x00, 200},
224     { {617,   0, 672,  34}, 0x04, 66},
225   }, },
226   { {0, 0, 672, 34}, 34, 1, {34, }, 2, {
227     { {  0,   0, 604,  34}, 0x00, 200}, { {606,   0, 672,  34}, 0x04, 66},
228   }, },
229   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
230     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 184,  20}, 0x00, 70},
231     { {184,   0, 424,  20}, 0x00, 240}, { {424,   0, 672,  20}, 0x00, 60},
232     { {  0,  20, 672,  40}, 0x00, 200},
233   }, },
234   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
235     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 227,  20}, 0x00, 113},
236     { {227,   0, 424,  20}, 0x00, 197}, { {424,   0, 672,  20}, 0x00, 60},
237     { {  0,  20, 672,  40}, 0x00, 200},
238   }, },
239   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
240     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 328,  20}, 0x00, 214},
241     { {328,   0, 511,  20}, 0x00, 183}, { {511,   0, 672,  20}, 0x00, 161},
242     { {  0,  20, 672,  40}, 0x00, 200},
243   }, },
244   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
245     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 167,  20}, 0x00, 53},
246     { {167,   0, 511,  20}, 0x00, 344}, { {511,   0, 672,  20}, 0x00, 161},
247     { {  0,  20, 672,  40}, 0x00, 200},
248   }, },
249   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
250     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 328,  20}, 0x00, 214},
251     { {328,   0, 511,  20}, 0x00, 183}, { {511,   0, 672,  20}, 0x00, 161},
252     { {  0,  20, 672,  40}, 0x00, 200},
253   }, },
254   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
255     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 328,  20}, 0x00, 214},
256     { {328,   0, 511,  20}, 0x00, 183}, { {511,   0, 672,  20}, 0x00, 161},
257     { {  0,  20, 672,  40}, 0x00, 200},
258   }, },
259   { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
260     { {  0,   0, 114,  28}, 0x00, 40}, { {114,   0, 328,  28}, 0x00, 214},
261     { {328,   0, 511,  28}, 0x00, 183}, { {511,   0, 672,  28}, 0x00, 161},
262     { {  0,  28, 672,  56}, 0x00, 200},
263   }, },
264   { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
265     { {  0,   0, 114,  20}, 0x00, 40}, { {114,   0, 328,  20}, 0x00, 214},
266     { {328,   0, 511,  20}, 0x00, 183}, { {511,   0, 672,  20}, 0x00, 161},
267     { {  0,  20, 672,  40}, 0x00, 200},
268   }, },
269   { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, {
270     { {  0,   0, 114,  28}, 0x00, 40}, { {114,   0, 328,  28}, 0x00, 214},
271     { {328,   0, 511,  28}, 0x00, 183}, { {511,   0, 672,  28}, 0x00, 161},
272     { {  0,  28, 672,  56}, 0x00, 200},
273   }, },
274   { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
275   }, },
276   { {0, 0, 672, 65}, 65, 1, {65, }, 3, {
277     { {  0,   0,  90,  65}, 0x40, 90}, { { 90,   0, 180,  65}, 0x40, 90},
278     { {180,   0, 672,  65}, 0x40, 90},
279   }, },
280   { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
281   }, },
282   { {0, 0, 65, 226}, 65, 1, {65, }, 1, {
283     { {  0,   0, 226,  65}, 0x40, 90},
284   }, },
285   { {0, 0, 65, 226}, 65, 1, {65, }, 2, {
286     { {  0,   0,  90,  65}, 0x40, 90}, { { 90,   0, 226,  65}, 0x40, 90},
287   }, },
288   { {0, 0, 65, 226}, 65, 1, {65, }, 3, {
289     { {  0,   0,  90,  65}, 0x40, 90}, { { 90,   0, 163,  65}, 0x40, 90},
290     { {163,   0, 226,  65}, 0x40, 90},
291   }, },
292 };
293
294 static int rbsize_numtests = 0;
295
296 #define check_sizes_todo(todomask) { \
297         RECT rc; \
298         REBARBANDINFO rbi; \
299         int count, i/*, mask=(todomask)*/; \
300         rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
301         assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
302         GetClientRect(hRebar, &rc); \
303         check_rect("client", rc, res->rcClient); \
304         count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
305         compare(count, res->nRows, "%d"); \
306         for (i=0; i<min(count, res->nRows); i++) { \
307             int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
308             ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
309         } \
310         count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
311         compare(count, res->nBands, "%d"); \
312         for (i=0; i<min(count, res->nBands); i++) { \
313             ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \
314             if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
315                 check_rect("band", rc, res->bands[i].rc); \
316             rbi.cbSize = REBARBANDINFOA_V6_SIZE; \
317             rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
318             ok(SendMessageA(hRebar, RB_GETBANDINFO,  i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
319             compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
320             compare(rbi.cx, res->bands[i].cx, "%d"); \
321         } \
322         rbsize_numtests++; \
323     }
324
325 #define check_sizes() check_sizes_todo(0)
326
327 #endif
328
329 static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
330 {
331     CHAR buffer[MAX_PATH];
332     REBARBANDINFOA rbi;
333
334     if (lpszText != NULL)
335         strcpy(buffer, lpszText);
336     rbi.cbSize = REBARBANDINFOA_V6_SIZE;
337     rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
338     rbi.cx = cx;
339     rbi.cxMinChild = cxMinChild;
340     rbi.cxIdeal = cxIdeal;
341     rbi.cyMinChild = 20;
342     rbi.hwndChild = build_toolbar(1, hRebar);
343     rbi.lpText = (lpszText ? buffer : NULL);
344     SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
345 }
346
347 static void layout_test(void)
348 {
349     HWND hRebar = NULL;
350     REBARBANDINFO rbi;
351     HIMAGELIST himl;
352     REBARINFO ri;
353
354     rebuild_rebar(&hRebar);
355     check_sizes();
356     rbi.cbSize = REBARBANDINFOA_V6_SIZE;
357     rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
358     rbi.cx = 200;
359     rbi.cxMinChild = 100;
360     rbi.cyMinChild = 30;
361     rbi.hwndChild = NULL;
362     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
363     check_sizes();
364
365     rbi.fMask |= RBBIM_STYLE;
366     rbi.fStyle = RBBS_CHILDEDGE;
367     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
368     check_sizes();
369
370     rbi.fStyle = 0;
371     rbi.cx = 200;
372     rbi.cxMinChild = 30;
373     rbi.cyMinChild = 30;
374     rbi.hwndChild = build_toolbar(0, hRebar);
375     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
376     check_sizes();
377
378     rbi.fStyle = RBBS_CHILDEDGE;
379     rbi.cx = 68;
380     rbi.hwndChild = build_toolbar(0, hRebar);
381     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
382     check_sizes();
383
384     SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
385     check_sizes();      /* a style change won't start a relayout */
386     rbi.fMask = RBBIM_SIZE;
387     rbi.cx = 66;
388     SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
389     check_sizes();      /* here it will be relayouted */
390
391     /* this will force a new row */
392     rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
393     rbi.cx = 200;
394     rbi.cxMinChild = 400;
395     rbi.cyMinChild = 30;
396     rbi.hwndChild = build_toolbar(0, hRebar);
397     SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
398     check_sizes();
399
400     rbi.fMask = RBBIM_STYLE;
401     rbi.fStyle = RBBS_HIDDEN;
402     SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
403     check_sizes();
404
405     SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
406     check_sizes();
407     SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
408     check_sizes();
409     SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
410     check_sizes();
411
412     rebuild_rebar(&hRebar);
413     add_band_w(hRebar, "ABC",     70,  40, 100);
414     add_band_w(hRebar, NULL,      40,  70, 100);
415     add_band_w(hRebar, NULL,     170, 240, 100);
416     add_band_w(hRebar, "MMMMMMM", 60,  60, 100);
417     add_band_w(hRebar, NULL,     200, 200, 100);
418     check_sizes();
419     SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
420     check_sizes();
421     SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
422     check_sizes();
423     SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
424     check_sizes();
425     SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
426     check_sizes();
427     SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
428     check_sizes();
429
430     /* an image will increase the band height */
431     himl = ImageList_LoadImage(LoadLibrary("comctl32"), MAKEINTRESOURCE(121), 24, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
432     ri.cbSize = sizeof(ri);
433     ri.fMask = RBIM_IMAGELIST;
434     ri.himl = himl;
435     ok(SendMessage(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
436     rbi.fMask = RBBIM_IMAGE;
437     rbi.iImage = 1;
438     SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
439     check_sizes();
440
441     /* after removing it everything is back to normal*/
442     rbi.iImage = -1;
443     SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
444     check_sizes();
445
446     /* Only -1 means that the image is not present. Other invalid values increase the height */
447     rbi.iImage = -2;
448     SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
449     check_sizes();
450
451     /* VARHEIGHT resizing test on a horizontal rebar */
452     rebuild_rebar(&hRebar);
453     SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
454     check_sizes();
455     rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
456     rbi.fStyle = RBBS_VARIABLEHEIGHT;
457     rbi.cxMinChild = 50;
458     rbi.cyMinChild = 10;
459     rbi.cyIntegral = 11;
460     rbi.cyChild = 70;
461     rbi.cyMaxChild = 200;
462     rbi.cx = 90;
463     rbi.hwndChild = build_toolbar(0, hRebar);
464     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
465
466     rbi.cyChild = 50;
467     rbi.hwndChild = build_toolbar(0, hRebar);
468     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
469
470     rbi.cyMinChild = 40;
471     rbi.cyChild = 50;
472     rbi.cyIntegral = 5;
473     rbi.hwndChild = build_toolbar(0, hRebar);
474     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
475     check_sizes();
476
477     /* VARHEIGHT resizing on a vertical rebar */
478     rebuild_rebar(&hRebar);
479     SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
480     check_sizes();
481     rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
482     rbi.fStyle = RBBS_VARIABLEHEIGHT;
483     rbi.cxMinChild = 50;
484     rbi.cyMinChild = 10;
485     rbi.cyIntegral = 11;
486     rbi.cyChild = 70;
487     rbi.cyMaxChild = 90;
488     rbi.cx = 90;
489     rbi.hwndChild = build_toolbar(0, hRebar);
490     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
491     check_sizes();
492
493     rbi.cyChild = 50;
494     rbi.hwndChild = build_toolbar(0, hRebar);
495     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
496     check_sizes();
497
498     rbi.cyMinChild = 40;
499     rbi.cyChild = 50;
500     rbi.cyIntegral = 5;
501     rbi.hwndChild = build_toolbar(0, hRebar);
502     SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
503     check_sizes();
504
505     DestroyWindow(hRebar);
506     ImageList_Destroy(himl);
507 }
508
509 #if 0       /* use this to generate more tests */
510
511 static void dump_client(HWND hRebar)
512 {
513     RECT r;
514     BOOL notify;
515     GetWindowRect(hRebar, &r);
516     MapWindowPoints(HWND_DESKTOP, hMainWnd, &r, 2);
517     if (height_change_notify_rect.top != -1)
518     {
519         RECT rcClient;
520         GetClientRect(hRebar, &rcClient);
521         assert(EqualRect(&rcClient, &height_change_notify_rect));
522         notify = TRUE;
523     }
524     else
525         notify = FALSE;
526     printf("    {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
527         notify ? "TRUE" : "FALSE");
528     SetRect(&height_change_notify_rect, -1, -1, -1, -1);
529 }
530
531 #define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
532 #define check_client() dump_client(hRebar)
533
534 #else
535
536 typedef struct {
537     RECT rc;
538     INT iNumRows;
539     BOOL heightNotify;
540 } rbresize_test_result_t;
541
542 rbresize_test_result_t resize_results[] = {
543 /* style 00000001 */
544     {{0, 2, 672, 2}, 0, FALSE},
545     {{0, 2, 672, 22}, 1, TRUE},
546     {{0, 2, 672, 22}, 1, FALSE},
547     {{0, 2, 672, 22}, 1, FALSE},
548     {{0, 2, 672, 22}, 1, FALSE},
549     {{0, 2, 672, 22}, 0, FALSE},
550 /* style 00000041 */
551     {{0, 0, 672, 0}, 0, FALSE},
552     {{0, 0, 672, 20}, 1, TRUE},
553     {{0, 0, 672, 20}, 1, FALSE},
554     {{0, 0, 672, 20}, 1, FALSE},
555     {{0, 0, 672, 20}, 1, FALSE},
556     {{0, 0, 672, 20}, 0, FALSE},
557 /* style 00000003 */
558     {{0, 226, 672, 226}, 0, FALSE},
559     {{0, 206, 672, 226}, 1, TRUE},
560     {{0, 206, 672, 226}, 1, FALSE},
561     {{0, 206, 672, 226}, 1, FALSE},
562     {{0, 206, 672, 226}, 1, FALSE},
563     {{0, 206, 672, 226}, 0, FALSE},
564 /* style 00000043 */
565     {{0, 226, 672, 226}, 0, FALSE},
566     {{0, 206, 672, 226}, 1, TRUE},
567     {{0, 206, 672, 226}, 1, FALSE},
568     {{0, 206, 672, 226}, 1, FALSE},
569     {{0, 206, 672, 226}, 1, FALSE},
570     {{0, 206, 672, 226}, 0, FALSE},
571 /* style 00000080 */
572     {{2, 0, 2, 226}, 0, FALSE},
573     {{2, 0, 22, 226}, 1, TRUE},
574     {{2, 0, 22, 226}, 1, FALSE},
575     {{2, 0, 22, 226}, 1, FALSE},
576     {{2, 0, 22, 226}, 1, FALSE},
577     {{2, 0, 22, 226}, 0, FALSE},
578 /* style 00000083 */
579     {{672, 0, 672, 226}, 0, FALSE},
580     {{652, 0, 672, 226}, 1, TRUE},
581     {{652, 0, 672, 226}, 1, FALSE},
582     {{652, 0, 672, 226}, 1, FALSE},
583     {{652, 0, 672, 226}, 1, FALSE},
584     {{652, 0, 672, 226}, 0, FALSE},
585 /* style 00000008 */
586     {{10, 11, 510, 11}, 0, FALSE},
587     {{10, 15, 510, 35}, 1, TRUE},
588     {{10, 17, 510, 37}, 1, FALSE},
589     {{10, 14, 110, 54}, 2, TRUE},
590     {{0, 4, 0, 44}, 2, FALSE},
591     {{0, 6, 0, 46}, 2, FALSE},
592     {{0, 8, 0, 48}, 2, FALSE},
593     {{0, 12, 0, 32}, 1, TRUE},
594     {{0, 4, 100, 24}, 0, FALSE},
595 /* style 00000048 */
596     {{10, 5, 510, 5}, 0, FALSE},
597     {{10, 5, 510, 25}, 1, TRUE},
598     {{10, 5, 510, 25}, 1, FALSE},
599     {{10, 10, 110, 50}, 2, TRUE},
600     {{0, 0, 0, 40}, 2, FALSE},
601     {{0, 0, 0, 40}, 2, FALSE},
602     {{0, 0, 0, 40}, 2, FALSE},
603     {{0, 0, 0, 20}, 1, TRUE},
604     {{0, 0, 100, 20}, 0, FALSE},
605 /* style 00000004 */
606     {{10, 5, 510, 20}, 0, FALSE},
607     {{10, 5, 510, 20}, 1, TRUE},
608     {{10, 10, 110, 110}, 2, TRUE},
609     {{0, 0, 0, 0}, 2, FALSE},
610     {{0, 0, 0, 0}, 2, FALSE},
611     {{0, 0, 0, 0}, 2, FALSE},
612     {{0, 0, 0, 0}, 1, TRUE},
613     {{0, 0, 100, 100}, 0, FALSE},
614 /* style 00000002 */
615     {{0, 5, 672, 5}, 0, FALSE},
616     {{0, 5, 672, 25}, 1, TRUE},
617     {{0, 10, 672, 30}, 1, FALSE},
618     {{0, 0, 672, 20}, 1, FALSE},
619     {{0, 0, 672, 20}, 1, FALSE},
620     {{0, 0, 672, 20}, 0, FALSE},
621 /* style 00000082 */
622     {{10, 0, 10, 226}, 0, FALSE},
623     {{10, 0, 30, 226}, 1, TRUE},
624     {{10, 0, 30, 226}, 1, FALSE},
625     {{0, 0, 20, 226}, 1, FALSE},
626     {{0, 0, 20, 226}, 1, FALSE},
627     {{0, 0, 20, 226}, 0, FALSE},
628 /* style 00800001 */
629     {{-2, 0, 674, 4}, 0, FALSE},
630     {{-2, 0, 674, 24}, 1, TRUE},
631     {{-2, 0, 674, 24}, 1, FALSE},
632     {{-2, 0, 674, 24}, 1, FALSE},
633     {{-2, 0, 674, 24}, 1, FALSE},
634     {{-2, 0, 674, 24}, 0, FALSE},
635 /* style 00800048 */
636     {{10, 5, 510, 9}, 0, FALSE},
637     {{10, 5, 510, 29}, 1, TRUE},
638     {{10, 5, 510, 29}, 1, FALSE},
639     {{10, 10, 110, 54}, 2, TRUE},
640     {{0, 0, 0, 44}, 2, FALSE},
641     {{0, 0, 0, 44}, 2, FALSE},
642     {{0, 0, 0, 44}, 2, FALSE},
643     {{0, 0, 0, 24}, 1, TRUE},
644     {{0, 0, 100, 24}, 0, FALSE},
645 /* style 00800004 */
646     {{10, 5, 510, 20}, 0, FALSE},
647     {{10, 5, 510, 20}, 1, TRUE},
648     {{10, 10, 110, 110}, 2, TRUE},
649     {{0, 0, 0, 0}, 2, FALSE},
650     {{0, 0, 0, 0}, 2, FALSE},
651     {{0, 0, 0, 0}, 2, FALSE},
652     {{0, 0, 0, 0}, 1, TRUE},
653     {{0, 0, 100, 100}, 0, FALSE},
654 /* style 00800002 */
655     {{-2, 5, 674, 9}, 0, FALSE},
656     {{-2, 5, 674, 29}, 1, TRUE},
657     {{-2, 10, 674, 34}, 1, FALSE},
658     {{-2, 0, 674, 24}, 1, FALSE},
659     {{-2, 0, 674, 24}, 1, FALSE},
660     {{-2, 0, 674, 24}, 0, FALSE},
661 };
662
663 static int resize_numtests = 0;
664
665 #define comment(fmt, arg1)
666 #define check_client() { \
667         RECT r; \
668         rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
669         assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
670         GetWindowRect(hRebar, &r); \
671         MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
672         if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
673             check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
674         } else { \
675             check_rect("client", r, res->rc); \
676         } \
677         expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
678         if (res->heightNotify) { \
679             RECT rcClient; \
680             GetClientRect(hRebar, &rcClient); \
681             check_rect("notify", height_change_notify_rect, rcClient); \
682         } else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
683         SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
684     }
685
686 #endif
687
688 static void resize_test(void)
689 {
690     DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
691         CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
692         CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
693         CCS_NOMOVEY | WS_BORDER};
694
695     const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
696     int i;
697
698     for (i = 0; i < styles_count; i++)
699     {
700         comment("style %08x", dwStyles[i]);
701         SetRect(&height_change_notify_rect, -1, -1, -1, -1);
702         hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
703         check_client();
704         add_band_w(hRebar, NULL, 70, 100, 0);
705         if (dwStyles[i] & CCS_NOPARENTALIGN)  /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
706             check_client();
707         add_band_w(hRebar, NULL, 70, 100, 0);
708         check_client();
709         MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
710         check_client();
711         MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
712         check_client();
713         /* try to fool the rebar by sending invalid width/height - won't work */
714         if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
715         {
716             WINDOWPOS pos;
717             pos.hwnd = hRebar;
718             pos.hwndInsertAfter = NULL;
719             pos.cx = 500;
720             pos.cy = 500;
721             pos.x = 10;
722             pos.y = 10;
723             pos.flags = 0;
724             SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
725             SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
726             check_client();
727             SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
728             check_client();
729         }
730         SendMessage(hRebar, RB_DELETEBAND, 0, 0);
731         check_client();
732         SendMessage(hRebar, RB_DELETEBAND, 0, 0);
733         MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
734         check_client();
735         DestroyWindow(hRebar);
736     }
737 }
738
739 static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
740     COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
741     INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
742     INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
743     INT cxHeader, INT cxHeader_broken)
744 {
745     CHAR buf[MAX_PATH] = "abc";
746     REBARBANDINFOA rb;
747
748     memset(&rb, 0xdd, sizeof(rb));
749     rb.cbSize = REBARBANDINFOA_V6_SIZE;
750     rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
751         | RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
752         | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
753     rb.lpText = buf;
754     rb.cch = MAX_PATH;
755     ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
756     expect_eq(rb.fStyle, fStyle, int, "%x");
757     todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
758     todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
759     expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
760     expect_eq(rb.iImage, iImage, int, "%x");
761     expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
762     expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
763     expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
764     expect_eq(rb.cx, cx, int, "%d");
765     expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
766     expect_eq(rb.wID, wID, int, "%d");
767     /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
768     expect_eq(rb.cyChild, cyChild, int, "%x");
769     expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
770     expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
771     expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
772     expect_eq(rb.lParam, lParam, LPARAM, "%ld");
773     ok( rb.cxHeader == cxHeader || broken(rb.cxHeader == cxHeader_broken),
774         "expected %d for %d\n", cxHeader, rb.cxHeader );
775 }
776
777 static void bandinfo_test(void)
778 {
779     REBARBANDINFOA rb;
780     CHAR szABC[] = "ABC";
781     CHAR szABCD[] = "ABCD";
782
783     rebuild_rebar(&hRebar);
784     rb.cbSize = REBARBANDINFOA_V6_SIZE;
785     rb.fMask = 0;
786     if (!SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb))
787     {
788         win_skip( "V6 info not supported\n" );
789         DestroyWindow(hRebar);
790         return;
791     }
792     expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
793
794     rb.fMask = RBBIM_CHILDSIZE;
795     rb.cxMinChild = 15;
796     rb.cyMinChild = 20;
797     rb.cyChild = 30;
798     rb.cyMaxChild = 20;
799     rb.cyIntegral = 10;
800     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
801     expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
802
803     rb.fMask = RBBIM_TEXT;
804     rb.lpText = szABC;
805     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
806     expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35, -1);
807
808     rb.cbSize = REBARBANDINFOA_V6_SIZE;
809     rb.fMask = 0;
810     ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
811     expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1);
812     expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40, -1);
813
814     rb.fMask = RBBIM_HEADERSIZE;
815     rb.cxHeader = 50;
816     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
817     expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50, -1);
818
819     rb.cxHeader = 5;
820     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
821     expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
822
823     rb.fMask = RBBIM_TEXT;
824     rb.lpText = szABCD;
825     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
826     expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
827     rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
828     rb.fStyle = RBBS_VARIABLEHEIGHT;
829     rb.lpText = szABC;
830     ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
831     expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40, 5);
832
833     DestroyWindow(hRebar);
834 }
835
836 START_TEST(rebar)
837 {
838     HMODULE hComctl32;
839     BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
840     INITCOMMONCONTROLSEX iccex;
841     WNDCLASSA wc;
842     MSG msg;
843     RECT rc;
844
845     /* LoadLibrary is needed. This file has no references to functions in comctl32 */
846     hComctl32 = LoadLibraryA("comctl32.dll");
847     pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
848     if (!pInitCommonControlsEx)
849     {
850         skip("InitCommonControlsEx() is missing. Skipping the tests\n");
851         return;
852     }
853     iccex.dwSize = sizeof(iccex);
854     iccex.dwICC = ICC_COOL_CLASSES;
855     pInitCommonControlsEx(&iccex);
856
857     wc.style = CS_HREDRAW | CS_VREDRAW;
858     wc.cbClsExtra = 0;
859     wc.cbWndExtra = 0;
860     wc.hInstance = GetModuleHandleA(NULL);
861     wc.hIcon = NULL;
862     wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
863     wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
864     wc.lpszMenuName = NULL;
865     wc.lpszClassName = "MyTestWnd";
866     wc.lpfnWndProc = MyWndProc;
867     RegisterClassA(&wc);
868     hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
869       CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
870       226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
871       NULL, NULL, GetModuleHandleA(NULL), 0);
872     GetClientRect(hMainWnd, &rc);
873     ShowWindow(hMainWnd, SW_SHOW);
874
875     bandinfo_test();
876
877     if(is_font_installed("System") && is_font_installed("Tahoma"))
878     {
879         layout_test();
880         resize_test();
881     } else
882         skip("Missing System or Tahoma font\n");
883
884     PostQuitMessage(0);
885     while(GetMessageA(&msg,0,0,0)) {
886         TranslateMessage(&msg);
887         DispatchMessageA(&msg);
888     }
889     DestroyWindow(hMainWnd);
890
891     FreeLibrary(hComctl32);
892 }