ReactOS  0.4.12-dev-418-g3df31a8
toolbar.c
Go to the documentation of this file.
1 /* Unit tests for toolbar.
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 <stdarg.h>
22 
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winnls.h"
28 #include "winreg.h"
29 #include "commctrl.h"
30 
31 #include "resources.h"
32 
33 #include "wine/test.h"
34 
35 #include "msg.h"
36 
37 #define PARENT_SEQ_INDEX 0
38 #define NUM_MSG_SEQUENCES 1
39 
40 static HWND (WINAPI *pCreateToolbarEx)(HWND, DWORD, UINT, INT, HINSTANCE, UINT_PTR, const TBBUTTON *,
41  INT, INT, INT, INT, INT, UINT);
42 static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
43 static INT (WINAPI *pImageList_GetImageCount)(HIMAGELIST);
44 static BOOL (WINAPI *pImageList_GetIconSize)(HIMAGELIST, int *, int *);
45 static HIMAGELIST (WINAPI *pImageList_LoadImageA)(HINSTANCE, LPCSTR, int, int, COLORREF, UINT, UINT);
46 
48 
49 static HWND hMainWnd;
56 
57 static const struct message ttgetdispinfo_parent_seq[] = {
58  { WM_NOTIFY, sent|id, 0, 0, TBN_GETINFOTIPA },
59  /* next line is todo, currently TTN_GETDISPINFOW is raised here */
60  { WM_NOTIFY, sent|id, 0, 0, TTN_GETDISPINFOA },
61  { 0 }
62 };
63 
64 static const struct message save_parent_seq[] = {
65  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, -1 },
66  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 0 },
67  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 1 },
68  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 2 },
69  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 3 },
70  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 4 },
71  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 5 },
72  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_SAVE, 6 },
73  { 0 }
74 };
75 
76 static const struct message restore_parent_seq[] = {
77  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, -1 },
78  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 0 },
79  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 1 },
80  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 2 },
81  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 3 },
82  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 4 },
83  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 5 },
84  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 6 },
85  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 7 },
86  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 8 },
87  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 9 },
88  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_RESTORE, 0xa },
89  { WM_NOTIFY, sent|id, 0, 0, TBN_BEGINADJUST },
90  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 0 },
91  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 1 },
92  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 2 },
93  { WM_NOTIFY, sent|id|custdraw, 0, 0, TBN_GETBUTTONINFOA, 3 },
94  { WM_NOTIFY, sent|id, 0, 0, TBN_ENDADJUST },
95  { 0 }
96 };
97 
98 #define DEFINE_EXPECT(func) \
99  static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
100 
101 #define CHECK_EXPECT2(func) \
102  do { \
103  ok(expect_ ##func, "unexpected call " #func "\n"); \
104  called_ ## func = TRUE; \
105  }while(0)
106 
107 #define CHECK_CALLED(func) \
108  do { \
109  ok(called_ ## func, "expected " #func "\n"); \
110  expect_ ## func = called_ ## func = FALSE; \
111  }while(0)
112 
113 #define SET_EXPECT(func) \
114  expect_ ## func = TRUE
115 
116 #define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
117 
118 #define check_rect(name, val, exp, ...) ok(EqualRect(&val, &exp), \
119  "invalid rect %s - expected %s - (" name ")\n", \
120  wine_dbgstr_rect(&val), wine_dbgstr_rect(&exp), __VA_ARGS__);
121 
122 #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
123 
124 #define check_button_size(handle, width, height, ...) {\
125  LRESULT bsize = SendMessageA(handle, TB_GETBUTTONSIZE, 0, 0);\
126  ok(bsize == MAKELONG(width, height), "Unexpected button size - got size (%d, %d), expected (%d, %d)\n", LOWORD(bsize), HIWORD(bsize), width, height);\
127  }
128 
129 static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) {
130  p->iBitmap = -2;
131  p->idCommand = idCommand;
132  p->fsState = TBSTATE_ENABLED;
133  p->fsStyle = fsStyle;
134  p->iString = nString;
135 }
136 
137 static void *alloced_str;
138 
140 {
141  NMHDR *hdr = (NMHDR *)lParam;
142  NMTBHOTITEM *nmhi;
143  NMTBDISPINFOA *nmdisp;
144  switch (hdr->code)
145  {
146  case TBN_HOTITEMCHANGE:
147  nmhi = (NMTBHOTITEM *)lParam;
150  {
151  compare(nmhi->idOld, g_fExpectedHotItemOld, "%d");
152  compare(nmhi->idNew, g_fExpectedHotItemNew, "%d");
153  }
155  return 1;
156  break;
157 
158  case TBN_GETDISPINFOA:
159  ok(FALSE, "TBN_GETDISPINFOA received\n");
160  break;
161 
162  case TBN_GETINFOTIPA:
163  {
165 
166  if (g_ResetDispTextPtr)
167  {
168  tbgit->pszText = NULL;
169  return 0;
170  }
171  break;
172  }
173  case TBN_GETDISPINFOW:
174  nmdisp = (NMTBDISPINFOA *)lParam;
175 
176  compare(nmdisp->dwMask, g_dwExpectedDispInfoMask, "%x");
177  ok(nmdisp->pszText == NULL, "pszText is not NULL\n");
178  break;
179  case TBN_SAVE:
180  {
181  NMTBSAVE *save = (NMTBSAVE *)lParam;
182  if (save->iItem == -1)
183  {
184  save->cbData = save->cbData * 2 + 11 * sizeof(DWORD);
185  save->pData = heap_alloc( save->cbData );
186  save->pData[0] = 0xcafe;
187  save->pCurrent = save->pData + 1;
188  }
189  else
190  {
191  save->pCurrent[0] = 0xcafe0000 + save->iItem;
192  save->pCurrent++;
193  }
194 
195  /* Add on 5 more pseudo buttons. */
196  if (save->iItem == save->cButtons - 1)
197  {
198  save->pCurrent[0] = 0xffffffff;
199  save->pCurrent[1] = 0xcafe0007;
200  save->pCurrent[2] = 0xfffffffe;
201  save->pCurrent[3] = 0xcafe0008;
202  save->pCurrent[4] = 0x80000000;
203  save->pCurrent[5] = 0xcafe0009;
204  save->pCurrent[6] = 0x7fffffff;
205  save->pCurrent[7] = 0xcafe000a;
206  save->pCurrent[8] = 0x100;
207  save->pCurrent[9] = 0xcafe000b;
208  }
209 
210  /* Return value is ignored */
211  return 1;
212  }
213  case TBN_RESTORE:
214  {
215  NMTBRESTORE *restore = (NMTBRESTORE *)lParam;
216 
217  if (restore->iItem == -1)
218  {
219  ok( restore->cButtons == 25, "got %d\n", restore->cButtons );
220  ok( *restore->pCurrent == 0xcafe, "got %08x\n", *restore->pCurrent );
221  /* Skip the last one */
222  restore->cButtons = 11;
223  restore->pCurrent++;
224  /* BytesPerRecord is ignored */
225  restore->cbBytesPerRecord = 10;
226  }
227  else
228  {
229  ok( *restore->pCurrent == 0xcafe0000 + restore->iItem, "got %08x\n", *restore->pCurrent );
230  if (restore->iItem < 7 || restore->iItem == 10)
231  {
232  ok( restore->tbButton.iBitmap == -1, "got %08x\n", restore->tbButton.iBitmap );
233  if (restore->iItem < 7)
234  ok( restore->tbButton.idCommand == restore->iItem * 2 + 1, "%d: got %08x\n", restore->iItem, restore->tbButton.idCommand );
235  else
236  ok( restore->tbButton.idCommand == 0x7fffffff, "%d: got %08x\n", restore->iItem, restore->tbButton.idCommand );
237  ok( restore->tbButton.fsState == 0, "%d: got %02x\n", restore->iItem, restore->tbButton.fsState );
238  ok( restore->tbButton.fsStyle == 0, "%d: got %02x\n", restore->iItem, restore->tbButton.fsStyle );
239  }
240  else
241  {
242  ok( restore->tbButton.iBitmap == 8, "got %08x\n", restore->tbButton.iBitmap );
243  ok( restore->tbButton.idCommand == 0, "%d: got %08x\n", restore->iItem, restore->tbButton.idCommand );
244  if (restore->iItem == 7)
245  ok( restore->tbButton.fsState == 0, "%d: got %02x\n", restore->iItem, restore->tbButton.fsState );
246  else
247  ok( restore->tbButton.fsState == TBSTATE_HIDDEN, "%d: got %02x\n", restore->iItem, restore->tbButton.fsState );
248  ok( restore->tbButton.fsStyle == BTNS_SEP, "%d: got %02x\n", restore->iItem, restore->tbButton.fsStyle );
249  }
250 
251  ok( restore->tbButton.dwData == 0, "got %08lx\n", restore->tbButton.dwData );
252  ok( restore->tbButton.iString == 0, "got %08lx\n", restore->tbButton.iString );
253 
254  restore->tbButton.iBitmap = 0;
255  restore->tbButton.fsState = TBSTATE_ENABLED;
256  restore->tbButton.fsStyle = 0;
257  restore->tbButton.dwData = restore->iItem;
258 
259  if (restore->iItem == 0)
260  {
261  restore->tbButton.iString = (INT_PTR)heap_alloc_zero( 8 );
262  strcpy( (char *)restore->tbButton.iString, "foo" );
263  }
264  else if (restore->iItem == 1)
265  restore->tbButton.iString = 2;
266  else
267  restore->tbButton.iString = -1;
268 
269  restore->pCurrent++;
270  /* Altering cButtons after the 1st call makes no difference. */
271  restore->cButtons--;
272  }
273 
274  /* Returning non-zero from the 1st call aborts the restore,
275  otherwise the return value is ignored. */
276  if (restore->iItem == -1) return 0;
277  return 1;
278  }
279  case TBN_GETBUTTONINFOA:
280  {
282  tb->tbButton.iBitmap = 0;
283  tb->tbButton.fsState = 0;
284  tb->tbButton.fsStyle = 0;
285  tb->tbButton.dwData = 0;
286  ok( tb->cchText == 128, "got %d\n", tb->cchText );
287  switch (tb->iItem)
288  {
289  case 0:
290  tb->tbButton.idCommand = 7;
291  alloced_str = heap_alloc_zero( 8 );
292  strcpy( alloced_str, "foo" );
293  tb->tbButton.iString = (INT_PTR)alloced_str;
294  return 1;
295  case 1:
296  tb->tbButton.idCommand = 9;
297  tb->tbButton.iString = 0;
298  /* tb->pszText is ignored */
299  strcpy( tb->pszText, "foo" );
300  return 1;
301  case 2:
302  tb->tbButton.idCommand = 11;
303  tb->tbButton.iString = 3;
304  return 1;
305  }
306  return 0;
307  }
308  }
309  return 0;
310 }
311 
313 {
314  static LONG defwndproc_counter = 0;
315  struct message msg;
316  LRESULT ret;
317 
318  msg.message = message;
319  msg.flags = sent|wparam|lparam;
320  if (defwndproc_counter) msg.flags |= defwinproc;
321  msg.wParam = wParam;
322  msg.lParam = lParam;
323  if (message == WM_NOTIFY && lParam)
324  {
325  msg.id = ((NMHDR*)lParam)->code;
326  switch (msg.id)
327  {
328  case TBN_SAVE:
329  {
330  NMTBSAVE *save = (NMTBSAVE *)lParam;
331  msg.stage = save->iItem;
332  }
333  break;
334  case TBN_RESTORE:
335  {
336  NMTBRESTORE *restore = (NMTBRESTORE *)lParam;
337  msg.stage = restore->iItem;
338  }
339  break;
340  case TBN_GETBUTTONINFOA:
341  {
343  msg.stage = tb->iItem;
344  }
345  break;
346  }
347  }
348 
349  /* log system messages, except for painting */
350  if (message < WM_USER &&
351  message != WM_PAINT &&
352  message != WM_ERASEBKGND &&
353  message != WM_NCPAINT &&
354  message != WM_NCHITTEST &&
355  message != WM_GETTEXT &&
356  message != WM_GETICON &&
358  {
360  }
361 
362  switch (message)
363  {
364  case WM_NOTIFY:
365  return parent_wnd_notify(lParam);
366  }
367 
368  defwndproc_counter++;
370  defwndproc_counter--;
371 
372  return ret;
373 }
374 
375 static void basic_test(void)
376 {
377  TBBUTTON buttons[9];
378  HWND hToolbar;
379  int i;
380 
381  for (i=0; i<9; i++)
384  MakeButton(buttons+6, 1006, TBSTYLE_SEP, 0);
385 
386  hToolbar = pCreateToolbarEx(hMainWnd,
389  100,
390  0, NULL, 0,
391  buttons, sizeof(buttons)/sizeof(buttons[0]),
392  0, 0, 20, 16, sizeof(TBBUTTON));
393  ok(hToolbar != NULL, "Toolbar creation\n");
394  SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000");
395 
396  /* test for exclusion working inside a separator-separated :-) group */
397  SendMessageA(hToolbar, TB_CHECKBUTTON, 1000, 1); /* press A1 */
398  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
399  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1001, 0), "A2 not pressed\n");
400 
401  SendMessageA(hToolbar, TB_CHECKBUTTON, 1004, 1); /* press A5, release A1 */
402  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1004, 0), "A5 pressed\n");
403  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 not pressed anymore\n");
404 
405  SendMessageA(hToolbar, TB_CHECKBUTTON, 1005, 1); /* press A6, release A5 */
406  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 pressed\n");
407  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1004, 0), "A5 not pressed anymore\n");
408 
409  /* test for inter-group crosstalk, i.e. two radio groups interfering with each other */
410  SendMessageA(hToolbar, TB_CHECKBUTTON, 1007, 1); /* press B2 */
411  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 still pressed, no inter-group crosstalk\n");
412  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 still not pressed\n");
413  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 pressed\n");
414 
415  SendMessageA(hToolbar, TB_CHECKBUTTON, 1000, 1); /* press A1 and ensure B group didn't suffer */
416  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 not pressed anymore\n");
417  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
418  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 still pressed\n");
419 
420  SendMessageA(hToolbar, TB_CHECKBUTTON, 1008, 1); /* press B3, and ensure A group didn't suffer */
421  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1005, 0), "A6 pressed\n");
422  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1000, 0), "A1 pressed\n");
423  ok(!SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1007, 0), "B2 not pressed\n");
424  ok(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 1008, 0), "B3 pressed\n");
425 
426  /* tests with invalid index */
427  compare(SendMessageA(hToolbar, TB_ISBUTTONCHECKED, 0xdeadbeef, 0), -1L, "%ld");
428  compare(SendMessageA(hToolbar, TB_ISBUTTONPRESSED, 0xdeadbeef, 0), -1L, "%ld");
429  compare(SendMessageA(hToolbar, TB_ISBUTTONENABLED, 0xdeadbeef, 0), -1L, "%ld");
430  compare(SendMessageA(hToolbar, TB_ISBUTTONINDETERMINATE, 0xdeadbeef, 0), -1L, "%ld");
431  compare(SendMessageA(hToolbar, TB_ISBUTTONHIGHLIGHTED, 0xdeadbeef, 0), -1L, "%ld");
432  compare(SendMessageA(hToolbar, TB_ISBUTTONHIDDEN, 0xdeadbeef, 0), -1L, "%ld");
433 
434  DestroyWindow(hToolbar);
435 }
436 
437 static void rebuild_toolbar(HWND *hToolbar)
438 {
439  if (*hToolbar)
440  DestroyWindow(*hToolbar);
441  *hToolbar = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
443  ok(*hToolbar != NULL, "Toolbar creation problem\n");
444  ok(SendMessageA(*hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
445  ok(SendMessageA(*hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
446  ok(SendMessageA(*hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
447 }
448 
449 static void rebuild_toolbar_with_buttons(HWND *hToolbar)
450 {
451  TBBUTTON buttons[5];
452  rebuild_toolbar(hToolbar);
453 
454  ZeroMemory(&buttons, sizeof(buttons));
455  buttons[0].idCommand = 1;
456  buttons[0].fsStyle = BTNS_BUTTON;
457  buttons[0].fsState = TBSTATE_ENABLED;
458  buttons[0].iString = -1;
459  buttons[1].idCommand = 3;
460  buttons[1].fsStyle = BTNS_BUTTON;
461  buttons[1].fsState = TBSTATE_ENABLED;
462  buttons[1].iString = -1;
463  buttons[2].idCommand = 5;
464  buttons[2].fsStyle = BTNS_SEP;
465  buttons[2].fsState = TBSTATE_ENABLED;
466  buttons[2].iString = -1;
467  buttons[3].idCommand = 7;
468  buttons[3].fsStyle = BTNS_BUTTON;
469  buttons[3].fsState = TBSTATE_ENABLED;
470  buttons[3].iString = -1;
471  buttons[4].idCommand = 9;
472  buttons[4].fsStyle = BTNS_BUTTON;
473  buttons[4].fsState = 0; /* disabled */
474  buttons[4].iString = -1;
475  ok(SendMessageA(*hToolbar, TB_ADDBUTTONSA, 5, (LPARAM)buttons) == 1, "TB_ADDBUTTONSA failed\n");
476  ok(SendMessageA(*hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
477 }
478 
479 static void add_128x15_bitmap(HWND hToolbar, int nCmds)
480 {
481  TBADDBITMAP bmp128;
482  bmp128.hInst = GetModuleHandleA(NULL);
483  bmp128.nID = IDB_BITMAP_128x15;
484  ok(SendMessageA(hToolbar, TB_ADDBITMAP, nCmds, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
485 }
486 
487 #define CHECK_IMAGELIST(count, dx, dy) { \
488  int cx, cy; \
489  HIMAGELIST himl = (HIMAGELIST)SendMessageA(hToolbar, TB_GETIMAGELIST, 0, 0); \
490  ok(himl != NULL, "No image list\n"); \
491  if (himl != NULL) {\
492  ok(pImageList_GetImageCount(himl) == count, "Images count mismatch - %d vs %d\n", count, pImageList_GetImageCount(himl)); \
493  pImageList_GetIconSize(himl, &cx, &cy); \
494  ok(cx == dx && cy == dy, "Icon size mismatch - %dx%d vs %dx%d\n", dx, dy, cx, cy); \
495  } \
496 }
497 
498 static void test_add_bitmap(void)
499 {
500  TBADDBITMAP stdsmall, std;
501  HWND hToolbar = NULL;
502  TBADDBITMAP bmp128;
503  TBADDBITMAP bmp80;
504  TBADDBITMAP addbmp;
506  INT ret, id;
507 
508  /* Test default bitmaps range */
509  for (id = IDB_STD_SMALL_COLOR; id < IDB_HIST_LARGE_COLOR; id++)
510  {
512  int cx, cy, count;
513 
514  rebuild_toolbar(&hToolbar);
515 
516  std.hInst = HINST_COMMCTRL;
517  std.nID = id;
518 
519  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&std);
520  ok(ret == 0, "Got %d\n", ret);
521 
522  himl = (HIMAGELIST)SendMessageA(hToolbar, TB_GETIMAGELIST, 0, 0);
523  ok(himl != NULL, "Got %p\n", himl);
524 
525  ret = pImageList_GetIconSize(himl, &cx, &cy);
526  ok(ret, "Got %d\n", ret);
527  ok(cx == cy, "Got %d x %d\n", cx, cy);
528 
529  count = pImageList_GetImageCount(himl);
530 
531  /* Image count */
532  switch (id)
533  {
534  case IDB_STD_SMALL_COLOR:
535  case IDB_STD_LARGE_COLOR:
536  case 2:
537  case 3:
538  ok(count == 15, "got count %d\n", count);
539  break;
542  case 6:
543  case 7:
544  ok(count == 12, "got count %d\n", count);
545  break;
548  ok(count == 5, "got count %d\n", count);
549  break;
550  default:
551  ok(0, "id %d, count %d\n", id, count);
552  }
553 
554  /* Image sizes */
555  switch (id)
556  {
557  case IDB_STD_SMALL_COLOR:
558  case 2:
560  case 6:
562  ok(cx == 16, "got size %d\n", cx);
563  break;
564  case IDB_STD_LARGE_COLOR:
565  case 3:
567  case 7:
569  ok(cx == 24, "got size %d\n", cx);
570  break;
571  default:
572  ok(0, "id %d, size %d\n", id, cx);
573  }
574  }
575 
576  /* empty 128x15 bitmap */
577  bmp128.hInst = GetModuleHandleA(NULL);
578  bmp128.nID = IDB_BITMAP_128x15;
579 
580  /* empty 80x15 bitmap */
581  bmp80.hInst = GetModuleHandleA(NULL);
582  bmp80.nID = IDB_BITMAP_80x15;
583 
584  /* standard bitmap - 240x15 pixels */
585  stdsmall.hInst = HINST_COMMCTRL;
586  stdsmall.nID = IDB_STD_SMALL_COLOR;
587 
588  rebuild_toolbar(&hToolbar);
589  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 8, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
590  CHECK_IMAGELIST(8, 16, 16);
591 
592  /* adding more bitmaps */
593  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80) == 8, "TB_ADDBITMAP - unexpected return\n");
594  CHECK_IMAGELIST(13, 16, 16);
595  /* adding the same bitmap will simply return the index of the already loaded block */
596  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 8, (LPARAM)&bmp128);
597  ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
598  CHECK_IMAGELIST(13, 16, 16);
599  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80);
600  ok(ret == 8, "TB_ADDBITMAP - unexpected return %d\n", ret);
601  CHECK_IMAGELIST(13, 16, 16);
602  /* even if we increase the wParam */
603  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 55, (LPARAM)&bmp80);
604  ok(ret == 8, "TB_ADDBITMAP - unexpected return %d\n", ret);
605  CHECK_IMAGELIST(13, 16, 16);
606 
607  /* when the wParam is smaller than the bitmaps count but non-zero, all the bitmaps will be added*/
608  rebuild_toolbar(&hToolbar);
609  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 3, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
610  CHECK_IMAGELIST(8, 16, 16);
611  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80);
612  ok(ret == 3, "TB_ADDBITMAP - unexpected return %d\n", ret);
613  /* the returned value is misleading - id 8 is the id of the first icon from bmp80 */
614  CHECK_IMAGELIST(13, 16, 16);
615 
616  /* the same for negative wParam */
617  rebuild_toolbar(&hToolbar);
618  ret = SendMessageA(hToolbar, TB_ADDBITMAP, -143, (LPARAM)&bmp128);
619  ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
620  CHECK_IMAGELIST(8, 16, 16);
621  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp80);
622  ok(ret == -143, "TB_ADDBITMAP - unexpected return %d\n", ret);
623  CHECK_IMAGELIST(13, 16, 16);
624 
625  /* for zero only one bitmap will be added */
626  rebuild_toolbar(&hToolbar);
627  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&bmp80);
628  ok(ret == 0, "TB_ADDBITMAP - unexpected return %d\n", ret);
629  CHECK_IMAGELIST(1, 16, 16);
630 
631  /* if wParam is larger than the amount of icons, the list is grown */
632  rebuild_toolbar(&hToolbar);
633  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp80) == 0, "TB_ADDBITMAP - unexpected return\n");
634  CHECK_IMAGELIST(100, 16, 16);
635  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp128);
636  ok(ret == 100, "TB_ADDBITMAP - unexpected return %d\n", ret);
637  CHECK_IMAGELIST(200, 16, 16);
638 
639  /* adding built-in items - the wParam is ignored */
640  rebuild_toolbar(&hToolbar);
641  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp80) == 0, "TB_ADDBITMAP - unexpected return\n");
642  CHECK_IMAGELIST(5, 16, 16);
643  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&stdsmall) == 5, "TB_ADDBITMAP - unexpected return\n");
644  CHECK_IMAGELIST(20, 16, 16);
645  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp128) == 20, "TB_ADDBITMAP - unexpected return\n");
646  CHECK_IMAGELIST(28, 16, 16);
647 
648  /* when we increase the bitmap size, less icons will be created */
649  rebuild_toolbar(&hToolbar);
650  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(20, 20)) == TRUE, "TB_SETBITMAPSIZE failed\n");
651  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
652  CHECK_IMAGELIST(6, 20, 20);
653  ret = SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp80);
654  ok(ret == 1, "TB_ADDBITMAP - unexpected return %d\n", ret);
655  CHECK_IMAGELIST(10, 20, 20);
656  /* the icons can be resized - an UpdateWindow is needed as this probably happens during WM_PAINT */
657  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
658  UpdateWindow(hToolbar);
659  CHECK_IMAGELIST(26, 8, 8);
660  /* loading a standard bitmaps automatically resizes the icons */
661  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&stdsmall) == 2, "TB_ADDBITMAP - unexpected return\n");
662  UpdateWindow(hToolbar);
663  CHECK_IMAGELIST(28, 16, 16);
664 
665  /* two more SETBITMAPSIZE tests */
666  rebuild_toolbar(&hToolbar);
667  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
668  CHECK_IMAGELIST(100, 16, 16);
669  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 100, (LPARAM)&bmp80) == 100, "TB_ADDBITMAP - unexpected return\n");
670  CHECK_IMAGELIST(200, 16, 16);
671  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
672  UpdateWindow(hToolbar);
673  CHECK_IMAGELIST(200, 8, 8);
674  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
675  UpdateWindow(hToolbar);
676  CHECK_IMAGELIST(200, 30, 30);
677  rebuild_toolbar(&hToolbar);
678  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 5, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
679  CHECK_IMAGELIST(8, 16, 16);
680  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 3, (LPARAM)&bmp80) == 5, "TB_ADDBITMAP - unexpected return\n");
681  CHECK_IMAGELIST(13, 16, 16);
682  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(30, 30)) == TRUE, "TB_SETBITMAPSIZE failed\n");
683  UpdateWindow(hToolbar);
684  CHECK_IMAGELIST(8, 30, 30);
685  /* when the width or height is zero, set it to 1 */
686  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(0, 0)) == TRUE, "TB_SETBITMAPSIZE failed\n");
687  UpdateWindow(hToolbar);
688  CHECK_IMAGELIST(208, 1, 1);
689  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(0, 5)) == TRUE, "TB_SETBITMAPSIZE failed\n");
690  UpdateWindow(hToolbar);
691  CHECK_IMAGELIST(208, 1, 5);
692  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(5, 0)) == TRUE, "TB_SETBITMAPSIZE failed\n");
693  UpdateWindow(hToolbar);
694  CHECK_IMAGELIST(41, 5, 1);
695 
696  /* the control can add bitmaps to an existing image list */
697  rebuild_toolbar(&hToolbar);
698  himl = pImageList_LoadImageA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(IDB_BITMAP_80x15),
700  ok(himl != NULL, "failed to create imagelist\n");
701  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
702  CHECK_IMAGELIST(4, 20, 15);
703  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&bmp128) == 0, "TB_ADDBITMAP - unexpected return\n");
704  CHECK_IMAGELIST(10, 20, 15);
705  /* however TB_SETBITMAPSIZE/add std bitmap won't change the image size (the button size does change) */
706  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(8, 8)) == TRUE, "TB_SETBITMAPSIZE failed\n");
707  UpdateWindow(hToolbar);
708  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(15, 14), "%x");
709  CHECK_IMAGELIST(10, 20, 15);
710  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 0, (LPARAM)&stdsmall) == 1, "TB_SETBITMAPSIZE failed\n");
711  UpdateWindow(hToolbar);
712  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x");
713  CHECK_IMAGELIST(22, 20, 15);
714 
715  /* check standard bitmaps */
716  addbmp.hInst = HINST_COMMCTRL;
717  addbmp.nID = IDB_STD_SMALL_COLOR;
718  rebuild_toolbar(&hToolbar);
719  pImageList_Destroy(himl);
720 
721  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
722  CHECK_IMAGELIST(15, 16, 16);
723  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x");
724  addbmp.nID = IDB_STD_LARGE_COLOR;
725  rebuild_toolbar(&hToolbar);
726  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
727  CHECK_IMAGELIST(15, 24, 24);
728  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(31, 30), "%x");
729 
730  addbmp.nID = IDB_VIEW_SMALL_COLOR;
731  rebuild_toolbar(&hToolbar);
732  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
733  CHECK_IMAGELIST(12, 16, 16);
734  addbmp.nID = IDB_VIEW_LARGE_COLOR;
735  rebuild_toolbar(&hToolbar);
736  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
737  CHECK_IMAGELIST(12, 24, 24);
738 
739  addbmp.nID = IDB_HIST_SMALL_COLOR;
740  rebuild_toolbar(&hToolbar);
741  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
742  CHECK_IMAGELIST(5, 16, 16);
743  addbmp.nID = IDB_HIST_LARGE_COLOR;
744  rebuild_toolbar(&hToolbar);
745  ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
746  CHECK_IMAGELIST(5, 24, 24);
747 
748 
749  DestroyWindow(hToolbar);
750 }
751 
752 #define CHECK_STRING_TABLE(count, tab) { \
753  INT _i; \
754  CHAR _buf[260]; \
755  for (_i = 0; _i < (count); _i++) {\
756  ret = SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(260, _i), (LPARAM)_buf); \
757  ok(ret >= 0, "TB_GETSTRINGA - unexpected return %d while checking string %d\n", ret, _i); \
758  if (ret >= 0) \
759  ok(strcmp(_buf, (tab)[_i]) == 0, "Invalid string #%d - '%s' vs '%s'\n", _i, (tab)[_i], _buf); \
760  } \
761  ok(SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(260, (count)), (LPARAM)_buf) == -1, \
762  "Too many strings in table\n"); \
763  }
764 
765 static void test_add_string(void)
766 {
767  LPCSTR test1 = "a\0b\0";
768  LPCSTR test2 = "|a|b||\0";
769  LPCSTR ret1[] = {"a", "b"};
770  LPCSTR ret2[] = {"a", "b", "|a|b||"};
771  LPCSTR ret3[] = {"a", "b", "|a|b||", "p", "q"};
772  LPCSTR ret4[] = {"a", "b", "|a|b||", "p", "q", "p"};
773  LPCSTR ret5[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q"};
774  LPCSTR ret6[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q"};
775  LPCSTR ret7[] = {"a", "b", "|a|b||", "p", "q", "p", "p", "q", "p", "", "q", "br", "c", "d"};
776  HWND hToolbar = NULL;
777  TBBUTTON button;
778  int ret;
779  CHAR buf[260];
780 
781  rebuild_toolbar(&hToolbar);
782  ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test1);
783  ok(ret == 0, "TB_ADDSTRINGA - unexpected return %d\n", ret);
784  ret = SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(260, 1), (LPARAM)buf);
785  if (ret == 0)
786  {
787  win_skip("TB_GETSTRINGA needs 5.80\n");
788  return;
789  }
790  CHECK_STRING_TABLE(2, ret1);
791  ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test2);
792  ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret);
793  CHECK_STRING_TABLE(3, ret2);
794 
795  /* null instance handle */
796  ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, IDS_TBADD1);
797  ok(ret == -1, "TB_ADDSTRINGA - unexpected return %d\n", ret);
798 
799  /* invalid instance handle */
800  ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0xdeadbeef, IDS_TBADD1);
801  ok(ret == -1, "TB_ADDSTRINGA - unexpected return %d\n", ret);
802 
804  ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret);
805  CHECK_STRING_TABLE(3, ret2);
807  ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret);
808  CHECK_STRING_TABLE(5, ret3);
810  ok(ret == 5, "TB_ADDSTRINGA - unexpected return %d\n", ret);
811  CHECK_STRING_TABLE(6, ret4);
813  ok(ret == 6, "TB_ADDSTRINGA - unexpected return %d\n", ret);
814  CHECK_STRING_TABLE(8, ret5);
816  ok(ret == 8, "TB_ADDSTRINGA - unexpected return %d\n", ret);
817  CHECK_STRING_TABLE(11, ret6);
819  ok(ret == 11, "TB_ADDSTRINGA - unexpected return %d\n", ret);
820  CHECK_STRING_TABLE(14, ret7);
821 
822  ZeroMemory(&button, sizeof(button));
823  button.iString = (UINT_PTR)"Test";
824  SendMessageA(hToolbar, TB_INSERTBUTTONA, 0, (LPARAM)&button);
825  CHECK_STRING_TABLE(14, ret7);
826  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&button);
827  CHECK_STRING_TABLE(14, ret7);
828 
829  DestroyWindow(hToolbar);
830 }
831 
832 static void expect_hot_notify(int idold, int idnew)
833 {
834  g_fExpectedHotItemOld = idold;
835  g_fExpectedHotItemNew = idnew;
837 }
838 
839 #define check_hot_notify() \
840  ok(g_fReceivedHotItemChange, "TBN_HOTITEMCHANGE not received\n"); \
841  g_fExpectedHotItemOld = g_fExpectedHotItemNew = 0;
842 
843 static void test_hotitem(void)
844 {
845  HWND hToolbar = NULL;
846  TBBUTTONINFOA tbinfo;
847  LRESULT ret;
848 
850 
851  rebuild_toolbar_with_buttons(&hToolbar);
852  /* set TBSTYLE_FLAT. comctl5 allows hot items only for such toolbars.
853  * comctl6 doesn't have this requirement even when theme == NULL */
855  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
856  ok(ret == -1, "Hot item: %ld, expected -1\n", ret);
857  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 1, 0);
858  ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
859  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
860  ok(ret == 1, "Hot item: %ld, expected 1\n", ret);
861  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 2, 0);
862  ok(ret == 1, "TB_SETHOTITEM returned %ld, expected 1\n", ret);
863 
864  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 0xbeef, 0);
865  ok(ret == 2, "TB_SETHOTITEM returned %ld, expected 2\n", ret);
866  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
867  ok(ret == 2, "Hot item: %lx, expected 2\n", ret);
868  ret = SendMessageA(hToolbar, TB_SETHOTITEM, -0xbeef, 0);
869  ok(ret == 2, "TB_SETHOTITEM returned %ld, expected 2\n", ret);
870  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
871  ok(ret == -1, "Hot item: %lx, expected -1\n", ret);
872 
873  expect_hot_notify(0, 7);
874  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 3, 0);
875  ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
877  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
878  ok(ret == 3, "Hot item: %lx, expected 3\n", ret);
880  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 2, 0);
881  ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
882  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
883  ok(ret == 3, "Hot item: %lx, expected 3\n", ret);
885 
887  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 0xbeaf, 0);
888  ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
889  ok(g_fReceivedHotItemChange == FALSE, "TBN_HOTITEMCHANGE received for invalid parameter\n");
890 
892  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 3, 0);
893  ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
894  ok(g_fReceivedHotItemChange == FALSE, "TBN_HOTITEMCHANGE received after a duplication\n");
895 
896  expect_hot_notify(7, 0);
897  ret = SendMessageA(hToolbar, TB_SETHOTITEM, -0xbeaf, 0);
898  ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
900  SendMessageA(hToolbar, TB_SETHOTITEM, 3, 0);
901 
902  /* setting disabled buttons will generate a notify with the button id but no button will be hot */
903  expect_hot_notify(7, 9);
904  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 4, 0);
905  ok(ret == 3, "TB_SETHOTITEM returned %ld, expected 3\n", ret);
907  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
908  ok(ret == -1, "Hot item: %lx, expected -1\n", ret);
909  /* enabling the button won't change that */
910  SendMessageA(hToolbar, TB_ENABLEBUTTON, 9, TRUE);
911  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
912  ok(ret == -1, "TB_GETHOTITEM returned %ld, expected -1\n", ret);
913 
914  /* disabling a hot button works */
915  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 3, 0);
916  ok(ret == -1, "TB_SETHOTITEM returned %ld, expected -1\n", ret);
918  SendMessageA(hToolbar, TB_ENABLEBUTTON, 7, FALSE);
919  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
920  ok(ret == 3, "TB_GETHOTITEM returned %ld, expected 3\n", ret);
921  ok(g_fReceivedHotItemChange == FALSE, "Unexpected TBN_HOTITEMCHANGE\n");
922 
923  SendMessageA(hToolbar, TB_SETHOTITEM, 1, 0);
924  tbinfo.cbSize = sizeof(TBBUTTONINFOA);
925  tbinfo.dwMask = TBIF_STATE;
926  tbinfo.fsState = 0; /* disabled */
928  ok(SendMessageA(hToolbar, TB_SETBUTTONINFOA, 1, (LPARAM)&tbinfo) == TRUE, "TB_SETBUTTONINFOA failed\n");
929  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
930  ok(ret == 1, "TB_GETHOTITEM returned %ld, expected 1\n", ret);
931  ok(g_fReceivedHotItemChange == FALSE, "Unexpected TBN_HOTITEMCHANGE\n");
932 
933  /* deleting a button unsets the hot item */
934  ret = SendMessageA(hToolbar, TB_SETHOTITEM, 0, 0);
935  ok(ret == 1, "TB_SETHOTITEM returned %ld, expected 1\n", ret);
937  ret = SendMessageA(hToolbar, TB_DELETEBUTTON, 1, 0);
938  ok(ret == TRUE, "TB_DELETEBUTTON returned %ld, expected TRUE\n", ret);
939  ret = SendMessageA(hToolbar, TB_GETHOTITEM, 0, 0);
940  ok(ret == -1, "TB_GETHOTITEM returned %ld, expected -1\n", ret);
941  ok(g_fReceivedHotItemChange == FALSE, "Unexpected TBN_HOTITEMCHANGE\n");
942 
943  DestroyWindow(hToolbar);
944 }
945 
946 #if 0 /* use this to generate more tests*/
947 
948 static void dump_sizes(HWND hToolbar)
949 {
950  SIZE sz;
951  RECT r;
952  int count = SendMessageA(hToolbar, TB_BUTTONCOUNT, 0, 0);
953  int i;
954 
955  GetClientRect(hToolbar, &r);
956  SendMessageA(hToolbar, TB_GETMAXSIZE, 0, &sz);
957  printf(" { {%d, %d, %d, %d}, {%d, %d}, %d, {", r.left, r.top, r.right, r.bottom,
958  sz.cx, sz.cy, count);
959  for (i=0; i<count; i++)
960  {
961  SendMessageA(hToolbar, TB_GETITEMRECT, i, &r);
962  printf("%s{%3d, %3d, %3d, %3d}, ", (i%3==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom);
963  }
964  printf("\n }, },\n");
965 }
966 
967 #define check_sizes() dump_sizes(hToolbar);
968 #define check_sizes_todo(todomask) dump_sizes(hToolbar);
969 
970 #else
971 
972 static int system_font_height(void) {
973  HDC hDC;
974  TEXTMETRICA tm;
975 
978  DeleteDC(NULL);
979 
980  return tm.tmHeight;
981 }
982 
983 static int string_width(const CHAR *s) {
984  SIZE sz;
985  HDC hdc;
986 
989  DeleteDC(hdc);
990 
991  return sz.cx;
992 }
993 
994 typedef struct
995 {
1000 } tbsize_result_t;
1001 
1002 static tbsize_result_t init_tbsize_result(int nButtonsAlloc, int cleft, int ctop, int cright, int cbottom, int minx, int miny) {
1004 
1005  SetRect(&ret.rcClient, cleft, ctop, cright, cbottom);
1006  ret.szMin.cx = minx;
1007  ret.szMin.cy = miny;
1008  ret.nButtons = 0;
1009  ret.prcButtons = heap_alloc_zero(nButtonsAlloc * sizeof(*ret.prcButtons));
1010 
1011  return ret;
1012 }
1013 
1014 static void tbsize_addbutton(tbsize_result_t *tbsr, int left, int top, int right, int bottom) {
1015  SetRect(&tbsr->prcButtons[tbsr->nButtons], left, top, right, bottom);
1016  tbsr->nButtons++;
1017 }
1018 
1019 #define STRING0 "A"
1020 #define STRING1 "MMMMMMMMMMMMM"
1021 #define STRING2 "Tst"
1022 
1024 
1025 #define tbsize_results_num 28
1026 
1027 static void init_tbsize_results(void) {
1028  int fontheight = system_font_height();
1029  int buttonwidth;
1030 
1031  tbsize_results = heap_alloc_zero(tbsize_results_num * sizeof(*tbsize_results));
1032 
1033  tbsize_results[0] = init_tbsize_result(5, 0, 0 ,672 ,26, 100 ,22);
1034  tbsize_addbutton(&tbsize_results[0], 0, 2, 23, 24);
1035  tbsize_addbutton(&tbsize_results[0], 23, 2, 46, 24);
1036  tbsize_addbutton(&tbsize_results[0], 46, 2, 54, 24);
1037  tbsize_addbutton(&tbsize_results[0], 54, 2, 77, 24);
1038  tbsize_addbutton(&tbsize_results[0], 77, 2, 100, 24);
1039 
1040  tbsize_results[1] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22);
1041  tbsize_addbutton(&tbsize_results[1], 0, 2, 23, 24);
1042  tbsize_addbutton(&tbsize_results[1], 23, 2, 46, 24);
1043  tbsize_addbutton(&tbsize_results[1], 46, 2, 54, 24);
1044  tbsize_addbutton(&tbsize_results[1], 54, 2, 77, 24);
1045  tbsize_addbutton(&tbsize_results[1], 77, 2, 100, 24);
1046  tbsize_addbutton(&tbsize_results[1], 100, 2, 123, 24);
1047  tbsize_addbutton(&tbsize_results[1], 0, 24, 23, 46);
1048 
1049  tbsize_results[2] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22);
1050  tbsize_addbutton(&tbsize_results[2], 0, 2, 23, 24);
1051  tbsize_addbutton(&tbsize_results[2], 23, 2, 46, 24);
1052  tbsize_addbutton(&tbsize_results[2], 46, 2, 54, 24);
1053  tbsize_addbutton(&tbsize_results[2], 54, 2, 77, 24);
1054  tbsize_addbutton(&tbsize_results[2], 77, 2, 100, 24);
1055  tbsize_addbutton(&tbsize_results[2], 100, 2, 123, 24);
1056  tbsize_addbutton(&tbsize_results[2], 0, 24, 23, 46);
1057 
1058  tbsize_results[3] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22);
1059  tbsize_addbutton(&tbsize_results[3], 0, 2, 23, 24);
1060  tbsize_addbutton(&tbsize_results[3], 23, 2, 46, 24);
1061  tbsize_addbutton(&tbsize_results[3], 46, 2, 54, 24);
1062  tbsize_addbutton(&tbsize_results[3], 54, 2, 77, 24);
1063  tbsize_addbutton(&tbsize_results[3], 77, 2, 100, 24);
1064  tbsize_addbutton(&tbsize_results[3], 100, 2, 123, 24);
1065  tbsize_addbutton(&tbsize_results[3], 123, 2, 146, 24);
1066 
1067  tbsize_results[4] = init_tbsize_result(9, 0, 0, 672, 26, 192, 22);
1068  tbsize_addbutton(&tbsize_results[4], 0, 2, 23, 24);
1069  tbsize_addbutton(&tbsize_results[4], 23, 2, 46, 24);
1070  tbsize_addbutton(&tbsize_results[4], 46, 2, 54, 24);
1071  tbsize_addbutton(&tbsize_results[4], 54, 2, 77, 24);
1072  tbsize_addbutton(&tbsize_results[4], 77, 2, 100, 24);
1073  tbsize_addbutton(&tbsize_results[4], 100, 2, 123, 24);
1074  tbsize_addbutton(&tbsize_results[4], 123, 2, 146, 24);
1075  tbsize_addbutton(&tbsize_results[4], 146, 2, 169, 24);
1076  tbsize_addbutton(&tbsize_results[4], 169, 2, 192, 24);
1077 
1078  tbsize_results[5] = init_tbsize_result(39, 0, 0, 672, 92, 882, 22);
1079  tbsize_addbutton(&tbsize_results[5], 0, 2, 23, 24);
1080  tbsize_addbutton(&tbsize_results[5], 23, 2, 46, 24);
1081  tbsize_addbutton(&tbsize_results[5], 0, 2, 8, 29);
1082  tbsize_addbutton(&tbsize_results[5], 0, 29, 23, 51);
1083  tbsize_addbutton(&tbsize_results[5], 23, 29, 46, 51);
1084  tbsize_addbutton(&tbsize_results[5], 46, 29, 69, 51);
1085  tbsize_addbutton(&tbsize_results[5], 69, 29, 92, 51);
1086  tbsize_addbutton(&tbsize_results[5], 92, 29, 115, 51);
1087  tbsize_addbutton(&tbsize_results[5], 115, 29, 138, 51);
1088  tbsize_addbutton(&tbsize_results[5], 138, 29, 161, 51);
1089  tbsize_addbutton(&tbsize_results[5], 161, 29, 184, 51);
1090  tbsize_addbutton(&tbsize_results[5], 184, 29, 207, 51);
1091  tbsize_addbutton(&tbsize_results[5], 207, 29, 230, 51);
1092  tbsize_addbutton(&tbsize_results[5], 230, 29, 253, 51);
1093  tbsize_addbutton(&tbsize_results[5], 253, 29, 276, 51);
1094  tbsize_addbutton(&tbsize_results[5], 276, 29, 299, 51);
1095  tbsize_addbutton(&tbsize_results[5], 299, 29, 322, 51);
1096  tbsize_addbutton(&tbsize_results[5], 322, 29, 345, 51);
1097  tbsize_addbutton(&tbsize_results[5], 345, 29, 368, 51);
1098  tbsize_addbutton(&tbsize_results[5], 368, 29, 391, 51);
1099  tbsize_addbutton(&tbsize_results[5], 391, 29, 414, 51);
1100  tbsize_addbutton(&tbsize_results[5], 414, 29, 437, 51);
1101  tbsize_addbutton(&tbsize_results[5], 437, 29, 460, 51);
1102  tbsize_addbutton(&tbsize_results[5], 460, 29, 483, 51);
1103  tbsize_addbutton(&tbsize_results[5], 483, 29, 506, 51);
1104  tbsize_addbutton(&tbsize_results[5], 506, 29, 529, 51);
1105  tbsize_addbutton(&tbsize_results[5], 529, 29, 552, 51);
1106  tbsize_addbutton(&tbsize_results[5], 552, 29, 575, 51);
1107  tbsize_addbutton(&tbsize_results[5], 575, 29, 598, 51);
1108  tbsize_addbutton(&tbsize_results[5], 598, 29, 621, 51);
1109  tbsize_addbutton(&tbsize_results[5], 621, 29, 644, 51);
1110  tbsize_addbutton(&tbsize_results[5], 644, 29, 667, 51);
1111  tbsize_addbutton(&tbsize_results[5], 0, 51, 23, 73);
1112  tbsize_addbutton(&tbsize_results[5], 23, 51, 46, 73);
1113  tbsize_addbutton(&tbsize_results[5], 46, 51, 69, 73);
1114  tbsize_addbutton(&tbsize_results[5], 69, 51, 92, 73);
1115  tbsize_addbutton(&tbsize_results[5], 92, 51, 115, 73);
1116  tbsize_addbutton(&tbsize_results[5], 115, 51, 138, 73);
1117  tbsize_addbutton(&tbsize_results[5], 138, 51, 161, 73);
1118 
1119  tbsize_results[6] = init_tbsize_result(7, 0, 0, 48, 226, 23, 140);
1120  tbsize_addbutton(&tbsize_results[6], 0, 2, 23, 24);
1121  tbsize_addbutton(&tbsize_results[6], 23, 2, 46, 24);
1122  tbsize_addbutton(&tbsize_results[6], 46, 2, 94, 24);
1123  tbsize_addbutton(&tbsize_results[6], 94, 2, 117, 24);
1124  tbsize_addbutton(&tbsize_results[6], 117, 2, 140, 24);
1125  tbsize_addbutton(&tbsize_results[6], 140, 2, 163, 24);
1126  tbsize_addbutton(&tbsize_results[6], 0, 24, 23, 46);
1127 
1128  tbsize_results[7] = init_tbsize_result(7, 0, 0, 92, 226, 23, 140);
1129  tbsize_addbutton(&tbsize_results[7], 0, 2, 23, 24);
1130  tbsize_addbutton(&tbsize_results[7], 23, 2, 46, 24);
1131  tbsize_addbutton(&tbsize_results[7], 0, 24, 92, 32);
1132  tbsize_addbutton(&tbsize_results[7], 0, 32, 23, 54);
1133  tbsize_addbutton(&tbsize_results[7], 23, 32, 46, 54);
1134  tbsize_addbutton(&tbsize_results[7], 46, 32, 69, 54);
1135  tbsize_addbutton(&tbsize_results[7], 69, 32, 92, 54);
1136 
1137  tbsize_results[8] = init_tbsize_result(7, 0, 0, 672, 26, 194, 30);
1138  tbsize_addbutton(&tbsize_results[8], 0, 2, 31, 32);
1139  tbsize_addbutton(&tbsize_results[8], 31, 2, 62, 32);
1140  tbsize_addbutton(&tbsize_results[8], 62, 2, 70, 32);
1141  tbsize_addbutton(&tbsize_results[8], 70, 2, 101, 32);
1142  tbsize_addbutton(&tbsize_results[8], 101, 2, 132, 32);
1143  tbsize_addbutton(&tbsize_results[8], 132, 2, 163, 32);
1144  tbsize_addbutton(&tbsize_results[8], 0, 32, 31, 62);
1145 
1146  tbsize_results[9] = init_tbsize_result(7, 0, 0, 672, 64, 194, 30);
1147  tbsize_addbutton(&tbsize_results[9], 0, 2, 31, 32);
1148  tbsize_addbutton(&tbsize_results[9], 31, 2, 62, 32);
1149  tbsize_addbutton(&tbsize_results[9], 62, 2, 70, 32);
1150  tbsize_addbutton(&tbsize_results[9], 70, 2, 101, 32);
1151  tbsize_addbutton(&tbsize_results[9], 101, 2, 132, 32);
1152  tbsize_addbutton(&tbsize_results[9], 132, 2, 163, 32);
1153  tbsize_addbutton(&tbsize_results[9], 0, 32, 31, 62);
1154 
1155  tbsize_results[10] = init_tbsize_result(7, 0, 0, 672, 64, 194, 30);
1156  tbsize_addbutton(&tbsize_results[10], 0, 0, 31, 30);
1157  tbsize_addbutton(&tbsize_results[10], 31, 0, 62, 30);
1158  tbsize_addbutton(&tbsize_results[10], 62, 0, 70, 30);
1159  tbsize_addbutton(&tbsize_results[10], 70, 0, 101, 30);
1160  tbsize_addbutton(&tbsize_results[10], 101, 0, 132, 30);
1161  tbsize_addbutton(&tbsize_results[10], 132, 0, 163, 30);
1162  tbsize_addbutton(&tbsize_results[10], 0, 30, 31, 60);
1163 
1164  tbsize_results[11] = init_tbsize_result(7, 0, 0, 124, 226, 31, 188);
1165  tbsize_addbutton(&tbsize_results[11], 0, 0, 31, 30);
1166  tbsize_addbutton(&tbsize_results[11], 31, 0, 62, 30);
1167  tbsize_addbutton(&tbsize_results[11], 0, 30, 124, 38);
1168  tbsize_addbutton(&tbsize_results[11], 0, 38, 31, 68);
1169  tbsize_addbutton(&tbsize_results[11], 31, 38, 62, 68);
1170  tbsize_addbutton(&tbsize_results[11], 62, 38, 93, 68);
1171  tbsize_addbutton(&tbsize_results[11], 93, 38, 124, 68);
1172 
1173  tbsize_results[12] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22);
1174  tbsize_addbutton(&tbsize_results[12], 0, 2, 23, 24);
1175  tbsize_addbutton(&tbsize_results[12], 23, 2, 46, 24);
1176  tbsize_addbutton(&tbsize_results[12], 46, 2, 54, 24);
1177  tbsize_addbutton(&tbsize_results[12], 54, 2, 77, 24);
1178  tbsize_addbutton(&tbsize_results[12], 77, 2, 100, 24);
1179  tbsize_addbutton(&tbsize_results[12], 100, 2, 123, 24);
1180  tbsize_addbutton(&tbsize_results[12], 123, 2, 146, 24);
1181 
1182  tbsize_results[13] = init_tbsize_result(7, 0, 0, 672, 26, 146, 100);
1183  tbsize_addbutton(&tbsize_results[13], 0, 0, 23, 100);
1184  tbsize_addbutton(&tbsize_results[13], 23, 0, 46, 100);
1185  tbsize_addbutton(&tbsize_results[13], 46, 0, 54, 100);
1186  tbsize_addbutton(&tbsize_results[13], 54, 0, 77, 100);
1187  tbsize_addbutton(&tbsize_results[13], 77, 0, 100, 100);
1188  tbsize_addbutton(&tbsize_results[13], 100, 0, 123, 100);
1189  tbsize_addbutton(&tbsize_results[13], 123, 0, 146, 100);
1190 
1191  tbsize_results[14] = init_tbsize_result(10, 0, 0, 672, 26, 146, 100);
1192  tbsize_addbutton(&tbsize_results[14], 0, 0, 23, 100);
1193  tbsize_addbutton(&tbsize_results[14], 23, 0, 46, 100);
1194  tbsize_addbutton(&tbsize_results[14], 46, 0, 54, 100);
1195  tbsize_addbutton(&tbsize_results[14], 54, 0, 77, 100);
1196  tbsize_addbutton(&tbsize_results[14], 77, 0, 100, 100);
1197  tbsize_addbutton(&tbsize_results[14], 100, 0, 123, 100);
1198  tbsize_addbutton(&tbsize_results[14], 123, 0, 146, 100);
1199  tbsize_addbutton(&tbsize_results[14], 146, 0, 169, 100);
1200  tbsize_addbutton(&tbsize_results[14], 169, 0, 192, 100);
1201  tbsize_addbutton(&tbsize_results[14], 192, 0, 215, 100);
1202 
1203  tbsize_results[15] = init_tbsize_result(11, 0, 0, 672, 26, 238, 39);
1204  tbsize_addbutton(&tbsize_results[15], 0, 0, 23, 23 + fontheight);
1205  tbsize_addbutton(&tbsize_results[15], 23, 0, 46, 23 + fontheight);
1206  tbsize_addbutton(&tbsize_results[15], 46, 0, 54, 23 + fontheight);
1207  tbsize_addbutton(&tbsize_results[15], 54, 0, 77, 23 + fontheight);
1208  tbsize_addbutton(&tbsize_results[15], 77, 0, 100, 23 + fontheight);
1209  tbsize_addbutton(&tbsize_results[15], 100, 0, 123, 23 + fontheight);
1210  tbsize_addbutton(&tbsize_results[15], 123, 0, 146, 23 + fontheight);
1211  tbsize_addbutton(&tbsize_results[15], 146, 0, 169, 23 + fontheight);
1212  tbsize_addbutton(&tbsize_results[15], 169, 0, 192, 23 + fontheight);
1213  tbsize_addbutton(&tbsize_results[15], 192, 0, 215, 23 + fontheight);
1214  tbsize_addbutton(&tbsize_results[15], 215, 0, 238, 23 + fontheight);
1215 
1216  tbsize_results[16] = init_tbsize_result(11, 0, 0, 672, 26, 239, 22);
1217  tbsize_addbutton(&tbsize_results[16], 0, 0, 23, 22);
1218  tbsize_addbutton(&tbsize_results[16], 23, 0, 46, 22);
1219  tbsize_addbutton(&tbsize_results[16], 46, 0, 54, 22);
1220  tbsize_addbutton(&tbsize_results[16], 54, 0, 77, 22);
1221  tbsize_addbutton(&tbsize_results[16], 77, 0, 100, 22);
1222  tbsize_addbutton(&tbsize_results[16], 100, 0, 123, 22);
1223  tbsize_addbutton(&tbsize_results[16], 123, 0, 146, 22);
1224  tbsize_addbutton(&tbsize_results[16], 146, 0, 169, 22);
1225  tbsize_addbutton(&tbsize_results[16], 169, 0, 192, 22);
1226  tbsize_addbutton(&tbsize_results[16], 192, 0, 215, 22);
1227  tbsize_addbutton(&tbsize_results[16], 215, 0, 238, 22);
1228 
1229  buttonwidth = 7 + string_width(STRING1);
1230 
1231  tbsize_results[17] = init_tbsize_result(3, 0, 0, 672, 26, 489, 39);
1232  tbsize_addbutton(&tbsize_results[17], 0, 2, buttonwidth, 25 + fontheight);
1233  tbsize_addbutton(&tbsize_results[17], buttonwidth, 2, 2*buttonwidth + 4, 25 + fontheight);
1234  tbsize_addbutton(&tbsize_results[17], 2*buttonwidth + 4, 2, 3*buttonwidth + 4, 25 + fontheight);
1235 
1236  tbsize_results[18] = init_tbsize_result(6, 0, 0, 672, 104, 978, 24);
1237  tbsize_addbutton(&tbsize_results[18], 0, 2, buttonwidth, 10 + fontheight);
1238  tbsize_addbutton(&tbsize_results[18], buttonwidth, 2, 2*buttonwidth, 10 + fontheight);
1239  tbsize_addbutton(&tbsize_results[18], 2*buttonwidth, 2, 3*buttonwidth, 10 + fontheight);
1240  tbsize_addbutton(&tbsize_results[18], 3*buttonwidth, 2, 4*buttonwidth, 10 + fontheight);
1241  tbsize_addbutton(&tbsize_results[18], 4*buttonwidth, 2, 5*buttonwidth + 4, 10 + fontheight);
1242  tbsize_addbutton(&tbsize_results[18], 5*buttonwidth + 4, 2, 5*buttonwidth + 4 + string_width(STRING2) + 11, 10 + fontheight);
1243 
1244  tbsize_results[19] = init_tbsize_result(6, 0, 0, 672, 28, 978, 38);
1245  tbsize_addbutton(&tbsize_results[19], 0, 0, buttonwidth, 22 + fontheight);
1246  tbsize_addbutton(&tbsize_results[19], buttonwidth, 0, 2*buttonwidth, 22 + fontheight);
1247  tbsize_addbutton(&tbsize_results[19], 2*buttonwidth, 0, 3*buttonwidth, 22 + fontheight);
1248  tbsize_addbutton(&tbsize_results[19], 3*buttonwidth, 0, 4*buttonwidth, 22 + fontheight);
1249  tbsize_addbutton(&tbsize_results[19], 4*buttonwidth, 0, 5*buttonwidth + 4, 22 + fontheight);
1250  tbsize_addbutton(&tbsize_results[19], 5*buttonwidth + 4, 0, 5*buttonwidth + 4 + string_width(STRING2) + 11, 22 + fontheight);
1251 
1252  tbsize_results[20] = init_tbsize_result(3, 0, 0, 672, 100, 239, 102);
1253  tbsize_addbutton(&tbsize_results[20], 0, 2, 100, 102);
1254  tbsize_addbutton(&tbsize_results[20], 100, 2, 139, 102);
1255  tbsize_addbutton(&tbsize_results[20], 139, 2, 239, 102);
1256 
1257  tbsize_results[21] = init_tbsize_result(3, 0, 0, 672, 42, 185, 40);
1258  tbsize_addbutton(&tbsize_results[21], 0, 2, 75, 40);
1259  tbsize_addbutton(&tbsize_results[21], 75, 2, 118, 40);
1260  tbsize_addbutton(&tbsize_results[21], 118, 2, 165 + string_width(STRING2), 40);
1261 
1262  tbsize_results[22] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40);
1263  tbsize_addbutton(&tbsize_results[22], 0, 2, 47 + string_width(STRING2), 40);
1264 
1265  tbsize_results[23] = init_tbsize_result(2, 0, 0, 672, 42, 67, 41);
1266  tbsize_addbutton(&tbsize_results[23], 0, 2, 672, 25 + fontheight);
1267  tbsize_addbutton(&tbsize_results[23], 0, 25 + fontheight, 672, 48 + 2*fontheight);
1268 
1269  tbsize_results[24] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40);
1270  tbsize_addbutton(&tbsize_results[24], 0, 2, 11 + string_width(STRING2), 24);
1271 
1272  tbsize_results[25] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40);
1273  tbsize_addbutton(&tbsize_results[25], 0, 2, 40, 24);
1274 
1275  tbsize_results[26] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40);
1276  tbsize_addbutton(&tbsize_results[26], 0, 2, 40, 24);
1277 
1278  tbsize_results[27] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40);
1279  tbsize_addbutton(&tbsize_results[27], 0, 2, 40, 24);
1280 }
1281 
1282 static void free_tbsize_results(void) {
1283  int i;
1284 
1285  for (i = 0; i < tbsize_results_num; i++)
1286  heap_free(tbsize_results[i].prcButtons);
1288  tbsize_results = NULL;
1289 }
1290 
1291 static int tbsize_numtests = 0;
1292 
1293 typedef struct
1294 {
1299 
1301 {
1302  { 5, 2, { 0, 24, 8, 29 } },
1303  { 20, 1, { 100, 2, 107, 102 } },
1304  { 20, 2, { 107, 2, 207, 102 } }
1305 };
1306 
1308 
1309 #define check_sizes_todo(todomask) { \
1310  RECT rc; \
1311  int buttonCount, i, mask=(todomask); \
1312  tbsize_result_t *res = &tbsize_results[tbsize_numtests]; \
1313  GetClientRect(hToolbar, &rc); \
1314  /*check_rect("client", rc, res->rcClient);*/ \
1315  buttonCount = SendMessageA(hToolbar, TB_BUTTONCOUNT, 0, 0); \
1316  compare(buttonCount, res->nButtons, "%d"); \
1317  for (i=0; i<min(buttonCount, res->nButtons); i++) { \
1318  ok(SendMessageA(hToolbar, TB_GETITEMRECT, i, (LPARAM)&rc) == 1, "TB_GETITEMRECT\n"); \
1319  if (broken(tbsize_alt_numtests < sizeof(tbsize_alt_results)/sizeof(tbsize_alt_results[0]) && \
1320  EqualRect(&rc, &tbsize_alt_results[tbsize_alt_numtests].rcButton))) { \
1321  win_skip("Alternate rect found\n"); \
1322  tbsize_alt_numtests++; \
1323  } else todo_wine_if(mask&1) \
1324  check_rect("button = %d, tbsize_numtests = %d", rc, res->prcButtons[i], i, tbsize_numtests); \
1325  mask >>= 1; \
1326  } \
1327  tbsize_numtests++; \
1328  }
1329 
1330 #define check_sizes() check_sizes_todo(0)
1331 
1332 #endif
1333 
1334 static TBBUTTON buttons1[] = {
1335  {0, 10, TBSTATE_WRAP|TBSTATE_ENABLED, 0, {0, }, 0, -1},
1336  {0, 11, 0, 0, {0, }, 0, -1},
1337 };
1338 static TBBUTTON buttons2[] = {
1339  {0, 20, TBSTATE_ENABLED, 0, {0, }, 0, -1},
1340  {0, 21, TBSTATE_ENABLED, 0, {0, }, 0, -1},
1341 };
1342 static TBBUTTON buttons3[] = {
1343  {0, 30, TBSTATE_ENABLED, 0, {0, }, 0, 0},
1344  {0, 31, TBSTATE_ENABLED, 0, {0, }, 0, 1},
1345  {0, 32, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, 1},
1346  {0, 33, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, (UINT_PTR)STRING2}
1347 };
1348 static TBBUTTON buttons4[] = {
1349  {0, 40, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, (UINT_PTR)STRING2},
1350  {0, 41, TBSTATE_ENABLED, 0, {0, }, 0, (UINT_PTR)STRING2},
1351  {0, 41, TBSTATE_ENABLED, BTNS_SHOWTEXT, {0, }, 0, (UINT_PTR)STRING2}
1352 };
1353 
1354 static void test_sizes(void)
1355 {
1356  HWND hToolbar = NULL;
1357  HIMAGELIST himl, himl2;
1358  TBBUTTONINFOA tbinfo;
1359  TBBUTTON button;
1360  int style;
1361  int i;
1362  int fontheight = system_font_height();
1363 
1365 
1366  rebuild_toolbar_with_buttons(&hToolbar);
1367  style = GetWindowLongA(hToolbar, GWL_STYLE);
1368  ok(style == (WS_CHILD|WS_VISIBLE|CCS_TOP), "Invalid style %x\n", style);
1369  check_sizes();
1370  /* the TBSTATE_WRAP makes a second row */
1371  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons1);
1372  check_sizes();
1373  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
1374  check_sizes();
1375  SendMessageA(hToolbar, TB_GETBUTTON, 5, (LPARAM)&button);
1376  ok(button.fsState == (TBSTATE_WRAP|TBSTATE_ENABLED), "got %08x\n", button.fsState);
1377  /* after setting the TBSTYLE_WRAPABLE the TBSTATE_WRAP is ignored */
1379  check_sizes();
1380  SendMessageA(hToolbar, TB_GETBUTTON, 5, (LPARAM)&button);
1381  ok(button.fsState == TBSTATE_ENABLED, "got %08x\n", button.fsState);
1382  /* adding new buttons with TBSTYLE_WRAPABLE doesn't add a new row */
1383  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons1);
1384  check_sizes();
1385  /* only after adding enough buttons the bar will be wrapped on a
1386  * separator and then on the first button */
1387  for (i=0; i<15; i++)
1388  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons1);
1389  check_sizes_todo(0x4);
1390  SendMessageA(hToolbar, TB_GETBUTTON, 31, (LPARAM)&button);
1391  ok(button.fsState == (TBSTATE_WRAP|TBSTATE_ENABLED), "got %08x\n", button.fsState);
1392  SetWindowLongA(hToolbar, GWL_STYLE, style);
1393  SendMessageA(hToolbar, TB_GETBUTTON, 31, (LPARAM)&button);
1394  ok(button.fsState == TBSTATE_ENABLED, "got %08x\n", button.fsState);
1395 
1396  rebuild_toolbar_with_buttons(&hToolbar);
1397  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons1);
1398  /* setting the buttons vertical will only change the window client size */
1399  SetWindowLongA(hToolbar, GWL_STYLE, style | CCS_VERT);
1400  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
1401  check_sizes_todo(0x3c);
1402  /* with a TBSTYLE_WRAPABLE a wrapping will occur on the separator */
1404  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
1405  check_sizes_todo(0x7c);
1406 
1407  rebuild_toolbar_with_buttons(&hToolbar);
1408  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons1);
1409  /* a TB_SETBITMAPSIZE changes button sizes*/
1410  SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(24, 24));
1411  check_sizes();
1412 
1413  /* setting a TBSTYLE_FLAT doesn't change anything - even after a TB_AUTOSIZE */
1415  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
1416  check_sizes();
1417  /* but after a TB_SETBITMAPSIZE the top margins is changed */
1418  SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(20, 20));
1419  SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(24, 24));
1420  check_sizes();
1421  /* some vertical toolbar sizes */
1423  check_sizes_todo(0x7c);
1424 
1425  rebuild_toolbar_with_buttons(&hToolbar);
1427  /* newly added buttons will be use the previous margin */
1428  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons2);
1429  check_sizes();
1430  /* TB_SETBUTTONSIZE can't be used to reduce the size of a button below the default */
1431  check_button_size(hToolbar, 23, 22);
1432  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(22, 21))==1, "TB_SETBUTTONSIZE\n");
1433  check_button_size(hToolbar, 23, 22);
1434  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(5, 100))==1, "TB_SETBUTTONSIZE\n");
1435  check_button_size(hToolbar, 23, 100);
1436  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3))==1, "TB_SETBUTTONSIZE\n");
1437  check_button_size(hToolbar, 23, 22);
1438  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(5, 100))==1, "TB_SETBUTTONSIZE\n");
1439  check_button_size(hToolbar, 23, 100);
1440  check_sizes();
1441  /* add some buttons with non-default sizes */
1442  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons2);
1443  SendMessageA(hToolbar, TB_INSERTBUTTONA, -1, (LPARAM)&buttons2[0]);
1444  check_sizes();
1445  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[0]);
1446  /* TB_ADDSTRINGA resets the size */
1447  SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM) STRING0 "\0" STRING1 "\0");
1448  check_button_size(hToolbar, 23, 23 + fontheight);
1449  check_sizes();
1450  /* TB_SETBUTTONSIZE can be used to crop the text */
1451  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3));
1452  check_button_size(hToolbar, 23, 22);
1453  check_sizes();
1454  /* the default size is bitmap size + padding */
1455  SendMessageA(hToolbar, TB_SETPADDING, 0, MAKELONG(1, 1));
1456  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3));
1457  check_button_size(hToolbar, 17, 17);
1458  SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(3, 3));
1459  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3));
1460  check_button_size(hToolbar, 4, 4);
1461 
1462  rebuild_toolbar(&hToolbar);
1463  /* sending a TB_SETBITMAPSIZE with the same sizes is enough to make the button smaller */
1464  check_button_size(hToolbar, 23, 22);
1465  SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(16, 15));
1466  check_button_size(hToolbar, 23, 21);
1467  /* -1 in TB_SETBITMAPSIZE is a special code meaning that the coordinate shouldn't be changed */
1468  add_128x15_bitmap(hToolbar, 16);
1469  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(14, -1)), "TB_SETBITMAPSIZE failed\n");
1470  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 21), "%x");
1471  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(-1, 12)), "TB_SETBITMAPSIZE failed\n");
1472  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 18), "%x");
1473  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(-1, -1)), "TB_SETBITMAPSIZE failed\n");
1474  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(21, 18), "%x");
1475  /* check the imagelist */
1476  InvalidateRect(hToolbar, NULL, TRUE);
1477  UpdateWindow(hToolbar);
1478  CHECK_IMAGELIST(16, 14, 12);
1479 
1480  rebuild_toolbar(&hToolbar);
1481  SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)STRING0 "\0" STRING1 "\0");
1482  /* the height is increased after a TB_ADDSTRINGA */
1483  check_button_size(hToolbar, 23, 23 + fontheight);
1484  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100));
1485  /* if a string is in the pool, even adding a button without a string resets the size */
1486  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons2[0]);
1487  check_button_size(hToolbar, 23, 22);
1488  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100));
1489  /* an BTNS_AUTOSIZE button is also considered when computing the new size */
1490  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[2]);
1491  check_button_size(hToolbar, 7 + string_width(STRING1), 23 + fontheight);
1492  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[0]);
1493  check_sizes();
1494  /* delete button doesn't change the buttons size */
1495  SendMessageA(hToolbar, TB_DELETEBUTTON, 2, 0);
1496  SendMessageA(hToolbar, TB_DELETEBUTTON, 1, 0);
1497  check_button_size(hToolbar, 7 + string_width(STRING1), 23 + fontheight);
1498  /* TB_INSERTBUTTONAS will */
1499  SendMessageA(hToolbar, TB_INSERTBUTTONA, 1, (LPARAM)&buttons2[0]);
1500  check_button_size(hToolbar, 23, 22);
1501 
1502  /* TB_HIDEBUTTON and TB_MOVEBUTTON doesn't force a recalc */
1503  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100));
1504  ok(SendMessageA(hToolbar, TB_MOVEBUTTON, 0, 1), "TB_MOVEBUTTON failed\n");
1505  check_button_size(hToolbar, 100, 100);
1506  ok(SendMessageA(hToolbar, TB_HIDEBUTTON, 20, TRUE), "TB_HIDEBUTTON failed\n");
1507  check_button_size(hToolbar, 100, 100);
1508  /* however changing the hidden flag with TB_SETSTATE does */
1509  ok(SendMessageA(hToolbar, TB_SETSTATE, 20, TBSTATE_ENABLED|TBSTATE_HIDDEN), "TB_SETSTATE failed\n");
1510  check_button_size(hToolbar, 100, 100);
1511  ok(SendMessageA(hToolbar, TB_SETSTATE, 20, TBSTATE_ENABLED), "TB_SETSTATE failed\n");
1512  check_button_size(hToolbar, 23, 22);
1513 
1514  /* TB_SETIMAGELIST always changes the height but the width only if necessary */
1515  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100));
1516  himl = pImageList_LoadImageA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(IDB_BITMAP_80x15),
1518  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
1519  check_button_size(hToolbar, 100, 21);
1520  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100));
1521  check_button_size(hToolbar, 100, 100);
1522  /* But there are no update when we change imagelist, and image sizes are the same */
1523  himl2 = pImageList_LoadImageA(GetModuleHandleA(NULL), (LPCSTR)MAKEINTRESOURCE(IDB_BITMAP_128x15),
1525  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LRESULT)himl2) == (LRESULT)himl, "TB_SETIMAGELIST failed\n");
1526  check_button_size(hToolbar, 100, 100);
1527  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(1, 1));
1528  check_button_size(hToolbar, 27, 21);
1529  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, 0) == (LRESULT)himl2, "TB_SETIMAGELIST failed\n");
1530  check_button_size(hToolbar, 27, 7);
1531  SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(1, 1));
1532  check_button_size(hToolbar, 8, 7)
1533  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
1534  check_button_size(hToolbar, 27, 21)
1535  /* the text is taken into account */
1536  SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)STRING0 "\0" STRING1 "\0");
1537  SendMessageA(hToolbar, TB_ADDBUTTONSA, 4, (LPARAM)buttons3);
1538  check_button_size(hToolbar, 7 + string_width(STRING1), 22 + fontheight);
1539  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, 0) == (LRESULT)himl, "TB_SETIMAGELIST failed\n");
1540  check_button_size(hToolbar, 7 + string_width(STRING1), 8 + fontheight);
1541  /* the style change also comes into effect */
1542  check_sizes();
1544  ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n");
1545  check_sizes_todo(0x30); /* some small problems with BTNS_AUTOSIZE button sizes */
1546 
1547  rebuild_toolbar(&hToolbar);
1548  pImageList_Destroy(himl);
1549  pImageList_Destroy(himl2);
1550 
1551  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]);
1552  check_button_size(hToolbar, 7 + string_width(STRING2), 23 + fontheight);
1553  SendMessageA(hToolbar, TB_DELETEBUTTON, 0, 0);
1554  check_button_size(hToolbar, 7 + string_width(STRING2), 23 + fontheight);
1555 
1556  rebuild_toolbar(&hToolbar);
1557 
1558  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELPARAM(32, 32)) == 1, "TB_SETBITMAPSIZE failed\n");
1559  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(100, 100)) == 1, "TB_SETBUTTONSIZE failed\n");
1560  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons2[0]) == 1, "TB_ADDBUTTONSA failed\n");
1561  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[2]) == 1, "TB_ADDBUTTONSA failed\n");
1562  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[0]) == 1, "TB_ADDBUTTONSA failed\n");
1563  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1564  check_sizes();
1565 
1566  rebuild_toolbar(&hToolbar);
1568  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELPARAM(32, 32)) == 1, "TB_SETBITMAPSIZE failed\n");
1569  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(100, 100)) == 1, "TB_SETBUTTONSIZE failed\n");
1570  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons2[0]) == 1, "TB_ADDBUTTONSA failed\n");
1571  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[2]) == 1, "TB_ADDBUTTONSA failed\n");
1572  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]) == 1, "TB_ADDBUTTONSA failed\n");
1573  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1574  check_sizes_todo(0xff);
1575 
1576  rebuild_toolbar(&hToolbar);
1578  ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELPARAM(32, 32)) == 1, "TB_SETBITMAPSIZE failed\n");
1579  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(100, 100)) == 1, "TB_SETBUTTONSIZE failed\n");
1580  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]) == 1, "TB_ADDBUTTONSA failed\n");
1581  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1582  check_sizes();
1583 
1584  rebuild_toolbar(&hToolbar);
1586  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]) == 1, "TB_ADDBUTTONSA failed\n");
1587  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]) == 1, "TB_ADDBUTTONSA failed\n");
1588  tbinfo.cx = 672;
1589  tbinfo.cbSize = sizeof(TBBUTTONINFOA);
1590  tbinfo.dwMask = TBIF_SIZE | TBIF_BYINDEX;
1591  if (SendMessageA(hToolbar, TB_SETBUTTONINFOA, 0, (LPARAM)&tbinfo))
1592  {
1593  ok(SendMessageA(hToolbar, TB_SETBUTTONINFOA, 1, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFOA failed\n");
1594  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
1595  check_sizes();
1596  }
1597  else /* TBIF_BYINDEX probably not supported, confirm that this was the reason for the failure */
1598  {
1599  tbinfo.dwMask = TBIF_SIZE;
1600  ok(SendMessageA(hToolbar, TB_SETBUTTONINFOA, 33, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFOA failed\n");
1601  tbsize_numtests++;
1602  }
1603 
1604  /* Single BTNS_AUTOSIZE button with string. */
1605  rebuild_toolbar(&hToolbar);
1606  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons4[0]) == 1, "TB_ADDBUTTONSA failed\n");
1607  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(40, 20)) == 1, "TB_SETBUTTONSIZE failed\n");
1608  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1609  check_sizes();
1610 
1611  /* Single non-BTNS_AUTOSIZE button with string. */
1612  rebuild_toolbar(&hToolbar);
1613  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons4[1]) == 1, "TB_ADDBUTTONSA failed\n");
1614  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(40, 20)) == 1, "TB_SETBUTTONSIZE failed\n");
1615  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1616  check_sizes();
1617 
1618  /* Single non-BTNS_AUTOSIZE button with string with TBSTYLE_EX_MIXEDBUTTONS set. */
1619  rebuild_toolbar(&hToolbar);
1621  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons4[1]) == 1, "TB_ADDBUTTONSA failed\n");
1622  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(40, 20)) == 1, "TB_SETBUTTONSIZE failed\n");
1623  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1624  check_sizes();
1625 
1626  /* Single non-BTNS_AUTOSIZE, BTNS_SHOWTEXT button with string with TBSTYLE_EX_MIXEDBUTTONS set. */
1627  rebuild_toolbar(&hToolbar);
1629  ok(SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons4[2]) == 1, "TB_ADDBUTTONSA failed\n");
1630  ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELPARAM(40, 20)) == 1, "TB_SETBUTTONSIZE failed\n");
1631  SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0 );
1632  check_sizes();
1633 
1635  DestroyWindow(hToolbar);
1636 }
1637 
1638 /* Toolbar control has two ways of reacting to a change. We call them a
1639  * relayout and recalc. A recalc forces a recompute of values like button size
1640  * and top margin (the latter in comctl32 <v6), while a relayout uses the cached
1641  * values. This functions creates a flat toolbar with a top margin of a non-flat
1642  * toolbar. We will notice a recalc, as it will recompte the top margin and
1643  * change it to zero*/
1644 static void prepare_recalc_test(HWND *phToolbar)
1645 {
1646  RECT rect;
1647  rebuild_toolbar_with_buttons(phToolbar);
1648  SetWindowLongA(*phToolbar, GWL_STYLE,
1649  GetWindowLongA(*phToolbar, GWL_STYLE) | TBSTYLE_FLAT);
1650  SendMessageA(*phToolbar, TB_GETITEMRECT, 1, (LPARAM)&rect);
1651  ok(rect.top == 2, "Test will make no sense because initial top is %d instead of 2\n",
1652  rect.top);
1653 }
1654 
1655 static BOOL did_recalc(HWND hToolbar)
1656 {
1657  RECT rect;
1658  SendMessageA(hToolbar, TB_GETITEMRECT, 1, (LPARAM)&rect);
1659  ok(rect.top == 2 || rect.top == 0, "Unexpected top margin %d in recalc test\n",
1660  rect.top);
1661  return (rect.top == 0);
1662 }
1663 
1664 /* call after a recalc did happen to return to an unstable state */
1665 static void restore_recalc_state(HWND hToolbar)
1666 {
1667  RECT rect;
1668  /* return to style with a 2px top margin */
1669  SetWindowLongA(hToolbar, GWL_STYLE,
1670  SendMessageA(hToolbar, TB_GETSTYLE, 0, 0) & ~TBSTYLE_FLAT);
1671  /* recalc */
1672  SendMessageA(hToolbar, TB_ADDBUTTONSA, 1, (LPARAM)&buttons3[3]);
1673  /* top margin will be 0px if a recalc occurs */
1674  SetWindowLongA(hToolbar, GWL_STYLE,
1675  SendMessageA(hToolbar, TB_GETSTYLE, 0, 0) | TBSTYLE_FLAT);
1676  /* safety check */
1677  SendMessageA(hToolbar, TB_GETITEMRECT, 1, (LPARAM)&rect);
1678  ok(rect.top == 2, "Test will make no sense because initial top is %d instead of 2\n",
1679  rect.top);
1680 }
1681 
1682 static void test_recalc(void)
1683 {
1684  HWND hToolbar = NULL;
1685  TBBUTTONINFOA bi;
1686  CHAR test[] = "Test";
1687  const int EX_STYLES_COUNT = 5;
1688  int i;
1689  BOOL recalc;
1690  DWORD style;
1691 
1692  /* Like TB_ADDBUTTONSA tested in test_sized, inserting a button without text
1693  * results in a relayout, while adding one with text forces a recalc */
1694  prepare_recalc_test(&hToolbar);
1695  SendMessageA(hToolbar, TB_INSERTBUTTONA, 1, (LPARAM)&buttons3[0]);
1696  recalc = did_recalc(hToolbar);
1697  ok(!recalc, "Unexpected recalc - adding button without text\n");
1698 
1699  prepare_recalc_test(&hToolbar);
1700  SendMessageA(hToolbar, TB_INSERTBUTTONA, 1, (LPARAM)&buttons3[3]);
1701  recalc = did_recalc(hToolbar);
1702  ok(recalc, "Expected a recalc - adding button with text\n");
1703 
1704  /* TB_SETBUTTONINFOA, even when adding a text, results only in a relayout */
1705  prepare_recalc_test(&hToolbar);
1706  bi.cbSize = sizeof(bi);
1707  bi.dwMask = TBIF_TEXT;
1708  bi.pszText = test;
1709  SendMessageA(hToolbar, TB_SETBUTTONINFOA, 1, (LPARAM)&bi);
1710  recalc = did_recalc(hToolbar);
1711  ok(!recalc, "Unexpected recalc - setting a button text\n");
1712 
1713  /* most extended styled doesn't force a recalc (testing all the bits gives
1714  * the same results, but prints some ERRs while testing) */
1715  for (i = 0; i < EX_STYLES_COUNT; i++)
1716  {
1717  if (i == 1 || i == 3) /* an undoc style and TBSTYLE_EX_MIXEDBUTTONS */
1718  continue;
1719  prepare_recalc_test(&hToolbar);
1720  expect(0, (int)SendMessageA(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0));
1721  SendMessageA(hToolbar, TB_SETEXTENDEDSTYLE, 0, (1 << i));
1722  recalc = did_recalc(hToolbar);
1723  ok(!recalc, "Unexpected recalc - setting bit %d\n", i);
1724  SendMessageA(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0);
1725  recalc = did_recalc(hToolbar);
1726  ok(!recalc, "Unexpected recalc - clearing bit %d\n", i);
1727  expect(0, (int)SendMessageA(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0));
1728  }
1729 
1730  /* TBSTYLE_EX_MIXEDBUTTONS does a recalc on change */
1731  prepare_recalc_test(&hToolbar);
1733  recalc = did_recalc(hToolbar);
1734  if (recalc)
1735  {
1736  ok(recalc, "Expected a recalc - setting TBSTYLE_EX_MIXEDBUTTONS\n");
1737  restore_recalc_state(hToolbar);
1739  recalc = did_recalc(hToolbar);
1740  ok(!recalc, "Unexpected recalc - setting TBSTYLE_EX_MIXEDBUTTONS again\n");
1741  restore_recalc_state(hToolbar);
1742  SendMessageA(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0);
1743  recalc = did_recalc(hToolbar);
1744  ok(recalc, "Expected a recalc - clearing TBSTYLE_EX_MIXEDBUTTONS\n");
1745  }
1746  else win_skip( "No recalc on TBSTYLE_EX_MIXEDBUTTONS\n" );
1747 
1748  /* undocumented exstyle 0x2 seems to change the top margin, which
1749  * interferes with these tests */
1750 
1751  /* Show that a change in TBSTYLE_WRAPABLE causes a recalc */
1752  prepare_recalc_test(&hToolbar);
1753  style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0);
1754  SendMessageA(hToolbar, TB_SETSTYLE, 0, style);
1755  recalc = did_recalc(hToolbar);
1756  ok(!recalc, "recalc %d\n", recalc);
1757 
1759  recalc = did_recalc(hToolbar);
1760  ok(!recalc, "recalc %d\n", recalc);
1761 
1763  recalc = did_recalc(hToolbar);
1764  ok(recalc, "recalc %d\n", recalc);
1765  restore_recalc_state(hToolbar);
1766 
1768  recalc = did_recalc(hToolbar);
1769  ok(!recalc, "recalc %d\n", recalc);
1770 
1771  SendMessageA(hToolbar, TB_SETSTYLE, 0, style);
1772  recalc = did_recalc(hToolbar);
1773  ok(recalc, "recalc %d\n", recalc);
1774  restore_recalc_state(hToolbar);
1775 
1776  /* Changing CCS_VERT does not recalc */
1777  SendMessageA(hToolbar, TB_SETSTYLE, 0, style | CCS_VERT);
1778  recalc = did_recalc(hToolbar);
1779  ok(!recalc, "recalc %d\n", recalc);
1780  restore_recalc_state(hToolbar);
1781 
1782  SendMessageA(hToolbar, TB_SETSTYLE, 0, style);
1783  recalc = did_recalc(hToolbar);
1784  ok(!recalc, "recalc %d\n", recalc);
1785  restore_recalc_state(hToolbar);
1786 
1787  /* Setting the window's style directly also causes recalc */
1789  recalc = did_recalc(hToolbar);
1790  ok(recalc, "recalc %d\n", recalc);
1791 
1792  DestroyWindow(hToolbar);
1793 }
1794 
1795 static void test_getbuttoninfo(void)
1796 {
1797  HWND hToolbar = NULL;
1798  TBBUTTONINFOW tbiW;
1799  TBBUTTONINFOA tbi;
1800  int i;
1801 
1802  rebuild_toolbar_with_buttons(&hToolbar);
1803  for (i = 0; i < 128; i++)
1804  {
1805  int ret;
1806 
1807  tbi.cbSize = i;
1808  tbi.dwMask = TBIF_COMMAND;
1809  ret = (int)SendMessageA(hToolbar, TB_GETBUTTONINFOA, 1, (LPARAM)&tbi);
1810  if (i == sizeof(TBBUTTONINFOA)) {
1811  compare(ret, 0, "%d");
1812  } else {
1813  compare(ret, -1, "%d");
1814  }
1815  }
1816 
1817  /* TBIF_TEXT with NULL pszText */
1818  memset(&tbiW, 0, sizeof(tbiW));
1819  tbiW.cbSize = sizeof(tbiW);
1821  i = SendMessageA(hToolbar, TB_GETBUTTONINFOW, 1, (LPARAM)&tbiW);
1822  ok(i == 1, "Got index %d\n", i);
1823 
1824  DestroyWindow(hToolbar);
1825 }
1826 
1827 static void test_createtoolbarex(void)
1828 {
1829  HWND hToolbar;
1830  TBBUTTON btns[3];
1831  ZeroMemory(&btns, sizeof(btns));
1832 
1833  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1834  3, 20, 20, 16, 16, sizeof(TBBUTTON));
1835  CHECK_IMAGELIST(16, 20, 20);
1836  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0x1a001b, "%x");
1837  DestroyWindow(hToolbar);
1838 
1839  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1840  3, 4, 4, 16, 16, sizeof(TBBUTTON));
1841  CHECK_IMAGELIST(32, 4, 4);
1842  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0xa000b, "%x");
1843  DestroyWindow(hToolbar);
1844 
1845  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1846  3, 0, 8, 12, 12, sizeof(TBBUTTON));
1847  CHECK_IMAGELIST(16, 12, 12);
1848  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0x120013, "%x");
1849  DestroyWindow(hToolbar);
1850 
1851  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1852  3, -1, 8, 12, 12, sizeof(TBBUTTON));
1853  CHECK_IMAGELIST(16, 12, 8);
1854  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0xe0013, "%x");
1855  DestroyWindow(hToolbar);
1856 
1857  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1858  3, -1, 8, -1, 12, sizeof(TBBUTTON));
1859  CHECK_IMAGELIST(16, 16, 8);
1860  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0xe0017, "%x");
1861  DestroyWindow(hToolbar);
1862 
1863  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1864  3, 0, 0, 12, -1, sizeof(TBBUTTON));
1865  CHECK_IMAGELIST(16, 12, 16);
1866  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0x160013, "%x");
1867  DestroyWindow(hToolbar);
1868 
1869  hToolbar = pCreateToolbarEx(hMainWnd, WS_VISIBLE, 1, 16, GetModuleHandleA(NULL), IDB_BITMAP_128x15, btns,
1870  3, 0, 0, 0, 12, sizeof(TBBUTTON));
1871  CHECK_IMAGELIST(16, 16, 16);
1872  compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), 0x160017, "%x");
1873  DestroyWindow(hToolbar);
1874 }
1875 
1876 static void test_dispinfo(void)
1877 {
1878  HWND hToolbar = NULL;
1879  const TBBUTTON buttons_disp[] = {
1880  {-1, 20, TBSTATE_ENABLED, 0, {0, }, 0, -1},
1881  {0, 21, TBSTATE_ENABLED, 0, {0, }, 0, -1},
1882  };
1883  BOOL ret;
1884 
1885  rebuild_toolbar(&hToolbar);
1887  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons_disp);
1889  /* Some TBN_GETDISPINFO tests will be done in MyWnd_Notify function.
1890  * We will receive TBN_GETDISPINFOW even if the control is ANSI */
1891  compare((BOOL)SendMessageA(hToolbar, CCM_GETUNICODEFORMAT, 0, 0), 0, "%d");
1892  ShowWindow(hToolbar, SW_SHOW);
1893  UpdateWindow(hToolbar);
1894 
1895  ret = (BOOL)SendMessageA(hToolbar, CCM_SETUNICODEFORMAT, TRUE, 0);
1896  compare(ret, FALSE, "%d");
1897  compare(SendMessageA(hToolbar, CCM_GETUNICODEFORMAT, 0, 0), 1L, "%ld");
1898  InvalidateRect(hToolbar, NULL, FALSE);
1899  UpdateWindow(hToolbar);
1900 
1901  ret = (BOOL)SendMessageA(hToolbar, CCM_SETUNICODEFORMAT, FALSE, 0);
1902  compare(ret, TRUE, "%d");
1903  compare(SendMessageA(hToolbar, CCM_GETUNICODEFORMAT, 0, 0), 0L, "%ld");
1904  InvalidateRect(hToolbar, NULL, FALSE);
1905  UpdateWindow(hToolbar);
1906 
1907  DestroyWindow(hToolbar);
1909 }
1910 
1911 typedef struct
1912 {
1913  int nRows;
1916 } tbrows_result_t;
1917 
1919 {
1920  {1, TRUE, 1}, /* 0: Simple case 9 in a row */
1921  {2, TRUE, 2}, /* 1: Another simple case 5 on one row, 4 on another*/
1922  {3, FALSE, 3}, /* 2: 3 lines - should be 3 lines of 3 buttons */
1923  {8, FALSE, 5}, /* 3: 8 lines - should be 5 lines of 2 buttons */
1924  {8, TRUE, 9}, /* 4: 8 lines but grow - should be 9 lines */
1925  {1, TRUE, 1} /* 5: Back to simple case */
1926 };
1927 
1928 static void test_setrows(void)
1929 {
1930  TBBUTTON buttons[9];
1931  HWND hToolbar;
1932  DWORD i;
1933 
1934  for (i=0; i<9; i++)
1936 
1937  /* Test 1 - 9 buttons */
1938  hToolbar = pCreateToolbarEx(hMainWnd,
1940  | CCS_NOMOVEY | CCS_TOP,
1941  0,
1942  0, NULL, 0,
1943  buttons, sizeof(buttons)/sizeof(buttons[0]),
1944  20, 20, 0, 0, sizeof(TBBUTTON));
1945  ok(hToolbar != NULL, "Toolbar creation\n");
1946  ok(SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
1947 
1948  /* test setting rows to each of 1-10 with bLarger true and false */
1949  for (i=0; i<(sizeof(tbrows_results) / sizeof(tbrows_result_t)); i++) {
1950  RECT rc;
1951  int rows;
1952 
1953  memset(&rc, 0xCC, sizeof(rc));
1954  SendMessageA(hToolbar, TB_SETROWS,
1956  (LPARAM) &rc);
1957 
1958  rows = SendMessageA(hToolbar, TB_GETROWS, MAKELONG(0,0), MAKELONG(0,0));
1959  ok(rows == tbrows_results[i].expectedRows,
1960  "[%d] Unexpected number of rows %d (expected %d)\n", i, rows,
1961  tbrows_results[i].expectedRows);
1962  }
1963 
1964  DestroyWindow(hToolbar);
1965 }
1966 
1967 static void test_getstring(void)
1968 {
1969  HWND hToolbar = NULL;
1970  char str[10];
1971  WCHAR strW[10];
1972  static const char answer[] = "STR";
1973  static const WCHAR answerW[] = { 'S','T','R',0 };
1974  INT r;
1975 
1977  ok(hToolbar != NULL, "Toolbar creation problem\n");
1978 
1979  r = SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(0, 0), 0);
1980  if (r == 0)
1981  {
1982  win_skip("TB_GETSTRINGA and TB_GETSTRINGW need 5.80\n");
1983  DestroyWindow(hToolbar);
1984  return;
1985  }
1986  expect(-1, r);
1987  r = SendMessageW(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), 0);
1988  expect(-1, r);
1989  r = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)answer);
1990  expect(0, r);
1991  r = SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(0, 0), 0);
1992  expect(lstrlenA(answer), r);
1993  r = SendMessageW(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), 0);
1994  expect(lstrlenA(answer), r);
1995  r = SendMessageA(hToolbar, TB_GETSTRINGA, MAKEWPARAM(sizeof(str), 0), (LPARAM)str);
1996  expect(lstrlenA(answer), r);
1997  expect(0, lstrcmpA(answer, str));
1998  r = SendMessageW(hToolbar, TB_GETSTRINGW, MAKEWPARAM(sizeof(strW), 0), (LPARAM)strW);
1999  expect(lstrlenA(answer), r);
2000  expect(0, lstrcmpW(answerW, strW));
2001 
2002  DestroyWindow(hToolbar);
2003 }
2004 
2005 static void test_tooltip(void)
2006 {
2007  HWND hToolbar = NULL;
2008  const TBBUTTON buttons_disp[] = {
2009  {-1, 20, TBSTATE_ENABLED, 0, {0, }, 0, -1},
2010  {0, 21, TBSTATE_ENABLED, 0, {0, }, 0, -1},
2011  };
2012  NMTTDISPINFOW nmtti;
2013  HWND tooltip;
2014 
2015  rebuild_toolbar(&hToolbar);
2016 
2017  SendMessageA(hToolbar, TB_ADDBUTTONSA, 2, (LPARAM)buttons_disp);
2018 
2019  /* W used to get through toolbar code that assumes tooltip is always Unicode */
2020  memset(&nmtti, 0, sizeof(nmtti));
2021  nmtti.hdr.code = TTN_GETDISPINFOW;
2022  nmtti.hdr.idFrom = 20;
2023 
2024  SendMessageA(hToolbar, CCM_SETUNICODEFORMAT, FALSE, 0);
2025 
2027  SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
2029  "dispinfo from tooltip", TRUE);
2030 
2032  SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
2034 
2035  DestroyWindow(hToolbar);
2036 
2037  /* TBSTYLE_TOOLTIPS */
2038  hToolbar = CreateWindowExA(0, TOOLBARCLASSNAMEA, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
2040  tooltip = (HWND)SendMessageA(hToolbar, TB_GETTOOLTIPS, 0, 0);
2041  ok(tooltip == NULL, "got %p\n", tooltip);
2042  DestroyWindow(hToolbar);
2043 }
2044 
2045 static void test_get_set_style(void)
2046 {
2047  TBBUTTON buttons[9];
2048  DWORD style, style2, ret;
2049  HWND hToolbar;
2050  int i;
2051 
2052  for (i=0; i<9; i++)
2055  MakeButton(buttons+6, 1006, TBSTYLE_SEP, 0);
2056 
2057  hToolbar = pCreateToolbarEx(hMainWnd,
2060  100,
2061  0, NULL, 0,
2062  buttons, sizeof(buttons)/sizeof(buttons[0]),
2063  0, 0, 20, 16, sizeof(TBBUTTON));
2064  ok(hToolbar != NULL, "Toolbar creation\n");
2065  SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000");
2066 
2067  style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0);
2068  style2 = GetWindowLongA(hToolbar, GWL_STYLE);
2069 todo_wine
2070  ok(style == style2, "got 0x%08x, expected 0x%08x\n", style, style2);
2071 
2072  /* try to alter common window bits */
2073  style2 |= WS_BORDER;
2074  ret = SendMessageA(hToolbar, TB_SETSTYLE, 0, style2);
2075  ok(ret == 0, "got %d\n", ret);
2076  style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0);
2077  style2 = GetWindowLongA(hToolbar, GWL_STYLE);
2078  ok((style != style2) && (style == (style2 | WS_BORDER)),
2079  "got 0x%08x, expected 0x%08x\n", style, style2);
2080  ok(style & WS_BORDER, "got 0x%08x\n", style);
2081 
2082  /* now styles are the same, alter window style */
2083  ret = SendMessageA(hToolbar, TB_SETSTYLE, 0, style2);
2084  ok(ret == 0, "got %d\n", ret);
2085  style2 |= WS_BORDER;
2086  SetWindowLongA(hToolbar, GWL_STYLE, style2);
2087  style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0);
2088  ok(style == style2, "got 0x%08x, expected 0x%08x\n", style, style2);
2089 
2090  DestroyWindow(hToolbar);
2091 }
2092 
2093 static HHOOK g_tbhook;
2095 
2096 DEFINE_EXPECT(g_hook_create);
2097 DEFINE_EXPECT(g_hook_WM_NCCREATE);
2098 DEFINE_EXPECT(g_hook_WM_CREATE);
2099 
2101 {
2103  LRESULT ret;
2104  DWORD style;
2105 
2106  if (msg == WM_NCCREATE)
2107  {
2108  if (g_toolbar == hwnd)
2109  {
2110  CHECK_EXPECT2(g_hook_WM_NCCREATE);
2111  g_toolbar = hwnd;
2112  ret = CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
2113 
2114  /* control is already set up */
2115  style = SendMessageA(hwnd, TB_GETSTYLE, 0, 0);
2116  ok(style != 0, "got %x\n", style);
2117 
2119  ok((style & TBSTYLE_TOOLTIPS) == 0, "got 0x%08x\n", style);
2122  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%08x\n", style);
2123 
2124  return ret;
2125  }
2126  }
2127  else if (msg == WM_CREATE)
2128  {
2130 
2131  if (g_toolbar == hwnd)
2132  {
2133  CHECK_EXPECT2(g_hook_WM_CREATE);
2134 
2136  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%08x\n", style);
2137 
2138  /* test if toolbar-specific messages are already working before WM_CREATE */
2139  style = SendMessageA(hwnd, TB_GETSTYLE, 0, 0);
2140  ok(style != 0, "got %x\n", style);
2141  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%x\n", style);
2142  ok((cs->style & TBSTYLE_TOOLTIPS) == 0, "0x%08x\n", cs->style);
2143 
2144  ret = CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
2145 
2147  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%08x\n", style);
2148 
2149  /* test if toolbar-specific messages are already working before WM_CREATE */
2150  style = SendMessageA(hwnd, TB_GETSTYLE, 0, 0);
2151  ok(style != 0, "got %x\n", style);
2152  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%x\n", style);
2153 
2154  return ret;
2155  }
2156  }
2157 
2158  return CallWindowProcA(oldproc, hwnd, msg, wParam, lParam);
2159 }
2160 
2162 {
2163  if (code == HCBT_CREATEWND)
2164  {
2165  HWND hwnd = (HWND)wParam;
2166 
2167  if (!g_toolbar)
2168  {
2169  WNDPROC oldproc;
2170 
2171  CHECK_EXPECT2(g_hook_create);
2172  g_toolbar = hwnd;
2173  /* subclass */
2176  }
2177  return 0;
2178  }
2179 
2181 }
2182 
2183 static void test_create(void)
2184 {
2185  HWND hwnd, tooltip;
2186  DWORD style;
2187 
2189 
2190  SET_EXPECT(g_hook_create);
2191  SET_EXPECT(g_hook_WM_NCCREATE);
2192  SET_EXPECT(g_hook_WM_CREATE);
2193 
2196 
2197  CHECK_CALLED(g_hook_create);
2198  CHECK_CALLED(g_hook_WM_NCCREATE);
2199  CHECK_CALLED(g_hook_WM_CREATE);
2200 
2202  ok((style & TBSTYLE_TOOLTIPS) == TBSTYLE_TOOLTIPS, "got 0x%08x\n", style);
2203 
2204  tooltip = (HWND)SendMessageA(hwnd, TB_GETTOOLTIPS, 0, 0);
2205  ok(tooltip != NULL, "got %p\n", tooltip);
2206  ok(GetParent(tooltip) == hMainWnd, "got %p, %p\n", hMainWnd, hwnd);
2207 
2210 
2211  /* TBSTYLE_TRANSPARENT */
2214  0, 0, 0, 0, hMainWnd, (HMENU)5, GetModuleHandleA(NULL), NULL);
2215 
2217  ok((style & TBSTYLE_TRANSPARENT) == TBSTYLE_TRANSPARENT, "got 0x%08x\n", style);
2218 
2219  style = SendMessageA(hwnd, TB_GETSTYLE, 0, 0);
2220  ok((style & TBSTYLE_TRANSPARENT) == TBSTYLE_TRANSPARENT, "got 0x%08x\n", style);
2221 
2223 }
2224 
2225 typedef struct {
2230 
2232  {
2236  },
2237  {
2240  },
2241 
2243  { 0, 0, 0 },
2246 
2247  { 0, 0, 0 },
2251 
2252  {
2255  },
2256  {
2259  }
2260 };
2261 
2263 {
2264  DWORD style, oldstyle, oldstyle2;
2265  const extended_style_t *ptr;
2266  HWND hwnd = NULL;
2267  int i;
2268 
2270 
2274  {
2275  win_skip("Some extended style bits are not supported\n");
2277  return;
2278  }
2279 
2280  for (i = 0; i < sizeof(extended_style_test)/sizeof(extended_style_t); i++)
2281  {
2283 
2284  oldstyle2 = SendMessageA(hwnd, TB_GETEXTENDEDSTYLE, 0, 0);
2285 
2286  oldstyle = SendMessageA(hwnd, TB_SETEXTENDEDSTYLE, ptr->mask, ptr->style);
2287  ok(oldstyle == oldstyle2, "%d: got old style 0x%08x, expected 0x%08x\n", i, oldstyle, oldstyle2);
2289  ok(style == ptr->style_set, "%d: got style 0x%08x, expected 0x%08x\n", i, style, ptr->style_set);
2290  }
2291 
2292  /* Windows sets CCS_VERT when TB_GETEXTENDEDSTYLE is set */
2293  oldstyle2 = SendMessageA(hwnd, TB_GETEXTENDEDSTYLE, 0, 0);
2295  ok(oldstyle == oldstyle2, "got old style 0x%08x, expected 0x%08x\n", oldstyle, oldstyle2);
2297  ok(style == TBSTYLE_EX_VERTICAL, "got style 0x%08x, expected 0x%08x\n", style, TBSTYLE_EX_VERTICAL);
2298  style = SendMessageA(hwnd, TB_GETSTYLE, 0, 0);
2299  todo_wine
2300  ok(style == CCS_VERT, "got style 0x%08x, expected CCS_VERT\n", style);
2301 
2303 }
2304 
2305 static void test_noresize(void)
2306 {
2307  HWND wnd;
2308  int i;
2309  TBBUTTON button = {0, 10, TBSTATE_ENABLED, 0, {0, }, 0, -1};
2310 
2313  SendMessageA(wnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
2314 
2315  for (i=0; i<30; i++)
2316  {
2317  button.idCommand = 10 + i;
2318  SendMessageA(wnd, TB_ADDBUTTONSA, 1, (LPARAM)&button);
2319  }
2320 
2322 
2323  /* autosize clears the wrap on button 0 */
2324  SendMessageA(wnd, TB_AUTOSIZE, 0, 0);
2325  for (i=0; i<30; i++)
2326  {
2327  SendMessageA(wnd, TB_GETBUTTON, i, (LPARAM)&button);
2328  if (i % 4 == 3)
2329  ok(button.fsState == (TBSTATE_WRAP|TBSTATE_ENABLED), "%d: got %08x\n", i, button.fsState);
2330  else
2331  ok(button.fsState == TBSTATE_ENABLED, "%d: got %08x\n", i, button.fsState);
2332  }
2333 
2334  /* changing the parent doesn't do anything */
2335  MoveWindow(hMainWnd, 0,0, 400, 200, FALSE);
2336  for (i=0; i<30; i++)
2337  {
2338  SendMessageA(wnd, TB_GETBUTTON, i, (LPARAM)&button);
2339  if (i % 4 == 3)
2340  ok(button.fsState == (TBSTATE_WRAP|TBSTATE_ENABLED), "%d: got %08x\n", i, button.fsState);
2341  else
2342  ok(button.fsState == TBSTATE_ENABLED, "%d: got %08x\n", i, button.fsState);
2343  }
2344 
2345  /* again nothing here */
2346  SendMessageA(wnd, TB_AUTOSIZE, 0, 0);
2347  for (i=0; i<30; i++)
2348  {
2349  SendMessageA(wnd, TB_GETBUTTON, i, (LPARAM)&button);
2350  if (i % 4 == 3)
2351  ok(button.fsState == (TBSTATE_WRAP|TBSTATE_ENABLED), "%d: got %08x\n", i, button.fsState);
2352  else
2353  ok(button.fsState == TBSTATE_ENABLED, "%d: got %08x\n", i, button.fsState);
2354  }
2355 
2356  DestroyWindow(wnd);
2357 
2358 }
2359 
2360 static void test_save(void)
2361 {
2362  HWND wnd = NULL;
2364  static const WCHAR subkey[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
2365  'W','i','n','e','T','e','s','t',0};
2366  static const WCHAR value[] = {'t','o','o','l','b','a','r','t','e','s','t',0};
2367  LONG res;
2368  HKEY key;
2369  BYTE data[100];
2370  DWORD size = sizeof(data), type, i, count;
2371  TBBUTTON tb;
2372  static const TBBUTTON more_btns[2] =
2373  {
2374  {0, 11, TBSTATE_HIDDEN, BTNS_BUTTON, {0}, 0, -1},
2375  {0, 13, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, -1}
2376  };
2377  static const DWORD expect[] = {0xcafe, 1, 0xcafe0000, 3, 0xcafe0001, 5, 0xcafe0002, 7, 0xcafe0003,
2378  9, 0xcafe0004, 11, 0xcafe0005, 13, 0xcafe0006, 0xffffffff, 0xcafe0007,
2379  0xfffffffe, 0xcafe0008, 0x80000000, 0xcafe0009, 0x7fffffff, 0xcafe000a,
2380  0x100, 0xcafe000b};
2381  static const TBBUTTON expect_btns[] =
2382  {
2383  {0, 1, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
2384  {0, 3, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 1, 2},
2385  {0, 5, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 2, 0},
2386  {0, 7, 0, BTNS_BUTTON, {0}, 0, (INT_PTR)"foo"},
2387  {0, 9, 0, BTNS_BUTTON, {0}, 0, 0},
2388  {0, 11, 0, BTNS_BUTTON, {0}, 0, 3},
2389  {0, 13, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 6, 0},
2390  {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 7, 0},
2391  {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 8, 0},
2392  {0, 0, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 9, 0},
2393  {0, 0x7fffffff, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0xa, 0},
2394  };
2395 
2396  params.hkr = HKEY_CURRENT_USER;
2397  params.pszSubKey = subkey;
2398  params.pszValueName = value;
2399 
2401  SendMessageW( wnd, TB_ADDBUTTONSW, sizeof(more_btns) / sizeof(more_btns[0]), (LPARAM)more_btns );
2402 
2405  ok( res, "saving failed\n" );
2407  DestroyWindow( wnd );
2408 
2409  res = RegOpenKeyW( HKEY_CURRENT_USER, subkey, &key );
2410  ok( !res, "got %08x\n", res );
2412  ok( !res, "got %08x\n", res );
2413  ok( type == REG_BINARY, "got %08x\n", type );
2414  ok( size == sizeof(expect), "got %08x\n", size );
2415  ok( !memcmp( data, expect, size ), "mismatch\n" );
2416 
2417  RegCloseKey( key );
2418 
2419  wnd = NULL;
2420  rebuild_toolbar( &wnd );
2421 
2424  ok( res, "restoring failed\n" );
2426  count = SendMessageW( wnd, TB_BUTTONCOUNT, 0, 0 );
2427  ok( count == sizeof(expect_btns) / sizeof(expect_btns[0]), "got %d\n", count );
2428 
2429  for (i = 0; i < count; i++)
2430  {
2431  res = SendMessageW( wnd, TB_GETBUTTON, i, (LPARAM)&tb );
2432  ok( res, "got %d\n", res );
2433 
2434  ok( tb.iBitmap == expect_btns[i].iBitmap, "%d: got %d\n", i, tb.iBitmap );
2435  ok( tb.idCommand == expect_btns[i].idCommand, "%d: got %d\n", i, tb.idCommand );
2436  ok( tb.fsState == expect_btns[i].fsState, "%d: got %02x\n", i, tb.fsState );
2437  ok( tb.fsStyle == expect_btns[i].fsStyle, "%d: got %02x\n", i, tb.fsStyle );
2438  ok( tb.dwData == expect_btns[i].dwData, "%d: got %lx\n", i, tb.dwData );
2439  if (IS_INTRESOURCE(expect_btns[i].iString))
2440  ok( tb.iString == expect_btns[i].iString, "%d: got %lx\n", i, tb.iString );
2441  else
2442  ok( !strcmp( (char *)tb.iString, (char *)expect_btns[i].iString ),
2443  "%d: got %s\n", i, (char *)tb.iString );
2444 
2445  /* In fact the ptr value set in TBN_GETBUTTONINFOA is simply copied */
2446  if (tb.idCommand == 7)
2447  ok( tb.iString == (INT_PTR)alloced_str, "string not set\n");
2448  }
2449 
2450  DestroyWindow( wnd );
2451  RegOpenKeyW( HKEY_CURRENT_USER, subkey, &key );
2453  RegCloseKey( key );
2454 }
2455 
2456 static void test_drawtext_flags(void)
2457 {
2458  HWND hwnd = NULL;
2459  UINT flags;
2460 
2462 
2464 todo_wine
2465  ok(flags == 0, "Unexpected draw text flags %#x\n", flags);
2466 
2467  /* zero mask, flags are retained */
2469 todo_wine
2470  ok(flags == 0, "Unexpected draw text flags %#x\n", flags);
2471  ok(!(flags & DT_BOTTOM), "Unexpected DT_BOTTOM style\n");
2472 
2474 todo_wine
2475  ok(flags == 0, "Unexpected draw text flags %#x\n", flags);
2476  ok(!(flags & DT_BOTTOM), "Unexpected DT_BOTTOM style\n");
2477 
2478  /* set/remove */
2480 todo_wine
2481  ok(flags == 0, "Unexpected draw text flags %#x\n", flags);
2482  ok(!(flags & DT_BOTTOM), "Unexpected DT_BOTTOM style\n");
2483 
2485 todo_wine
2486  ok(flags == DT_BOTTOM, "Unexpected draw text flags %#x\n", flags);
2487  ok(flags & DT_BOTTOM, "Expected DT_BOTTOM style, %#x\n", flags);
2488 
2490 todo_wine
2491  ok(flags == 0, "Unexpected draw text flags %#x\n", flags);
2492  ok(!(flags & DT_BOTTOM), "Unexpected DT_BOTTOM style\n");
2493 
2495 }
2496 
2497 static void test_imagelist(void)
2498 {
2499  HIMAGELIST imagelist;
2500  HWND hwnd = NULL;
2501  int ret;
2502 
2504 
2505  imagelist = (HIMAGELIST)SendMessageA(hwnd, TB_GETIMAGELIST, 0, 0);
2506  ok(imagelist == NULL, "got %p\n", imagelist);
2507 
2508  ret = SendMessageA(hwnd, TB_SETBITMAPSIZE, 0, MAKELONG(16, 16));
2509  ok(ret, "got %d\n", ret);
2510 
2511  imagelist = (HIMAGELIST)SendMessageA(hwnd, TB_GETIMAGELIST, 0, 0);
2512  ok(imagelist == NULL, "got %p\n", imagelist);
2513 
2515 }
2516 
2517 static void init_functions(void)
2518 {
2519  HMODULE hComCtl32 = LoadLibraryA("comctl32.dll");
2520 
2521 #define X(f) p##f = (void*)GetProcAddress(hComCtl32, #f);
2522  X(CreateToolbarEx);
2527 #undef X
2528 }
2529 
2530 START_TEST(toolbar)
2531 {
2532  WNDCLASSA wc;
2533  MSG msg;
2534  RECT rc;
2535 
2537  init_functions();
2538 
2539  wc.style = CS_HREDRAW | CS_VREDRAW;
2540  wc.cbClsExtra = 0;
2541  wc.cbWndExtra = 0;
2543  wc.hIcon = NULL;
2546  wc.lpszMenuName = NULL;
2547  wc.lpszClassName = "Toolbar test parent";
2549  RegisterClassA(&wc);
2550 
2551  hMainWnd = CreateWindowExA(0, "Toolbar test parent", "Blah", WS_OVERLAPPEDWINDOW,
2553  GetClientRect(hMainWnd, &rc);
2555 
2556  basic_test();
2557  test_add_bitmap();
2558  test_add_string();
2559  test_hotitem();
2560  test_sizes();
2561  test_recalc();
2564  test_dispinfo();
2565  test_setrows();
2566  test_getstring();
2567  test_tooltip();
2569  test_create();
2571  test_noresize();
2572  test_save();
2574  test_imagelist();
2575 
2576  PostQuitMessage(0);
2577  while(GetMessageA(&msg,0,0,0)) {
2580  }
2582 }
#define TBSTYLE_EX_DOUBLEBUFFER
Definition: commctrl.h:984
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
INT WINAPI ImageList_GetImageCount(HIMAGELIST himl)
Definition: imagelist.c:1967
static void test_hotitem(void)
Definition: toolbar.c:843
#define TB_MOVEBUTTON
Definition: commctrl.h:1158
#define TBIF_COMMAND
Definition: commctrl.h:1194
#define PARENT_SEQ_INDEX
Definition: toolbar.c:37
static LRESULT parent_wnd_notify(LPARAM lParam)
Definition: toolbar.c:139
static const struct message restore_parent_seq[]
Definition: toolbar.c:76
#define HDC
Definition: msvc.h:22
#define check_sizes()
Definition: toolbar.c:1330
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
#define MAKEINTRESOURCE
Definition: winuser.h:591
#define TB_ADDSTRINGA
Definition: commctrl.h:1101
RECT * prcButtons
Definition: toolbar.c:999
#define TB_ISBUTTONHIGHLIGHTED
Definition: commctrl.h:1023
#define TB_SETBUTTONSIZE
Definition: commctrl.h:1105
static void prepare_recalc_test(HWND *phToolbar)
Definition: toolbar.c:1644
BOOL WINAPI TranslateMessage(_In_ const MSG *)
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
#define TB_ISBUTTONPRESSED
Definition: commctrl.h:1020
#define TB_BUTTONSTRUCTSIZE
Definition: commctrl.h:1104
#define TB_BUTTONCOUNT
Definition: commctrl.h:1080
#define TRUE
Definition: types.h:120
#define MAKEWPARAM(l, h)
Definition: winuser.h:3916
static const struct message ttgetdispinfo_parent_seq[]
Definition: toolbar.c:57
#define TBN_GETINFOTIPA
Definition: commctrl.h:1311
#define TBN_ENDADJUST
Definition: commctrl.h:1280
#define HCBT_CREATEWND
Definition: winuser.h:58
char hdr[14]
Definition: iptest.cpp:33
#define check_sizes_todo(todomask)
Definition: toolbar.c:1309
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define TB_GETROWS
Definition: commctrl.h:1112
#define TBSTYLE_EX_HIDECLIPPEDBUTTONS
Definition: commctrl.h:983
static TBBUTTON buttons2[]
Definition: toolbar.c:1338
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
static int string_width(const CHAR *s)
Definition: toolbar.c:983
#define REG_BINARY
Definition: nt_native.h:1496
static int tbsize_numtests
Definition: toolbar.c:1291
static DWORD
Definition: toolbar.c:40
__wchar_t WCHAR
Definition: xmlstorage.h:180
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define TBIF_BYINDEX
Definition: commctrl.h:1196
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define TB_SETSTATE
Definition: commctrl.h:1024
#define TBSTYLE_SEP
Definition: commctrl.h:952
#define TBSTYLE_TRANSPARENT
Definition: commctrl.h:966
static TBBUTTON buttons4[]
Definition: toolbar.c:1348
#define TB_GETBUTTON
Definition: commctrl.h:1079
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define HKEY_CURRENT_USER
Definition: winreg.h:11
char CHAR
Definition: xmlstorage.h:175
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
static void add_128x15_bitmap(HWND hToolbar, int nCmds)
Definition: toolbar.c:479
#define WM_GETTEXT
Definition: winuser.h:1600
#define TB_GETSTRINGA
Definition: commctrl.h:1246
HIMAGELIST WINAPI ImageList_LoadImageA(HINSTANCE hi, LPCSTR lpbmp, INT cx, INT cGrow, COLORREF clrMask, UINT uType, UINT uFlags)
Definition: imagelist.c:2062
Definition: msg.h:39
#define TB_SETSTYLE
Definition: commctrl.h:1128
#define MAKELPARAM(l, h)
Definition: winuser.h:3915
#define TBIF_STYLE
Definition: commctrl.h:1192
static TBBUTTON buttons1[]
Definition: toolbar.c:1334
DWORD dwMask
Definition: commctrl.h:1213
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
#define CALLBACK
Definition: compat.h:27
BOOL WINAPI UpdateWindow(_In_ HWND)
HWND hWnd
Definition: settings.c:17
static BOOL g_fBlockHotItemChange
Definition: toolbar.c:50
#define TBSTYLE_EX_DRAWDDARROWS
Definition: commctrl.h:979
BOOL WINAPI GetMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT)
#define IDB_BITMAP_80x15
Definition: resources.h:25
static BOOL g_fExpectedHotItemNew
Definition: toolbar.c:53
static void test_sizes(void)
Definition: toolbar.c:1354
int cbClsExtra
Definition: winuser.h:3118
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
#define IDB_STD_SMALL_COLOR
Definition: commctrl.h:1034
#define ZeroMemory
Definition: winbase.h:1635
#define CS_HREDRAW
Definition: winuser.h:648
LPCSTR lpszMenuName
Definition: winuser.h:3124
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define STRING0
Definition: toolbar.c:1019
#define WM_NCHITTEST
Definition: winuser.h:1668
#define compare(val, exp, format)
Definition: toolbar.c:122
static HWND hMainWnd
Definition: toolbar.c:49
#define test
Definition: rosglue.h:37
#define BTNS_AUTOSIZE
Definition: commctrl.h:974
static void test_get_set_style(void)
Definition: toolbar.c:2045
#define DEFINE_EXPECT(func)
Definition: toolbar.c:98
static void test_getbuttoninfo(void)
Definition: toolbar.c:1795
static HHOOK g_tbhook
Definition: toolbar.c:2093
HBRUSH hbrBackground
Definition: winuser.h:3123
HINSTANCE hInst
Definition: commctrl.h:1029
#define WS_CHILD
Definition: pedump.c:617
#define TB_SAVERESTOREW
Definition: commctrl.h:1099
#define CCM_GETUNICODEFORMAT
Definition: commctrl.h:98
#define STRING1
Definition: toolbar.c:1020
#define IDB_HIST_LARGE_COLOR
Definition: commctrl.h:1039
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
#define TB_GETMAXSIZE
Definition: commctrl.h:1159
int32_t INT_PTR
Definition: typedefs.h:62
BYTE fsStyle
Definition: commctrl.h:922
#define TB_GETIMAGELIST
Definition: commctrl.h:1121
Definition: features.h:417
#define WS_CLIPCHILDREN
Definition: pedump.c:619
static const extended_style_t extended_style_test[]
Definition: toolbar.c:2231
HWND WINAPI CreateToolbarEx(HWND hwnd, DWORD style, UINT wID, INT nBitmaps, HINSTANCE hBMInst, UINT_PTR wBMID, LPCTBBUTTON lpButtons, INT iNumButtons, INT dxButton, INT dyButton, INT dxBitmap, INT dyBitmap, UINT uStructSize)
Definition: commctrl.c:929
static LRESULT WINAPI toolbar_subclass_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
Definition: toolbar.c:2100
#define TB_ISBUTTONHIDDEN
Definition: commctrl.h:1021
#define TBN_BEGINADJUST
Definition: commctrl.h:1279
int cButtons
Definition: commctrl.h:1331
HIMAGELIST himl
#define WM_NCCREATE
Definition: winuser.h:1665
BOOL WINAPI DestroyWindow(_In_ HWND)
#define COLOR_WINDOW
Definition: winuser.h:908
int32_t INT
Definition: typedefs.h:56
DWORD dwMask
Definition: commctrl.h:1200
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
#define SET_EXPECT(func)
Definition: toolbar.c:113
#define TBN_HOTITEMCHANGE
Definition: commctrl.h:1306
#define TB_GETITEMRECT
Definition: commctrl.h:1103
#define IDS_TBADD7
Definition: resources.h:32
#define IDC_IBEAM
Definition: winuser.h:683
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
#define CCS_VERT
Definition: commctrl.h:2219
static int int *static int
Definition: toolbar.c:45
static TBBUTTON buttons3[]
Definition: toolbar.c:1342
LRESULT WINAPI CallWindowProcA(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
UINT_PTR WPARAM
Definition: windef.h:207
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:893
UINT code
Definition: winuser.h:3112
#define WM_NCPAINT
Definition: winuser.h:1669
static DWORD tbsize_alt_numtests
Definition: toolbar.c:1307
uint32_t cs
Definition: isohybrid.c:75
int cbWndExtra
Definition: winuser.h:3119
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void test_tooltip(void)
Definition: toolbar.c:2005
#define BTNS_BUTTON
Definition: commctrl.h:968
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define TBSTYLE_CHECKGROUP
Definition: commctrl.h:955
#define TBN_GETBUTTONINFOA
Definition: commctrl.h:1276
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
static UINT_PTR
Definition: toolbar.c:40
GLenum const GLfloat * params
Definition: glext.h:5645
static void free_tbsize_results(void)
Definition: toolbar.c:1282
static LRESULT CALLBACK cbt_hook_proc(int code, WPARAM wParam, LPARAM lParam)
Definition: toolbar.c:2161
WCHAR strW[12]
Definition: clipboard.c:2029
long LONG
Definition: pedump.c:60
#define TB_AUTOSIZE
Definition: commctrl.h:1107
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR idFrom
Definition: winuser.h:3111
LPSTR pszText
Definition: commctrl.h:1207
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3311
#define tbsize_results_num
Definition: toolbar.c:1025
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
static void test_recalc(void)
Definition: toolbar.c:1682
static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: toolbar.c:312
static PVOID ptr
Definition: dispmode.c:27
#define TB_GETSTRINGW
Definition: commctrl.h:1245
HCURSOR hCursor
Definition: winuser.h:3122
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
DWORD * pCurrent
Definition: commctrl.h:1328
#define TB_ENABLEBUTTON
Definition: commctrl.h:1012
Definition: msg.h:45
static void * alloced_str
Definition: toolbar.c:137
#define CW_USEDEFAULT
Definition: winuser.h:225
#define GWLP_USERDATA
Definition: treelist.c:63
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
#define TBNF_IMAGE
Definition: commctrl.h:1366
HDC hdc
Definition: msvc.h:53
#define CHECK_CALLED(func)
Definition: toolbar.c:107
const WCHAR * str
#define MAKELONG(a, b)
Definition: typedefs.h:248
#define TB_GETEXTENDEDSTYLE
Definition: commctrl.h:1161
UINT msg
Definition: msvc.h:92
smooth NULL
Definition: ftsmooth.c:416
static const struct message save_parent_seq[]
Definition: toolbar.c:64
#define SYSTEM_FONT
Definition: wingdi.h:910
LONG cx
Definition: windef.h:319
#define CHECK_EXPECT2(func)
Definition: toolbar.c:101
#define CCS_TOP
Definition: commctrl.h:2212
#define CCS_NOPARENTALIGN
Definition: commctrl.h:2216
GLint GLint bottom
Definition: glext.h:7726
#define TTN_GETDISPINFOA
Definition: commctrl.h:1842
#define BTNS_SHOWTEXT
Definition: commctrl.h:976
HHOOK WINAPI SetWindowsHookA(_In_ int, _In_ HOOKPROC)
#define WH_CBT
Definition: winuser.h:35
static UINT
Definition: toolbar.c:40
#define CLR_NONE
Definition: commctrl.h:304
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
const char * LPCSTR
Definition: xmlstorage.h:183
INT_PTR iString
Definition: commctrl.h:929
#define SW_SHOW
Definition: winuser.h:769
static void rebuild_toolbar(HWND *hToolbar)
Definition: toolbar.c:437
static void test_getstring(void)
Definition: toolbar.c:1967
#define TB_GETHOTITEM
Definition: commctrl.h:1140
DWORD_PTR dwData
Definition: commctrl.h:928
int iBitmap
Definition: commctrl.h:919
#define ok(value,...)
Definition: CComObject.cpp:34
#define GetWindowLongPtrA
Definition: winuser.h:4697
static void test_noresize(void)
Definition: toolbar.c:2305
TBBUTTON tbButton
Definition: commctrl.h:1343
static void tbsize_addbutton(tbsize_result_t *tbsr, int left, int top, int right, int bottom)
Definition: toolbar.c:1014
static tbsize_alt_result_t tbsize_alt_results[]
Definition: toolbar.c:1300
#define CCS_BOTTOM
Definition: commctrl.h:2214
#define TB_SETIMAGELIST
Definition: commctrl.h:1120
#define TB_GETBUTTONSIZE
Definition: commctrl.h:1130
#define CS_VREDRAW
Definition: winuser.h:653
static void test_drawtext_flags(void)
Definition: toolbar.c:2456
#define TBIF_STATE
Definition: commctrl.h:1191
#define IDB_VIEW_SMALL_COLOR
Definition: commctrl.h:1036
#define IDS_TBADD3
Definition: resources.h:29
unsigned int BOOL
Definition: ntddk_ex.h:94
GLsizeiptr size
Definition: glext.h:5919
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
static void test_create(void)
Definition: toolbar.c:2183
#define BTNS_SEP
Definition: commctrl.h:969
static HWND g_toolbar
Definition: toolbar.c:2094
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4134
int cbBytesPerRecord
Definition: commctrl.h:1342
static tbsize_result_t init_tbsize_result(int nButtonsAlloc, int cleft, int ctop, int cright, int cbottom, int minx, int miny)
Definition: toolbar.c:1002
#define IDB_VIEW_LARGE_COLOR
Definition: commctrl.h:1037
void test1(void)
Definition: hivetest.c:366
#define ok_sequence(seq, index, exp, contx, todo)
Definition: msg.h:387
unsigned int UINT
Definition: ndis.h:50
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint left
Definition: glext.h:7726
static void test_setrows(void)
Definition: toolbar.c:1928
static BOOL g_ResetDispTextPtr
Definition: toolbar.c:55
static void test_add_string(void)
Definition: toolbar.c:765
static const WCHAR tb[]
Definition: suminfo.c:286
#define TBSTYLE_TOOLTIPS
Definition: commctrl.h:959
static BOOL(WINAPI *pImageList_Destroy)(HIMAGELIST)
GLdouble GLdouble right
Definition: glext.h:10859
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: toolbar.c:47
#define TB_ADDBITMAP
Definition: commctrl.h:1026
GLbitfield flags
Definition: glext.h:7161
static void test_TB_GET_SET_EXTENDEDSTYLE(void)
Definition: toolbar.c:2262
#define WM_PAINT
Definition: winuser.h:1602
static HWND(WINAPI *pCreateToolbarEx)(HWND
#define CCS_NORESIZE
Definition: commctrl.h:2215
static int system_font_height(void)
Definition: toolbar.c:972
#define STRING2
Definition: toolbar.c:1021
int ret
static void rebuild_toolbar_with_buttons(HWND *hToolbar)
Definition: toolbar.c:449
static void test_add_bitmap(void)
Definition: toolbar.c:498
Definition: msg.h:34
BOOL WINAPI GetTextExtentPoint32A(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
static void test_dispinfo(void)
Definition: toolbar.c:1876
static const WCHAR L[]
Definition: oid.c:1087
#define todo_wine
Definition: test.h:154
static void restore_recalc_state(HWND hToolbar)
Definition: toolbar.c:1665
#define check_button_size(handle, width, height,...)
Definition: toolbar.c:124
#define TBN_SAVE
Definition: commctrl.h:1315
int idCommand
Definition: commctrl.h:920
HKEY key
Definition: reg.c:42
#define TB_GETTOOLTIPS
Definition: commctrl.h:1108
#define TB_CHECKBUTTON
Definition: commctrl.h:1013
#define TB_ADDBUTTONSW
Definition: commctrl.h:1236
#define SetWindowLongPtrA
Definition: winuser.h:5214
#define TB_SETBITMAPSIZE
Definition: commctrl.h:1106
unsigned char BYTE
Definition: mem.h:68
#define TB_SETPADDING
Definition: commctrl.h:1163
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:819
GLdouble s
Definition: gl.h:2039
static INT
Definition: toolbar.c:40
#define TB_GETBUTTONINFOA
Definition: commctrl.h:1229
#define IDB_STD_LARGE_COLOR
Definition: commctrl.h:1035
Definition: time.h:76
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define IDS_TBADD5
Definition: resources.h:31
LPCSTR lpszClassName
Definition: winuser.h:3125
BOOL WINAPI MoveWindow(_In_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ BOOL)
UINT WPARAM LPARAM lparam
Definition: msvc.h:92
GLsizei const GLfloat * value
Definition: glext.h:6069
#define WINAPI
Definition: msvc.h:20
#define WM_USER
Definition: winuser.h:1856
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
#define GWLP_WNDPROC
Definition: treelist.c:66
UINT style
Definition: winuser.h:3116
LPSTR pszText
Definition: commctrl.h:1376
#define TOOLBARCLASSNAMEA
Definition: commctrl.h:914
#define TB_GETBUTTONINFOW
Definition: commctrl.h:1227
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2859
#define GWL_STYLE
Definition: winuser.h:846
static HDC hDC
Definition: 3dtext.c:33
DWORD dwMask
Definition: commctrl.h:1372
void test2(void)
Definition: regtest.c:173
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define TB_INSERTBUTTONA
Definition: commctrl.h:1077
HWND WINAPI GetParent(_In_ HWND)
#define TB_ISBUTTONINDETERMINATE
Definition: commctrl.h:1022
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
#define WS_BORDER
Definition: pedump.c:625
#define check_hot_notify()
Definition: toolbar.c:839
START_TEST(toolbar)
Definition: toolbar.c:238
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define TB_LOADIMAGES
Definition: commctrl.h:1122
HWND buttons[5]
Definition: sndrec32.cpp:40
LONG WINAPI RegDeleteValueW(HKEY hKey, LPCWSTR lpValueName)
Definition: reg.c:2368
#define TB_SETBUTTONINFOA
Definition: commctrl.h:1230
BOOL WINAPI DeleteDC(_In_ HDC)
static tbsize_result_t * tbsize_results
Definition: toolbar.c:1023
HINSTANCE hInstance
Definition: winuser.h:3120
static void init_tbsize_results(void)
Definition: toolbar.c:1027
static void init_functions(void)
Definition: toolbar.c:2517
#define add_message(msg)
Definition: msg.c:2142
#define TBN_RESTORE
Definition: commctrl.h:1314
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define CCM_SETUNICODEFORMAT
Definition: commctrl.h:97
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
static void test_save(void)
Definition: toolbar.c:2360
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
#define TBIF_TEXT
Definition: commctrl.h:1190
UINT cbData
Definition: commctrl.h:1329
static BOOL did_recalc(HWND hToolbar)
Definition: toolbar.c:1655
LONG WINAPI SetWindowLongA(_In_ HWND, _In_ int, _In_ LONG)
#define IMAGE_BITMAP
Definition: winuser.h:211
#define TB_ADDBUTTONSA
Definition: commctrl.h:1076
#define IDS_TBADD1
Definition: resources.h:27
#define TB_HIDEBUTTON
Definition: commctrl.h:1015
#define WM_SETFONT
Definition: winuser.h:1632
#define WM_DEVICECHANGE
Definition: winuser.h:1787
#define HINST_COMMCTRL
Definition: commctrl.h:1033
WNDPROC lpfnWndProc
Definition: winuser.h:3117
#define expect(EXPECTED, GOT)
Definition: toolbar.c:116
#define CHECK_IMAGELIST(count, dx, dy)
Definition: toolbar.c:487
#define msg(x)
Definition: auth_time.c:54
_Out_opt_ int * cx
Definition: commctrl.h:570
static HINSTANCE
Definition: toolbar.c:40
int nRows
Definition: appswitch.c:56
#define TBSTATE_HIDDEN
Definition: commctrl.h:945
#define TBSTYLE_GROUP
Definition: commctrl.h:954
#define TBSTATE_ENABLED
Definition: commctrl.h:944
#define WM_CREATE
Definition: winuser.h:1590
GLuint res
Definition: glext.h:9613
BOOL WINAPI ImageList_GetIconSize(HIMAGELIST himl, INT *cx, INT *cy)
Definition: imagelist.c:1941
#define CCS_NOMOVEY
Definition: commctrl.h:2213
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
HWND WINAPI CreateWindowExA(_In_ DWORD dwExStyle, _In_opt_ LPCSTR lpClassName, _In_opt_ LPCSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define TBSTYLE_WRAPABLE
Definition: commctrl.h:960
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
BOOL WINAPI UnhookWindowsHook(_In_ int, _In_ HOOKPROC)
GLenum GLuint id
Definition: glext.h:5579
#define TBSTATE_WRAP
Definition: commctrl.h:947
#define TBSTYLE_EX_MIXEDBUTTONS
Definition: commctrl.h:982
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define TB_ISBUTTONENABLED
Definition: commctrl.h:1018
static DWORD g_dwExpectedDispInfoMask
Definition: toolbar.c:54
static void test_createtoolbarex(void)
Definition: toolbar.c:1827
static void test_imagelist(void)
Definition: toolbar.c:2497
#define TBN_GETDISPINFOA
Definition: commctrl.h:1309
static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString)
Definition: toolbar.c:129
#define TB_GETSTYLE
Definition: commctrl.h:1129
static BOOL g_fReceivedHotItemChange
Definition: toolbar.c:51
#define TB_ISBUTTONCHECKED
Definition: commctrl.h:1019
static int int *static COLORREF
Definition: toolbar.c:45
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
static void basic_test(void)
Definition: toolbar.c:375
#define TTN_GETDISPINFOW
Definition: commctrl.h:1843
static int int *static LPCSTR
Definition: toolbar.c:45
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define TBIF_SIZE
Definition: commctrl.h:1195
BYTE fsState
Definition: commctrl.h:921
#define IDS_TBADD2
Definition: resources.h:28
GLfloat GLfloat p
Definition: glext.h:8902
LONG_PTR LRESULT
Definition: windef.h:209
#define TB_SETHOTITEM
Definition: commctrl.h:1141
#define LR_DEFAULTCOLOR
Definition: winuser.h:1077
Arabic default style
Definition: afstyles.h:93
#define TBN_GETDISPINFOW
Definition: commctrl.h:1310
#define IDB_HIST_SMALL_COLOR
Definition: commctrl.h:1038
#define WS_VISIBLE
Definition: pedump.c:620
HBRUSH WINAPI GetSysColorBrush(_In_ int)
#define TB_SETDRAWTEXTFLAGS
Definition: commctrl.h:1243
#define memset(x, y, z)
Definition: compat.h:39
#define CHECK_STRING_TABLE(count, tab)
Definition: toolbar.c:752
#define TB_SETROWS
Definition: commctrl.h:1111
#define DT_BOTTOM
Definition: winuser.h:525
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define IDB_BITMAP_128x15
Definition: resources.h:24
LONG cy
Definition: windef.h:320
#define win_skip
Definition: test.h:141
#define TBSTYLE_LIST
Definition: commctrl.h:963
LPARAM lParam
Definition: combotst.c:139
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
__analysis_noreturn void WINAPI PostQuitMessage(_In_ int)
#define IDS_TBADD4
Definition: resources.h:30
#define NUM_MSG_SEQUENCES
Definition: toolbar.c:38
#define TBSTYLE_FLAT
Definition: commctrl.h:962
#define TB_SETEXTENDEDSTYLE
Definition: commctrl.h:1160
#define WM_NOTIFY
Definition: richedit.h:61
static void expect_hot_notify(int idold, int idnew)
Definition: toolbar.c:832
static BOOL g_fExpectedHotItemOld
Definition: toolbar.c:52
DWORD * pData
Definition: commctrl.h:1327
static int int *static HIMAGELIST(WINAPI *pImageList_LoadImageA)(HINSTANCE
static tbrows_result_t tbrows_results[]
Definition: toolbar.c:1918
#define TB_DELETEBUTTON
Definition: commctrl.h:1078
Definition: path.c:42
#define printf
Definition: config.h:203
#define X(f)
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#define TBSTYLE_EX_VERTICAL
Definition: commctrl.h:981
UINT WPARAM wparam
Definition: msvc.h:92
HICON hIcon
Definition: winuser.h:3121
UINT_PTR nID
Definition: commctrl.h:1030
DWORD * pCurrent
Definition: commctrl.h:1338