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