~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/comctl32/tests/toolbar.c

Version: ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /* Unit tests for treeview.
  2  *
  3  * Copyright 2005 Krzysztof Foltman
  4  * Copyright 2007 Mikolaj Zalewski
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include <assert.h>
 22 #include <stdarg.h>
 23 
 24 #include "windef.h"
 25 #include "winbase.h"
 26 #include "wingdi.h"
 27 #include "winuser.h"
 28 #include "winnls.h"
 29 #include "winreg.h"
 30 #include "commctrl.h" 
 31 
 32 #include "resources.h"
 33 
 34 #include "wine/test.h"
 35 
 36 static HWND hMainWnd;
 37 static BOOL g_fBlockHotItemChange;
 38 static BOOL g_fReceivedHotItemChange;
 39 static BOOL g_fExpectedHotItemOld;
 40 static BOOL g_fExpectedHotItemNew;
 41 static DWORD g_dwExpectedDispInfoMask;
 42 
 43 #define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
 44 
 45 #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
 46     val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
 47     val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
 48  
 49 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
 50 
 51 static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) {
 52   p->iBitmap = -2;
 53   p->idCommand = idCommand;
 54   p->fsState = TBSTATE_ENABLED;
 55   p->fsStyle = fsStyle;
 56   p->iString = nString;
 57 }
 58 
 59 static LRESULT MyWnd_Notify(LPARAM lParam)
 60 {
 61     NMHDR *hdr = (NMHDR *)lParam;
 62     NMTBHOTITEM *nmhi;
 63     NMTBDISPINFO *nmdisp;
 64     switch (hdr->code)
 65     {
 66         case TBN_HOTITEMCHANGE:
 67             nmhi = (NMTBHOTITEM *)lParam;
 68             g_fReceivedHotItemChange = TRUE;
 69             if (g_fExpectedHotItemOld != g_fExpectedHotItemNew)
 70             {
 71                 compare(nmhi->idOld, g_fExpectedHotItemOld, "%d");
 72                 compare(nmhi->idNew, g_fExpectedHotItemNew, "%d");
 73             }
 74             if (g_fBlockHotItemChange)
 75                 return 1;
 76             break;
 77 
 78         case TBN_GETDISPINFOA:
 79             ok(FALSE, "TBN_GETDISPINFOA received\n");
 80             break;
 81 
 82         case TBN_GETDISPINFOW:
 83             nmdisp = (NMTBDISPINFOA *)lParam;
 84 
 85             compare(nmdisp->dwMask, g_dwExpectedDispInfoMask, "%x");
 86             compare(nmdisp->iImage, -1, "%d");
 87             ok(nmdisp->pszText == NULL, "pszText is not NULL\n");
 88         break;
 89     }
 90     return 0;
 91 }
 92 
 93 static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 94 {
 95     switch (msg)
 96     {
 97         case WM_NOTIFY:
 98             return MyWnd_Notify(lParam);
 99     }
100     return DefWindowProcA(hWnd, msg, wParam, lParam);
101 }
102 
103 static void basic_test(void)
104 {
105     TBBUTTON buttons[9];
106     HWND hToolbar;
107     int i;
108     for (i=0; i<9; i++)
109         MakeButton(buttons+i, 1000+i, TBSTYLE_CHECKGROUP, 0);
110     MakeButton(buttons+3, 1003, TBSTYLE_SEP|TBSTYLE_GROUP, 0);
111     MakeButton(buttons+6, 1006, TBSTYLE_SEP, 0);
112 
113     hToolbar = CreateToolbarEx(hMainWnd,
114         WS_VISIBLE | WS_CLIPCHILDREN | CCS_TOP |
115         WS_CHILD | TBSTYLE_LIST,
116         100,
117         0, NULL, (UINT)0,
118         buttons, sizeof(buttons)/sizeof(buttons[0]),
119         0, 0, 20, 16, sizeof(TBBUTTON));
120     ok(hToolbar != NULL, "Toolbar creation\n");
121     SendMessage(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000");
122 
123     /* test for exclusion working inside a separator-separated :-) group */
124     SendMessage(hToolbar, TB_CHECKBUTTON, 1000, 1); /* press A1 */
125     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
126     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1001, 0), "A2 not pressed\n");
127 
128     SendMessage(hToolbar, TB_CHECKBUTTON, 1004, 1); /* press A5, release A1 */
129     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1004, 0), "A5 pressed\n");
130     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 not pressed anymore\n");
131 
132     SendMessage(hToolbar, TB_CHECKBUTTON, 1005, 1); /* press A6, release A5 */
133     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 pressed\n");
134     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1004, 0), "A5 not pressed anymore\n");
135 
136     /* test for inter-group crosstalk, ie. two radio groups interfering with each other */
137     SendMessage(hToolbar, TB_CHECKBUTTON, 1007, 1); /* press B2 */
138     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 still pressed, no inter-group crosstalk\n");
139     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 still not pressed\n");
140     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 pressed\n");
141 
142     SendMessage(hToolbar, TB_CHECKBUTTON, 1000, 1); /* press A1 and ensure B group didn't suffer */
143     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 not pressed anymore\n");
144     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
145     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 still pressed\n");
146 
147     SendMessage(hToolbar, TB_CHECKBUTTON, 1008, 1); /* press B3, and ensure A group didn't suffer */
148     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 pressed\n");
149     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
150     ok(!SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 not pressed\n");
151     ok(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 1008, 0), "B3 pressed\n");
152 
153     /* tests with invalid index */
154     compare(SendMessage(hToolbar, TB_ISBUTTONCHECKED, 0xdeadbeef, 0), -1L, "%ld");
155     compare(SendMessage(hToolbar, TB_ISBUTTONPRESSED, 0xdeadbeef, 0), -1L, "%ld");
156     compare(SendMessage(hToolbar, TB_ISBUTTONENABLED, 0xdeadbeef, 0), -1L, "%ld");
157     compare(SendMessage(hToolbar, TB_ISBUTTONINDETERMINATE, 0xdeadbeef, 0), -1L, "%ld");
158     compare(SendMessage(hToolbar, TB_ISBUTTONHIGHLIGHTED, 0xdeadbeef, 0), -1L, "%ld");
159     compare(SendMessage(hToolbar, TB_ISBUTTONHIDDEN, 0xdeadbeef, 0), -1L, "%ld");
160 
161     DestroyWindow(hToolbar);
162 }
163 
164 static void rebuild_toolbar(HWND *hToolbar)
165 {
166     if (*hToolbar != NULL)
167         DestroyWindow(*hToolbar);
168     *hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
169         hMainWnd, (HMENU)5, GetModuleHandle(NULL), NULL);
170     ok(*hToolbar != NULL, "Toolbar creation problem\n");
171     ok(SendMessage(*hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
172     ok(SendMessage(*hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
173     ok(SendMessage(*hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
174 }
175 
176 static void rebuild_toolbar_with_buttons(HWND *hToolbar)
177 {
178     TBBUTTON buttons[5];
179     rebuild_toolbar(hToolbar);
180     
181     ZeroMemory(&buttons, sizeof(buttons));
182     buttons[0].idCommand = 1;
183     buttons[0].fsStyle = BTNS_BUTTON;
184     buttons[0].fsState = TBSTATE_ENABLED;
185     buttons[0].iString = -1;
186     buttons[1].idCommand = 3;
187     buttons[1].fsStyle = BTNS_BUTTON;
188     buttons[1].fsState = TBSTATE_ENABLED;
189     buttons[1].iString = -1;
190     buttons[2].idCommand = 5;
191     buttons[2].fsStyle = BTNS_SEP;
192     buttons[2].fsState = TBSTATE_ENABLED;
193     buttons[2].iString = -1;
194     buttons[3].idCommand = 7;
195     buttons[3].fsStyle = BTNS_BUTTON;
196     buttons[3].fsState = TBSTATE_ENABLED;
197     buttons[3].iString = -1;
198     buttons[4].idCommand = 9;
199     buttons[4].fsStyle = BTNS_BUTTON;
200     buttons[4].fsState = 0;  /* disabled */
201     buttons[4].iString = -1;
202     ok(SendMessage(*hToolbar, TB_ADDBUTTONS, 5, (LPARAM)buttons) == 1, "TB_ADDBUTTONS failed\n");
203     ok(SendMessage(*hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
204 }
205 
206 static void add_128x15_bitmap(HWND hToolbar, int nCmds)
207 {
208     TBADDBITMAP bmp128;
209     bmp128.hInst = GetModuleHandle(NULL);
210     bmp128.nID = IDB_BITMAP_128x15;
211     ok(SendMessageA(hToolbar, TB_ADDBITMAP, nCmds, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
212 }
213 
214 #define CHECK_IMAGELIST(count, dx, dy) { \
215     int cx, cy; \
216     HIMAGELIST himl = (HIMAGELIST)SendMessageA(hToolbar, TB_GETIMAGELIST, 0, 0); \
217     ok(himl != NULL, "No image list\n"); \
218     if (himl != NULL) {\
219         ok(ImageList_GetImageCount(himl) == count, "Images count mismatch - %d vs %d\n", count, ImageList_GetImageCount(himl)); \
220         ImageList_GetIconSize(himl, &cx, &cy); \
221         ok(cx == dx && cy == dy, "Icon size mismatch - %dx%d vs %dx%d\n", dx, dy, cx, cy); \
222     } \
223 }
224 
225 static void test_add_bitmap(void)
226 {
227     HWND hToolbar = NULL;
228     TBADDBITMAP bmp128;
229     TBADDBITMAP bmp80;
230     TBADDBITMAP stdsmall;
231     TBADDBITMAP addbmp;
232     HIMAGELIST himl;
233     INT ret;
234 
235     /* empty 128x15 bitmap */
236     bmp128.hInst = GetModuleHandle(NULL);
237     bmp128.nID = IDB_BITMAP_128x15;
238 
239     /* empty 80x15 bitmap */
240     bmp80.hInst = GetModuleHandle(NULL);
241     bmp80.nID = IDB_BITMAP_80x15;
242 
243     /* standard bitmap - 240x15 pixels */
244     stdsmall.hInst = HINST_COMMCTRL;
245     stdsmall.nID = IDB_STD_SMALL_COLOR;
246 
247     rebuild_toolbar(&hToolbar);
248     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 8, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
249     CHECK_IMAGELIST(8, 16, 16);
250     
251     /* adding more bitmaps */
252     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80) == 8, "TB_ADDBITMAP - unexpected return\n");
253     CHECK_IMAGELIST(13, 16, 16);
254     /* adding the same bitmap will simply return the index of the already loaded block */
255     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 8, (LPARAM)&bmp128);
256     ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
257     CHECK_IMAGELIST(13, 16, 16);
258     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80);
259     ok(ret == 8, "TB_ADDBITMAP - unexpected return %d\n", ret);
260     CHECK_IMAGELIST(13, 16, 16);
261     /* even if we increase the wParam */
262     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 55, (LPARAM)&bmp80);
263     ok(ret == 8, "TB_ADDBITMAP - unexpected return %d\n", ret);
264     CHECK_IMAGELIST(13, 16, 16);
265 
266     /* when the wParam is smaller than the bitmaps count but non-zero, all the bitmaps will be added*/
267     rebuild_toolbar(&hToolbar);
268     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 3, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
269     CHECK_IMAGELIST(8, 16, 16);
270     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80);
271     ok(ret == 3, "TB_ADDBITMAP - unexpected return %d\n", ret);
272     /* the returned value is misleading - id 8 is the id of the first icon from bmp80 */
273     CHECK_IMAGELIST(13, 16, 16);
274 
275     /* the same for negative wParam */
276     rebuild_toolbar(&hToolbar);
277     ret = SendMessageA(hToolbar, TB_ADDBITMAP, -143, (LPARAM)&bmp128);
278     ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
279     CHECK_IMAGELIST(8, 16, 16);
280     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp80);
281     ok(ret == -143, "TB_ADDBITMAP - unexpected return %d\n", ret);
282     CHECK_IMAGELIST(13, 16, 16);
283 
284     /* for zero only one bitmap will be added */
285     rebuild_toolbar(&hToolbar);
286     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&bmp80);
287     ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
288     CHECK_IMAGELIST(1, 16, 16);
289 
290     /* if wParam is larger than the amount of icons, the list is grown */
291     rebuild_toolbar(&hToolbar);
292     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp80) == 0, "TB_ADDBITMAP - unexpected return\n");
293     CHECK_IMAGELIST(100, 16, 16);
294     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp128);
295     ok(ret == 100, "TB_ADDBITMAP - unexpected return %d\n", ret);
296     CHECK_IMAGELIST(200, 16, 16);
297 
298     /* adding built-in items - the wParam is ignored */
299     rebuild_toolbar(&hToolbar);
300     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80) == 0, "TB_ADDBITMAP - unexpected return\n");
301     CHECK_IMAGELIST(5, 16, 16);
302     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&stdsmall) == 5, "TB_ADDBITMAP - unexpected return\n");
303     CHECK_IMAGELIST(20, 16, 16);
304     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp128) == 20, "TB_ADDBITMAP - unexpected return\n");
305     CHECK_IMAGELIST(28, 16, 16);
306 
307     /* when we increase the bitmap size, less icons will be created */
308     rebuild_toolbar(&hToolbar);
309     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(20, 20)) == TRUE, "TB_SETBITMAPSIZE failed\n");
310     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
311     CHECK_IMAGELIST(6, 20, 20);
312     ret = SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp80);
313     ok(ret == 1, "TB_ADDBITMAP - unexpected return %d\n", ret);
314     CHECK_IMAGELIST(10, 20, 20);
315     /* the icons can be resized - an UpdateWindow is needed as this probably happens during WM_PAINT */
316     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
317     UpdateWindow(hToolbar);
318     CHECK_IMAGELIST(26, 8, 8);
319     /* loading a standard bitmaps automatically resizes the icons */
320     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&stdsmall) == 2, "TB_ADDBITMAP - unexpected return\n");
321     UpdateWindow(hToolbar);
322     CHECK_IMAGELIST(28, 16, 16);
323 
324     /* two more SETBITMAPSIZE tests */
325     rebuild_toolbar(&hToolbar);
326     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
327     CHECK_IMAGELIST(100, 16, 16);
328     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp80) == 100, "TB_ADDBITMAP - unexpected return\n");
329     CHECK_IMAGELIST(200, 16, 16);
330     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
331     UpdateWindow(hToolbar);
332     CHECK_IMAGELIST(200, 8, 8);
333     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
334     UpdateWindow(hToolbar);
335     CHECK_IMAGELIST(200, 30, 30);
336     rebuild_toolbar(&hToolbar);
337     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
338     CHECK_IMAGELIST(8, 16, 16);
339     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 3, (LPARAM)&bmp80) == 5, "TB_ADDBITMAP - unexpected return\n");
340     CHECK_IMAGELIST(13, 16, 16);
341     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
342     UpdateWindow(hToolbar);
343     CHECK_IMAGELIST(8, 30, 30);
344     /* when the width or height is zero, set it to 1 */
345     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(0, 0)) == TRUE, "TB_SETBITMAPSIZE failed\n");
346     UpdateWindow(hToolbar);
347     CHECK_IMAGELIST(208, 1, 1);
348     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(0, 5)) == TRUE, "TB_SETBITMAPSIZE failed\n");
349     UpdateWindow(hToolbar);
350     CHECK_IMAGELIST(208, 1, 5);
351     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(5, 0)) == TRUE, "TB_SETBITMAPSIZE failed\n");
352     UpdateWindow(hToolbar);
353     CHECK_IMAGELIST(41, 5, 1);
354 
355     /* the control can add bitmaps to an existing image list */
356     rebuild_toolbar(&hToolbar);
357     himl = ImageList_LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP_80x15), 20, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
358     ok(himl != NULL, "failed to create imagelist\n");
359     ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
360     CHECK_IMAGELIST(4, 20, 15);
361     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
362     CHECK_IMAGELIST(10, 20, 15);
363     /* however TB_SETBITMAPSIZE/add std bitmap won't change the image size (the button size does change) */
364     ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
365     UpdateWindow(hToolbar);
366     compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(15, 14), "%x");
367     CHECK_IMAGELIST(10, 20, 15);
368     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&stdsmall) == 1, "TB_SETBITMAPSIZE failed\n");
369     UpdateWindow(hToolbar);
370     compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x");
371     CHECK_IMAGELIST(22, 20, 15);
372 
373     /* check standard bitmaps */
374     addbmp.hInst = HINST_COMMCTRL;
375     addbmp.nID = IDB_STD_SMALL_COLOR;
376     rebuild_toolbar(&hToolbar);
377     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
378     CHECK_IMAGELIST(15, 16, 16);
379     compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x");
380     addbmp.nID = IDB_STD_LARGE_COLOR;
381     rebuild_toolbar(&hToolbar);
382     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
383     CHECK_IMAGELIST(15, 24, 24);
384     compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(31, 30), "%x");
385 
386     addbmp.nID = IDB_VIEW_SMALL_COLOR;
387     rebuild_toolbar(&hToolbar);
388     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
389     CHECK_IMAGELIST(12, 16, 16);
390     addbmp.nID = IDB_VIEW_LARGE_COLOR;
391     rebuild_toolbar(&hToolbar);
392     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
393     CHECK_IMAGELIST(12, 24, 24);
394 
395     addbmp.nID = IDB_HIST_SMALL_COLOR;
396     rebuild_toolbar(&hToolbar);
397     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
398     CHECK_IMAGELIST(5, 16, 16);
399     addbmp.nID = IDB_HIST_LARGE_COLOR;
400     rebuild_toolbar(&hToolbar);
401     ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
402     CHECK_IMAGELIST(5, 24, 24);
403 
404 
405     DestroyWindow(hToolbar);
406 }
407 
408 #define CHECK_STRING_TABLE(count, tab) { \
409         INT _i; \
410         CHAR _buf[260]; \
411         for (_i = 0; _i < (count); _i++) {\
412             ret = SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, _i), (LPARAM)_buf); \
413             ok(ret >= 0, "TB_GETSTRING - unexpected return %d while checking string %d\n", ret, _i); \
414             if (ret >= 0) \
415                 ok(strcmp(_buf, (tab)[_i]) == 0, "Invalid string #%d - '%s' vs '%s'\n", _i, (tab)[_i], _buf); \
416         } \
417         ok(SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, (count)), (LPARAM)_buf) == -1, \
418             "Too many string in table\n"); \
419     }
420 
421 static void test_add_string(void)
422 {
423     LPCSTR test1 = "a\0b\0";
424     LPCSTR test2 = "|a|b||\0";
425     LPCSTR ret1[] = {"a", "b"};
426     LPCSTR ret2[] = {"a", "b", "|a|b||"};
427     LPCSTR ret3[] = {"a", "b", "|a|b||", "p", "q"};
428     LPCSTR ret4[] = {"a", "b", "|a|b||", "p", "q", "p"};
429     LPCSTR ret5[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q"};
430     LPCSTR ret6[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q"};
431     LPCSTR ret7[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q", "br", "c", "d"};
432     HWND hToolbar = NULL;
433     TBBUTTON button;
434     int ret;
435 
436     rebuild_toolbar(&hToolbar);
437     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test1);
438     ok(ret == 0, "TB_ADDSTRINGA - unexpected return %d\n", ret);
439     CHECK_STRING_TABLE(2, ret1);
440     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test2);
441     ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret);
442     CHECK_STRING_TABLE(3, ret2);
443 
444     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD1);
445     ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret);
446     CHECK_STRING_TABLE(3, ret2);
447     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD2);
448     ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret);
449     CHECK_STRING_TABLE(5, ret3);
450     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD3);
451     ok(ret == 5, "TB_ADDSTRINGA - unexpected return %d\n", ret);
452     CHECK_STRING_TABLE(6, ret4);
453     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD4);
454     ok(ret == 6, "TB_ADDSTRINGA - unexpected return %d\n", ret);
455     CHECK_STRING_TABLE(8, ret5);
456     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD5);
457     ok(ret == 8, "TB_ADDSTRINGA - unexpected return %d\n", ret);
458     CHECK_STRING_TABLE(11, ret6);
459     ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD7);
460     ok(ret == 11, "TB_ADDSTRINGA - unexpected return %d\n", ret);
461     CHECK_STRING_TABLE(14, ret7);
462 
463     ZeroMemory(&button, sizeof(button));
464     button.iString = (UINT_PTR)"Test";
465     SendMessageA(hToolbar, TB_INSERTBUTTONA, 0, (LPARAM)&button);
466     CHECK_STRING_TABLE(14, ret7);
467     SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&button);
468     CHECK_STRING_TABLE(14, ret7);
469 
470     DestroyWindow(hToolbar);
471 }
472 
473 static void expect_hot_notify(int idold, int idnew)
474 {
475     g_fExpectedHotItemOld = idold;
476     g_fExpectedHotItemNew = idnew;
477     g_fReceivedHotItemChange = FALSE;
478 }
479 
480 #define check_hot_notify() \
481     ok(g_fReceivedHotItemChange, "TBN_HOTITEMCHANGE not received\n"); \
482     g_fExpectedHotItemOld = g_fExpectedHotItemNew = 0;
483 
484 static void test_hotitem(void)
485 {
486     HWND hToolbar = NULL;
487     TBBUTTONINFO tbinfo;
488     LRESULT ret;
489 
490     g_fBlockHotItemChange = FALSE;
491 
492     rebuild_toolbar_with_buttons(&hToolbar);
493     /* set TBSTYLE_FLAT. comctl5 allows hot items only for such toolbars.
494      * comctl6 doesn't have this requirement even when theme == NULL */
495     SetWindowLong(hToolbar, GWL_STYLE, TBSTYLE_FLAT | GetWindowLong(hToolbar, GWL_STYLE));
496     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
497     ok(ret == -1, "Hot item: %ld, expected -1\n", ret);
498     ret = SendMessage(hToolbar, TB_SETHOTITEM, 1, 0);
499     ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
500     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
501     ok(ret == 1, "Hot item: %ld, expected 1\n", ret);
502     ret = SendMessage(hToolbar, TB_SETHOTITEM, 2, 0);
503     ok(ret == 1, "TB_SETHOTITEM returned %ld, expected 1\n", ret);
504 
505     ret = SendMessage(hToolbar, TB_SETHOTITEM, 0xbeef, 0);
506     ok(ret == 2, "TB_SETHOTITEM returned %ld, expected 2\n", ret);
507     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
508     ok(ret == 2, "Hot item: %lx, expected 2\n", ret);
509     ret = SendMessage(hToolbar, TB_SETHOTITEM, -0xbeef, 0);
510     ok(ret == 2, "TB_SETHOTITEM returned %ld, expected 2\n", ret);
511     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
512     ok(ret == -1, "Hot item: %lx, expected -1\n", ret);
513 
514     expect_hot_notify(0, 7);
515     ret = SendMessage(hToolbar, TB_SETHOTITEM, 3, 0);
516     ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
517     check_hot_notify();
518     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
519     ok(ret == 3, "Hot item: %lx, expected 3\n", ret);
520     g_fBlockHotItemChange = TRUE;
521     ret = SendMessage(hToolbar, TB_SETHOTITEM, 2, 0);
522     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 2\n", ret);
523     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
524     ok(ret == 3, "Hot item: %lx, expected 3\n", ret);
525     g_fBlockHotItemChange = FALSE;
526 
527     g_fReceivedHotItemChange = FALSE;
528     ret = SendMessage(hToolbar, TB_SETHOTITEM, 0xbeaf, 0);
529     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
530     ok(g_fReceivedHotItemChange == FALSE, "TBN_HOTITEMCHANGE received for invalid parameter\n");
531 
532     g_fReceivedHotItemChange = FALSE;
533     ret = SendMessage(hToolbar, TB_SETHOTITEM, 3, 0);
534     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
535     ok(g_fReceivedHotItemChange == FALSE, "TBN_HOTITEMCHANGE received after a duplication\n");
536 
537     expect_hot_notify(7, 0);
538     ret = SendMessage(hToolbar, TB_SETHOTITEM, -0xbeaf, 0);
539     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
540     check_hot_notify();
541     SendMessage(hToolbar, TB_SETHOTITEM, 3, 0);
542 
543     /* setting disabled buttons will generate a notify with the button id but no button will be hot */
544     expect_hot_notify(7, 9);
545     ret = SendMessage(hToolbar, TB_SETHOTITEM, 4, 0);
546     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
547     check_hot_notify();
548     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
549     ok(ret == -1, "Hot item: %lx, expected -1\n", ret);
550     /* enabling the button won't change that */
551     SendMessage(hToolbar, TB_ENABLEBUTTON, 9, TRUE);
552     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
553     ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
554 
555     /* disabling a hot button works */
556     ret = SendMessage(hToolbar, TB_SETHOTITEM, 3, 0);
557     ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
558     g_fReceivedHotItemChange = FALSE;
559     SendMessage(hToolbar, TB_ENABLEBUTTON, 7, FALSE);
560     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
561     ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
562     ok(g_fReceivedHotItemChange == FALSE, "Unexpected TBN_HOTITEMCHANGE\n");
563 
564     SendMessage(hToolbar, TB_SETHOTITEM, 1, 0);
565     tbinfo.cbSize = sizeof(TBBUTTONINFO);
566     tbinfo.dwMask = TBIF_STATE;
567     tbinfo.fsState = 0;  /* disabled */
568     g_fReceivedHotItemChange = FALSE;
569     ok(SendMessage(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&tbinfo) == TRUE, "TB_SETBUTTONINFO failed\n");
570     ret = SendMessage(hToolbar, TB_GETHOTITEM, 0, 0);
571     ok(ret == 1, "TB_SETHOTITEM returned %ld, expected 1\n", ret);
572     ok(g_fReceivedHotItemChange == FALSE, "Unexpected TBN_HOTITEMCHANGE\n");
573 
574     DestroyWindow(hToolbar);
575 }
576 
577 #if 0  /* use this to generate more tests*/
578 
579 static void dump_sizes(HWND hToolbar)
580 {
581     SIZE sz;
582     RECT r;
583     int count = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0);
584     int i;
585 
586     GetClientRect(hToolbar, &r);
587     SendMessageA(hToolbar, TB_GETMAXSIZE, 0, &sz);
588     printf("  { {%d, %d, %d, %d}, {%d, %d}, %d, {", r.left, r.top, r.right, r.bottom,
589         sz.cx, sz.cy, count);
590     for (i=0; i<count; i++)
591     {
592         SendMessageA(hToolbar, TB_GETITEMRECT, i, &r);
593         printf("%s{%3d, %3d, %3d, %3d}, ", (i%3==0 ? "\n    " : ""), r.left, r.top, r.right, r.bottom);
594     }
595     printf("\n  }, }, \n");
596 }
597 
598 #define check_sizes() dump_sizes(hToolbar);
599 #define check_sizes_todo(todomask) dump_sizes(hToolbar);
600 
601 #else
602 
603 typedef struct
604 {
605     RECT rcClient;
606     SIZE szMin;
607     INT nButtons;
608     RECT rcButtons[100];
609 } tbsize_result_t;
610 
611 static tbsize_result_t tbsize_results[] =
612 {
613   { {0, 0, 672, 26}, {100, 22}, 5, {
614     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
615     { 54,   2,  77,  24}, { 77,   2, 100,  24},
616   }, },
617   { {0, 0, 672, 26}, {146, 22}, 7, {
618     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
619     { 54,   2,  77,  24}, { 77,   2, 100,  24}, {100,   2, 123,  24},
620     {  0,  24,  23,  46},
621   }, },
622   { {0, 0, 672, 48}, {146, 22}, 7, {
623     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
624     { 54,   2,  77,  24}, { 77,   2, 100,  24}, {100,   2, 123,  24},
625     {  0,  24,  23,  46},
626   }, },
627   { {0, 0, 672, 26}, {146, 22}, 7, {
628     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
629     { 54,   2,  77,  24}, { 77,   2, 100,  24}, {100,   2, 123,  24},
630     {123,   2, 146,  24},
631   }, },
632   { {0, 0, 672, 26}, {192, 22}, 9, {
633     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
634     { 54,   2,  77,  24}, { 77,   2, 100,  24}, {100,   2, 123,  24},
635     {123,   2, 146,  24}, {146,   2, 169,  24}, {169,   2, 192,  24},
636   }, },
637   { {0, 0, 672, 92}, {882, 22}, 39, {
638     {  0,   2,  23,  24}, { 23,   2,  46,  24}, {  0,   2,   8,  29},
639     {  0,  29,  23,  51}, { 23,  29,  46,  51}, { 46,  29,  69,  51},
640     { 69,  29,  92,  51}, { 92,  29, 115,  51}, {115,  29, 138,  51},
641     {138,  29, 161,  51}, {161,  29, 184,  51}, {184,  29, 207,  51},
642     {207,  29, 230,  51}, {230,  29, 253,  51}, {253,  29, 276,  51},
643     {276,  29, 299,  51}, {299,  29, 322,  51}, {322,  29, 345,  51},
644     {345,  29, 368,  51}, {368,  29, 391,  51}, {391,  29, 414,  51},
645     {414,  29, 437,  51}, {437,  29, 460,  51}, {460,  29, 483,  51},
646     {483,  29, 506,  51}, {506,  29, 529,  51}, {529,  29, 552,  51},
647     {552,  29, 575,  51}, {575,  29, 598,  51}, {598,  29, 621,  51},
648     {621,  29, 644,  51}, {644,  29, 667,  51}, {  0,  51,  23,  73},
649     { 23,  51,  46,  73}, { 46,  51,  69,  73}, { 69,  51,  92,  73},
650     { 92,  51, 115,  73}, {115,  51, 138,  73}, {138,  51, 161,  73},
651   }, },
652   { {0, 0, 48, 226}, {23, 140}, 7, {
653     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  94,  24},
654     { 94,   2, 117,  24}, {117,   2, 140,  24}, {140,   2, 163,  24},
655     {  0,  24,  23,  46},
656   }, },
657   { {0, 0, 92, 226}, {23, 140}, 7, {
658     {  0,   2,  23,  24}, { 23,   2,  46,  24}, {  0,  24,  92,  32},
659     {  0,  32,  23,  54}, { 23,  32,  46,  54}, { 46,  32,  69,  54},
660     { 69,  32,  92,  54},
661   }, },
662   { {0, 0, 672, 26}, {194, 30}, 7, {
663     {  0,   2,  31,  32}, { 31,   2,  62,  32}, { 62,   2,  70,  32},
664     { 70,   2, 101,  32}, {101,   2, 132,  32}, {132,   2, 163,  32},
665     {  0,  32,  31,  62},
666   }, },
667   { {0, 0, 672, 64}, {194, 30}, 7, {
668     {  0,   2,  31,  32}, { 31,   2,  62,  32}, { 62,   2,  70,  32},
669     { 70,   2, 101,  32}, {101,   2, 132,  32}, {132,   2, 163,  32},
670     {  0,  32,  31,  62},
671   }, },
672   { {0, 0, 672, 64}, {194, 30}, 7, {
673     {  0,   0,  31,  30}, { 31,   0,  62,  30}, { 62,   0,  70,  30},
674     { 70,   0, 101,  30}, {101,   0, 132,  30}, {132,   0, 163,  30},
675     {  0,  30,  31,  60},
676   }, },
677   { {0, 0, 124, 226}, {31, 188}, 7, {
678     {  0,   0,  31,  30}, { 31,   0,  62,  30}, {  0,  30, 124,  38},
679     {  0,  38,  31,  68}, { 31,  38,  62,  68}, { 62,  38,  93,  68},
680     { 93,  38, 124,  68},
681   }, },
682   { {0, 0, 672, 26}, {146, 22}, 7, {
683     {  0,   2,  23,  24}, { 23,   2,  46,  24}, { 46,   2,  54,  24},
684     { 54,   2,  77,  24}, { 77,   2, 100,  24}, {100,   2, 123,  24},
685     {123,   2, 146,  24},
686   }, },
687   { {0, 0, 672, 26}, {146, 100}, 7, {
688     {  0,   0,  23, 100}, { 23,   0,  46, 100}, { 46,   0,  54, 100},
689     { 54,   0,  77, 100}, { 77,   0, 100, 100}, {100,   0, 123, 100},
690     {123,   0, 146, 100},
691   }, },
692   { {0, 0, 672, 26}, {215, 100}, 10, {
693     {  0,   0,  23, 100}, { 23,   0,  46, 100}, { 46,   0,  54, 100},
694     { 54,   0,  77, 100}, { 77,   0, 100, 100}, {100,   0, 123, 100},
695     {123,   0, 146, 100}, {146,   0, 169, 100}, {169,   0, 192, 100},
696     {192,   0, 215, 100},
697   }, },
698   { {0, 0, 672, 26}, {238, 39}, 11, {
699     {  0,   0,  23,  39}, { 23,   0,  46,  39}, { 46,   0,  54,  39},
700     { 54,   0,  77,  39}, { 77,   0, 100,  39}, {100,   0, 123,  39},
701     {123,   0, 146,  39}, {146,   0, 169,  39}, {169,   0, 192,  39},
702     {192,   0, 215,  39}, {215,   0, 238,  39},
703   }, },
704   { {0, 0, 672, 26}, {238, 22}, 11, {
705     {  0,   0,  23,  22}, { 23,   0,  46,  22}, { 46,   0,  54,  22},
706     { 54,   0,  77,  22}, { 77,   0, 100,  22}, {100,   0, 123,  22},
707     {123,   0, 146,  22}, {146,   0, 169,  22}, {169,   0, 192,  22},
708     {192,   0, 215,  22}, {215,   0, 238,  22},
709   }, },
710   { {0, 0, 672, 26}, {489, 39}, 3, {
711     {  0,   2, 163,  41}, {163,   2, 330,  41}, {330,   2, 493,  41},
712   }, },
713   { {0, 0, 672, 104}, {978, 24}, 6, {
714     {  0,   2, 163,  26}, {163,   2, 326,  26}, {326,   2, 489,  26},
715     {489,   2, 652,  26}, {652,   2, 819,  26}, {819,   2, 850,  26},
716   }, },
717   { {0, 0, 672, 28}, {978, 38}, 6, {
718     {  0,   0, 163,  38}, {163,   0, 326,  38}, {326,   0, 489,  38},
719     {489,   0, 652,  38}, {652,   0, 819,  38}, {819,   0, 850,  38},
720   }, },
721 };
722 
723 static int tbsize_numtests = 0;
724 
725 #define check_sizes_todo(todomask) { \
726         RECT rc; \
727         int buttonCount, i, mask=(todomask); \
728         tbsize_result_t *res = &tbsize_results[tbsize_numtests]; \
729         assert(tbsize_numtests < sizeof(tbsize_results)/sizeof(tbsize_results[0])); \
730         GetClientRect(hToolbar, &rc); \
731         /*check_rect("client", rc, res->rcClient);*/ \
732         buttonCount = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0); \
733         compare(buttonCount, res->nButtons, "%d"); \