ReactOS  0.4.14-dev-583-g2a1ba2c
button.c
Go to the documentation of this file.
1 /* Unit test suite for Button control.
2  *
3  * Copyright 1999 Ove Kaaven
4  * Copyright 2003 Dimitrie O. Paun
5  * Copyright 2004, 2005 Dmitry Timoshkov
6  * Copyright 2014 Nikolay Sivov for CodeWeavers
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
23 #ifdef __REACTOS__
24 #undef USE_WINE_TODOS
25 #endif
26 
27 #include <windows.h>
28 #include <commctrl.h>
29 
30 #include "wine/test.h"
31 #include "v6util.h"
32 #include "msg.h"
33 
34 #ifdef __REACTOS__
35 #define BS_PUSHBOX 0x0000000AL
36 #endif
37 
38 #define IS_WNDPROC_HANDLE(x) (((ULONG_PTR)(x) >> 16) == (~0u >> 16))
39 
40 static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
41 static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
42 static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
43 static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
44 static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
45 static BOOL (WINAPI *pImageList_Destroy)(HIMAGELIST);
46 
47 /****************** button message test *************************/
48 #define ID_BUTTON 0x000e
49 
50 #define COMBINED_SEQ_INDEX 0
51 #define PARENT_CD_SEQ_INDEX 1
52 #define NUM_MSG_SEQUENCES 2
53 
55 
57 {
58  ULONG size;
59  DWORD res;
64 };
65 
66 /* returned pointer is valid as long as activation context is alive */
68 {
69  struct wndclass_redirect_data *wnddata;
70  ACTCTX_SECTION_KEYED_DATA data;
71  BOOL ret;
72 
73  memset(&data, 0, sizeof(data));
74  data.cbSize = sizeof(data);
75  ret = FindActCtxSectionStringW(0, NULL, ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION, name, &data);
76  ok(ret, "Failed to find class redirection section, error %u\n", GetLastError());
77  wnddata = (struct wndclass_redirect_data*)data.lpData;
78  return (WCHAR*)((BYTE*)wnddata + wnddata->name_offset);
79 }
80 
81 static void init_functions(void)
82 {
83  HMODULE hmod = GetModuleHandleA("comctl32.dll");
84  ok(hmod != NULL, "got %p\n", hmod);
85 
86 #define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
90 #undef MAKEFUNC_ORD
91 
92 #define X(f) p##f = (void *)GetProcAddress(hmod, #f);
96 #undef X
97 }
98 
99 /* try to make sure pending X events have been processed before continuing */
100 static void flush_events(void)
101 {
102  MSG msg;
103  int diff = 200;
104  int min_timeout = 100;
105  DWORD time = GetTickCount() + diff;
106 
107  while (diff > 0)
108  {
109  if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
110  while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
111  diff = time - GetTickCount();
112  }
113 }
114 
116 {
117  /* these are always ignored */
118  return (message >= 0xc000 ||
119  message == WM_GETICON ||
120  message == WM_GETOBJECT ||
121  message == WM_TIMECHANGE ||
122  message == WM_DISPLAYCHANGE ||
126  message == WM_GETTEXT);
127 }
128 
130 {
131  static LONG defwndproc_counter = 0;
132  struct message msg = { 0 };
133  LRESULT ret;
134 
135  if (ignore_message( message )) return pDefSubclassProc(hwnd, message, wParam, lParam);
136 
137  switch (message)
138  {
139  case WM_SYNCPAINT:
140  break;
141  case BM_SETSTATE:
142  if (GetCapture())
143  ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
144  /* fall through */
145  default:
146  msg.message = message;
147  msg.flags = sent|wparam|lparam;
148  if (defwndproc_counter) msg.flags |= defwinproc;
149  msg.wParam = wParam;
150  msg.lParam = lParam;
152  }
153 
154  if (message == WM_NCDESTROY)
155  pRemoveWindowSubclass(hwnd, button_subclass_proc, 0);
156 
157  defwndproc_counter++;
158  ret = pDefSubclassProc(hwnd, message, wParam, lParam);
159  defwndproc_counter--;
160 
161  return ret;
162 }
163 
164 static struct
165 {
171 } test_cd;
172 
173 #define set_test_cd_state(s) do { \
174  test_cd.state = (s); \
175  test_cd.empty = TRUE; \
176  test_cd.line = __LINE__; \
177 } while (0)
178 
179 #define set_test_cd_ret(r) do { \
180  test_cd.ret = (r); \
181  test_cd.empty = TRUE; \
182  test_cd.line = __LINE__; \
183 } while (0)
184 
185 static void disable_test_cd(void)
186 {
187  test_cd.line = 0;
188 }
189 
191 {
192  static LONG defwndproc_counter = 0;
193  static LONG beginpaint_counter = 0;
194  static HDC cd_first_hdc;
195  struct message msg = { 0 };
198  LRESULT ret;
199 
200  if (ignore_message( message )) return 0;
201 
207  {
208  msg.message = message;
209  msg.flags = sent|parent|wparam|lparam;
210  if (defwndproc_counter) msg.flags |= defwinproc;
211  if (beginpaint_counter) msg.flags |= beginpaint;
212  msg.wParam = wParam;
213  msg.lParam = lParam;
215  }
216 
217  if (message == WM_NOTIFY && cd->hdr.code == NM_CUSTOMDRAW && test_cd.line)
218  {
219  /* Ignore an inconsistency across Windows versions */
220  UINT state = cd->uItemState & ~CDIS_SHOWKEYBOARDCUES;
221 
222  /* Some Windows configurations paint twice with different DC */
223  if (test_cd.empty)
224  {
225  cd_first_hdc = cd->hdc;
226  test_cd.empty = FALSE;
227  }
228 
229  ok_(__FILE__,test_cd.line)(!(cd->dwDrawStage & CDDS_ITEM),
230  "[%u] CDDS_ITEM is set\n", test_cd.button);
231 
232  ok_(__FILE__,test_cd.line)(state == test_cd.state,
233  "[%u] expected uItemState %u, got %u\n", test_cd.button,
234  test_cd.state, state);
235 
236  msg.message = message;
237  msg.flags = sent|parent|wparam|lparam|id|custdraw;
238  msg.wParam = wParam;
239  msg.lParam = lParam;
240  msg.id = NM_CUSTOMDRAW;
241  msg.stage = cd->dwDrawStage;
242  if (cd->hdc == cd_first_hdc)
244 
245  ret = test_cd.ret;
246  switch (msg.stage)
247  {
248  case CDDS_PREERASE:
250  cd->dwItemSpec = 0xdeadbeef;
251  break;
252  case CDDS_PREPAINT:
254  break;
255  case CDDS_POSTERASE:
256  case CDDS_POSTPAINT:
257  ok_(__FILE__,test_cd.line)(cd->dwItemSpec == 0xdeadbeef,
258  "[%u] NMCUSTOMDRAW was not shared, stage %u\n", test_cd.button, msg.stage);
259  break;
260  }
261  return ret;
262  }
263 
264  if (message == WM_NOTIFY && bcd->hdr.code == BCN_DROPDOWN)
265  {
267  RECT rc;
268 
269  GetClientRect(bcd->hdr.hwndFrom, &rc);
270 
271  ok(bcd->hdr.hwndFrom != NULL, "Received BCN_DROPDOWN with no hwnd attached, wParam %lu id %lu\n",
272  wParam, bcd->hdr.idFrom);
273  ok(bcd->hdr.idFrom == wParam, "[%u] Mismatch between wParam (%lu) and idFrom (%lu)\n",
274  button, wParam, bcd->hdr.idFrom);
275  ok(EqualRect(&rc, &bcd->rcButton), "[%u] Wrong rcButton, expected %s got %s\n",
277 
278  msg.message = message;
279  msg.flags = sent|parent|wparam|lparam|id;
280  msg.wParam = wParam;
281  msg.lParam = lParam;
282  msg.id = BCN_DROPDOWN;
284  return 0;
285  }
286 
287  if (message == WM_PAINT)
288  {
289  PAINTSTRUCT ps;
290  beginpaint_counter++;
291  BeginPaint( hwnd, &ps );
292  beginpaint_counter--;
293  EndPaint( hwnd, &ps );
294  return 0;
295  }
296 
297  defwndproc_counter++;
299  defwndproc_counter--;
300 
301  return ret;
302 }
303 
304 static const struct message setfocus_seq[] =
305 {
308  { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
309  { WM_SETFOCUS, sent|wparam },
311  { WM_APP, sent|wparam|lparam },
312  { WM_PAINT, sent },
313  { 0 }
314 };
315 
316 static const struct message killfocus_seq[] =
317 {
318  { WM_KILLFOCUS, sent|wparam, 0 },
322  { WM_APP, sent|wparam|lparam, 0, 0 },
323  { WM_PAINT, sent },
324  { 0 }
325 };
326 
327 static const struct message setfocus_static_seq[] =
328 {
331  { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
332  { WM_SETFOCUS, sent|wparam, 0 },
334  { WM_COMMAND, sent|wparam|parent|optional, MAKEWPARAM(ID_BUTTON, BN_CLICKED) }, /* radio button */
335  { WM_APP, sent|wparam|lparam, 0, 0 },
336  { WM_PAINT, sent },
337  { 0 }
338 };
339 
340 static const struct message setfocus_groupbox_seq[] =
341 {
344  { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
345  { WM_SETFOCUS, sent|wparam, 0 },
347  { WM_COMMAND, sent|wparam|parent|optional, MAKEWPARAM(ID_BUTTON, BN_CLICKED) }, /* radio button */
348  { WM_APP, sent|wparam|lparam, 0, 0 },
349  { WM_PAINT, sent },
350  { 0 }
351 };
352 
353 static const struct message killfocus_static_seq[] =
354 {
355  { WM_KILLFOCUS, sent|wparam, 0 },
359  { WM_APP, sent|wparam|lparam, 0, 0 },
360  { WM_PAINT, sent },
361  { 0 }
362 };
363 
364 static const struct message setfocus_ownerdraw_seq[] =
365 {
368  { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
369  { WM_SETFOCUS, sent|wparam, 0 },
372  { WM_APP, sent|wparam|lparam, 0, 0 },
374  { 0 }
375 };
376 
377 static const struct message killfocus_ownerdraw_seq[] =
378 {
379  { WM_KILLFOCUS, sent|wparam, 0 },
383  { WM_APP, sent|wparam|lparam, 0, 0 },
384  { WM_PAINT, sent },
386  { 0 }
387 };
388 
389 static const struct message lbuttondown_seq[] =
390 {
391  { WM_LBUTTONDOWN, sent|wparam|lparam, 0, 0 },
394  { BM_GETSTATE, sent|defwinproc|optional }, /* when touchscreen is present */
397  { 0 }
398 };
399 
400 static const struct message lbuttonup_seq[] =
401 {
402  { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
406  { 0 }
407 };
408 
409 static const struct message setfont_seq[] =
410 {
411  { WM_SETFONT, sent },
412  { 0 }
413 };
414 
415 static const struct message setstyle_seq[] =
416 {
417  { BM_SETSTYLE, sent },
418  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
419  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
420  { WM_APP, sent|wparam|lparam, 0, 0 },
421  { WM_PAINT, sent },
422  { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
424  { WM_PAINT, sent|optional },
425  { 0 }
426 };
427 
428 static const struct message setstyle_static_seq[] =
429 {
430  { BM_SETSTYLE, sent },
431  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
432  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
433  { WM_APP, sent|wparam|lparam, 0, 0 },
434  { WM_PAINT, sent },
435  { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
437  { 0 }
438 };
439 
440 static const struct message setstyle_user_seq[] =
441 {
442  { BM_SETSTYLE, sent },
443  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
444  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
445  { WM_APP, sent|wparam|lparam, 0, 0 },
446  { WM_PAINT, sent },
447  { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
449  { 0 }
450 };
451 
452 static const struct message setstyle_ownerdraw_seq[] =
453 {
454  { BM_SETSTYLE, sent },
455  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
456  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
457  { WM_APP, sent|wparam|lparam, 0, 0 },
458  { WM_PAINT, sent },
459  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
462  { 0 }
463 };
464 
465 static const struct message setstate_seq[] =
466 {
467  { BM_SETSTATE, sent },
468  { WM_APP, sent|wparam|lparam, 0, 0 },
469  { WM_PAINT, sent },
470  { WM_PAINT, sent|optional },
471  { 0 }
472 };
473 
474 static const struct message setstate_static_seq[] =
475 {
476  { BM_SETSTATE, sent },
477  { WM_APP, sent|wparam|lparam, 0, 0 },
478  { WM_PAINT, sent },
479  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
481  { 0 }
482 };
483 
484 static const struct message setstate_user_seq[] =
485 {
486  { BM_SETSTATE, sent },
488  { WM_APP, sent|wparam|lparam, 0, 0 },
489  { WM_PAINT, sent },
490  { 0 }
491 };
492 
493 static const struct message setstate_ownerdraw_seq[] =
494 {
495  { BM_SETSTATE, sent },
496  { WM_APP, sent|wparam|lparam, 0, 0 },
497  { WM_PAINT, sent },
498  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
501  { 0 }
502 };
503 
504 static const struct message clearstate_seq[] =
505 {
506  { BM_SETSTATE, sent },
508  { WM_APP, sent|wparam|lparam, 0, 0 },
509  { WM_PAINT, sent },
510  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
512  { 0 }
513 };
514 
515 static const struct message clearstate_ownerdraw_seq[] =
516 {
517  { BM_SETSTATE, sent },
518  { WM_APP, sent|wparam|lparam, 0, 0 },
519  { WM_PAINT, sent },
520  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
523  { 0 }
524 };
525 
526 static const struct message setcheck_ignored_seq[] =
527 {
528  { BM_SETCHECK, sent },
529  { WM_APP, sent|wparam|lparam, 0, 0 },
530  { WM_PAINT, sent|optional },
531  { 0 }
532 };
533 
534 static const struct message setcheck_static_seq[] =
535 {
536  { BM_SETCHECK, sent },
537  { WM_APP, sent|wparam|lparam, 0, 0 },
538  { WM_PAINT, sent },
539  { WM_NCPAINT, sent|optional }, /* FIXME: Wine sends it */
541  { 0 }
542 };
543 
544 static const struct message setcheck_radio_seq[] =
545 {
546  { BM_SETCHECK, sent },
547  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
548  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
549  { WM_APP, sent|wparam|lparam, 0, 0 },
550  { 0 }
551 };
552 
553 static const struct message setcheck_radio_redraw_seq[] =
554 {
555  { BM_SETCHECK, sent },
556  { WM_STYLECHANGING, sent|wparam|defwinproc, GWL_STYLE },
557  { WM_STYLECHANGED, sent|wparam|defwinproc, GWL_STYLE },
558  { WM_APP, sent|wparam|lparam, 0, 0 },
559  { WM_PAINT, sent },
560  { WM_NCPAINT, sent|defwinproc|optional }, /* FIXME: Wine sends it */
561  { 0 }
562 };
563 
564 static const struct message empty_cd_seq[] = { { 0 } };
565 
566 static const struct message pre_cd_seq[] =
567 {
569  { 0 }
570 };
571 
572 static const struct message pre_pre_cd_seq[] =
573 {
576  { 0 }
577 };
578 
579 static const struct message pre_post_pre_cd_seq[] =
580 {
584  { 0 }
585 };
586 
587 static const struct message pre_pre_post_cd_seq[] =
588 {
592  { 0 }
593 };
594 
595 static const struct message pre_post_pre_post_cd_seq[] =
596 {
601  { 0 }
602 };
603 
604 static const struct message bcn_dropdown_seq[] =
605 {
608  { WM_NOTIFY, sent|parent|id, 0, 0, BCN_DROPDOWN },
610  { WM_KEYUP, sent|wparam|lparam, VK_DOWN, 0xc0000000 },
611  { WM_PAINT, sent },
612  { WM_DRAWITEM, sent|parent|optional }, /* for owner draw button */
613  { WM_PAINT, sent|optional }, /* sometimes sent rarely */
615  { 0 }
616 };
617 
619 {
620  HMENU menuid = 0;
621  HWND hwnd;
622 
623  if (parent)
624  {
626  menuid = (HMENU)ID_BUTTON;
627  }
628  hwnd = CreateWindowExA(0, WC_BUTTONA, "test", style, 0, 0, 50, 14, parent, menuid, 0, NULL);
629  ok(hwnd != NULL, "failed to create a button, 0x%08x, %p\n", style, parent);
630  pSetWindowSubclass(hwnd, button_subclass_proc, 0, 0);
631  return hwnd;
632 }
633 
634 static void test_button_messages(void)
635 {
636  enum cd_seq_type
637  {
638  cd_seq_empty,
639  cd_seq_normal,
640  cd_seq_optional
641  };
642 
643  static const struct
644  {
645  DWORD style;
646  DWORD dlg_code;
647  const struct message *setfocus;
648  const struct message *killfocus;
649  const struct message *setstyle;
650  const struct message *setstate;
651  const struct message *clearstate;
652  const struct message *setcheck;
653  enum cd_seq_type cd_setfocus_type;
654  enum cd_seq_type cd_setstyle_type;
655  enum cd_seq_type cd_setstate_type;
656  enum cd_seq_type cd_setcheck_type;
657  } button[] = {
661  cd_seq_normal, cd_seq_normal, cd_seq_normal, cd_seq_optional },
665  cd_seq_normal, cd_seq_normal, cd_seq_normal, cd_seq_optional },
669  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
673  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
677  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
681  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
685  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
689  cd_seq_empty, cd_seq_empty, cd_seq_empty, cd_seq_empty },
693  cd_seq_normal, cd_seq_empty, cd_seq_empty, cd_seq_empty },
697  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_optional },
701  cd_seq_empty, cd_seq_empty, cd_seq_empty, cd_seq_empty },
705  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_empty },
709  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_empty },
713  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_empty },
717  cd_seq_optional, cd_seq_optional, cd_seq_optional, cd_seq_empty }
718  };
719  LOGFONTA logfont = { 0 };
720  const struct message *seq, *cd_seq;
721  HFONT zfont, hfont2;
722  unsigned int i;
723  HWND hwnd, parent;
724  DWORD dlg_code;
725  BOOL todo;
726 
727  /* selection with VK_SPACE should capture button window */
729  ok(hwnd != 0, "Failed to create button window\n");
730  ReleaseCapture();
731  SetFocus(hwnd);
733  ok(GetCapture() == hwnd, "Should be captured on VK_SPACE WM_KEYDOWN\n");
736 
737  parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
738  100, 100, 200, 200, 0, 0, 0, NULL);
739  ok(parent != 0, "Failed to create parent window\n");
740 
741  logfont.lfHeight = -12;
742  logfont.lfWeight = FW_NORMAL;
743  strcpy(logfont.lfFaceName, "Tahoma");
744 
745  hfont2 = CreateFontIndirectA(&logfont);
746  ok(hfont2 != NULL, "Failed to create Tahoma font\n");
747 
748 #define check_cd_seq(type, context) do { \
749  if (button[i].type != cd_seq_optional || !test_cd.empty) \
750  ok_sequence(sequences, PARENT_CD_SEQ_INDEX, cd_seq, "[CustomDraw] " context, FALSE); \
751  } while(0)
752 
753  for (i = 0; i < ARRAY_SIZE(button); i++)
754  {
755  HFONT prevfont, hfont;
756  MSG msg;
757  DWORD style, state;
758  HDC hdc;
759 
760  test_cd.button = button[i].style;
762  ok(hwnd != NULL, "Failed to create a button.\n");
763 
765  style &= ~(WS_CHILD | BS_NOTIFY);
766  /* XP turns a BS_USERBUTTON into BS_PUSHBUTTON */
767  if (button[i].style == BS_USERBUTTON)
768  ok(style == BS_PUSHBUTTON, "expected style BS_PUSHBUTTON got %x\n", style);
769  else
770  ok(style == button[i].style, "expected style %x got %x\n", button[i].style, style);
771 
772  dlg_code = SendMessageA(hwnd, WM_GETDLGCODE, 0, 0);
773  if (button[i].style == BS_SPLITBUTTON ||
777  {
778  ok(dlg_code == button[i].dlg_code || broken(dlg_code == DLGC_BUTTON) /* WinXP */, "%u: wrong dlg_code %08x\n", i, dlg_code);
779  }
780  else
781  ok(dlg_code == button[i].dlg_code, "%u: wrong dlg_code %08x\n", i, dlg_code);
782 
785  SetFocus(0);
786  flush_events();
787  SetFocus(0);
788  cd_seq = (button[i].cd_setfocus_type == cd_seq_empty) ? empty_cd_seq : pre_pre_cd_seq;
792 
793  ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
794  SetFocus(hwnd);
795  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
796  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
797  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setfocus, "SetFocus(hwnd) on a button", FALSE);
798  check_cd_seq(cd_setfocus_type, "SetFocus(hwnd)");
799 
801  SetFocus(0);
802  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
803  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
804  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].killfocus, "SetFocus(0) on a button", FALSE);
805  check_cd_seq(cd_setfocus_type, "SetFocus(0)");
806  ok(GetFocus() == 0, "expected focus 0, got %p\n", GetFocus());
807 
808  cd_seq = (button[i].cd_setstyle_type == cd_seq_empty) ? empty_cd_seq : pre_pre_cd_seq;
810 
812  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
813  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
814  todo = button[i].style == BS_OWNERDRAW;
815  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setstyle, "BM_SETSTYLE on a button", todo);
816  check_cd_seq(cd_setstyle_type, "BM_SETSTYLE");
817 
820  /* XP doesn't turn a BS_USERBUTTON into BS_PUSHBUTTON here! */
821  ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
822 
824  ok(state == 0, "expected state 0, got %04x\n", state);
825 
826  cd_seq = (button[i].cd_setstate_type == cd_seq_empty) ? empty_cd_seq : pre_pre_cd_seq;
829 
831  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
832  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
833  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setstate, "BM_SETSTATE/TRUE on a button", FALSE);
834  check_cd_seq(cd_setstate_type, "BM_SETSTATE/TRUE");
835 
837  ok(state == BST_PUSHED, "expected state 0x0004, got %04x\n", state);
838 
841  ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
842 
845 
847  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
848  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
849  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].clearstate, "BM_SETSTATE/FALSE on a button", FALSE);
850  check_cd_seq(cd_setstate_type, "BM_SETSTATE/FALSE");
851 
853  ok(state == 0, "expected state 0, got %04x\n", state);
854 
857  ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
858 
860  ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
861 
862  cd_seq = (button[i].cd_setcheck_type == cd_seq_empty) ? empty_cd_seq : pre_pre_cd_seq;
865 
866  if (button[i].style == BS_RADIOBUTTON ||
868  {
869  seq = setcheck_radio_seq;
870  }
871  else
872  seq = setcheck_ignored_seq;
873 
875  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
876  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
877  ok_sequence(sequences, COMBINED_SEQ_INDEX, seq, "BM_SETCHECK on a button", FALSE);
878  check_cd_seq(cd_setcheck_type, "BM_SETCHECK");
879 
881  ok(state == BST_UNCHECKED, "expected BST_UNCHECKED, got %04x\n", state);
882 
885  ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
886 
889 
891  SendMessageA(hwnd, WM_APP, 0, 0); /* place a separator mark here */
892  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
893  ok_sequence(sequences, COMBINED_SEQ_INDEX, button[i].setcheck, "BM_SETCHECK on a button", FALSE);
894  check_cd_seq(cd_setcheck_type, "BM_SETCHECK");
895 
897  if (button[i].style == BS_PUSHBUTTON ||
899  button[i].style == BS_GROUPBOX ||
900  button[i].style == BS_USERBUTTON ||
901  button[i].style == BS_OWNERDRAW ||
906  {
907  ok(state == BST_UNCHECKED, "expected check BST_UNCHECKED, got %04x\n", state);
908  }
909  else
910  ok(state == BST_CHECKED, "expected check BST_CHECKED, got %04x\n", state);
911 
914  if (button[i].style == BS_RADIOBUTTON ||
916  ok(style == (button[i].style | WS_TABSTOP), "expected style %04x | WS_TABSTOP got %04x\n", button[i].style, style);
917  else
918  ok(style == button[i].style, "expected style %04x got %04x\n", button[i].style, style);
919 
920  /* Test that original font is not selected back after painting */
922  ok(hfont == NULL, "Unexpected control font.\n");
923 
925 
926  hdc = CreateCompatibleDC(0);
927 
928  prevfont = SelectObject(hdc, hfont2);
930  ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT) || broken(hfont2 == GetCurrentObject(hdc, OBJ_FONT)) /* WinXP */,
931  "button[%u]: unexpected font selected after WM_PRINTCLIENT\n", i);
932  SelectObject(hdc, prevfont);
933 
934  prevfont = SelectObject(hdc, hfont2);
936  ok(hfont2 != GetCurrentObject(hdc, OBJ_FONT) || broken(hfont2 == GetCurrentObject(hdc, OBJ_FONT)) /* WinXP */,
937  "button[%u]: unexpected font selected after WM_PAINT\n", i);
938  SelectObject(hdc, prevfont);
939 
940  DeleteDC(hdc);
941 
942  /* Test Custom Draw return values */
943  if (button[i].cd_setfocus_type != cd_seq_empty &&
944  broken(button[i].style != BS_USERBUTTON) /* WinXP */)
945  {
946  static const struct
947  {
948  const char *context;
949  LRESULT val;
950  const struct message *seq;
951  } ret[] = {
952  { "CDRF_DODEFAULT", CDRF_DODEFAULT, pre_pre_cd_seq },
953  { "CDRF_DOERASE", CDRF_DOERASE, pre_pre_cd_seq },
954  { "CDRF_SKIPDEFAULT", CDRF_SKIPDEFAULT, pre_cd_seq },
955  { "CDRF_SKIPDEFAULT | CDRF_NOTIFYPOSTERASE | CDRF_NOTIFYPOSTPAINT",
957  { "CDRF_NOTIFYPOSTERASE", CDRF_NOTIFYPOSTERASE, pre_post_pre_cd_seq },
958  { "CDRF_NOTIFYPOSTPAINT", CDRF_NOTIFYPOSTPAINT, pre_pre_post_cd_seq },
959  { "CDRF_NOTIFYPOSTERASE | CDRF_NOTIFYPOSTPAINT",
961  };
962  UINT k;
963 
964  for (k = 0; k < ARRAY_SIZE(ret); k++)
965  {
966  disable_test_cd();
967  SetFocus(0);
970  SetFocus(hwnd);
972 
973  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
974  if (button[i].cd_setfocus_type != cd_seq_optional || !test_cd.empty)
976  }
977  }
978 
979  disable_test_cd();
980 
981  if (!broken(LOBYTE(LOWORD(GetVersion())) < 6)) /* not available pre-Vista */
982  {
983  /* Send down arrow key to make the buttons send the drop down notification */
986  SendMessageW(hwnd, WM_KEYUP, VK_DOWN, 0xc0000000);
987  while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
988  ok_sequence(sequences, COMBINED_SEQ_INDEX, bcn_dropdown_seq, "BCN_DROPDOWN from the button", FALSE);
989  }
990 
992  }
993 
994 #undef check_cd_seq
995 
996  DeleteObject(hfont2);
998 
1000 
1002  flush_events();
1003 
1005  SetFocus(0);
1007 
1009  ok_sequence(sequences, COMBINED_SEQ_INDEX, lbuttondown_seq, "WM_LBUTTONDOWN on a button", FALSE);
1010 
1011  SendMessageA(hwnd, WM_LBUTTONUP, 0, 0);
1012  ok_sequence(sequences, COMBINED_SEQ_INDEX, lbuttonup_seq, "WM_LBUTTONUP on a button", TRUE);
1013 
1015  zfont = GetStockObject(SYSTEM_FONT);
1016  SendMessageA(hwnd, WM_SETFONT, (WPARAM)zfont, TRUE);
1017  UpdateWindow(hwnd);
1018  ok_sequence(sequences, COMBINED_SEQ_INDEX, setfont_seq, "WM_SETFONT on a button", FALSE);
1019 
1021 }
1022 
1023 static void test_button_class(void)
1024 {
1025  static const WCHAR testW[] = {'t','e','s','t',0};
1026  WNDCLASSEXW exW, ex2W;
1027  WNDCLASSEXA exA;
1028  char buffA[100];
1029  WCHAR *nameW;
1030  HWND hwnd;
1031  BOOL ret;
1032  int len;
1033 
1034  ret = GetClassInfoExA(NULL, WC_BUTTONA, &exA);
1035  ok(ret, "got %d\n", ret);
1036  ok(IS_WNDPROC_HANDLE(exA.lpfnWndProc), "got %p\n", exA.lpfnWndProc);
1037  ok(exA.cbClsExtra == 0, "Unexpected class bytes %d.\n", exA.cbClsExtra);
1038  ok(exA.cbWndExtra == sizeof(void *), "Unexpected window bytes %d.\n", exA.cbWndExtra);
1039 
1040  ret = GetClassInfoExW(NULL, WC_BUTTONW, &exW);
1041  ok(ret, "got %d\n", ret);
1042  ok(!IS_WNDPROC_HANDLE(exW.lpfnWndProc), "got %p\n", exW.lpfnWndProc);
1043  ok(exW.cbClsExtra == 0, "Unexpected class bytes %d.\n", exW.cbClsExtra);
1044  ok(exW.cbWndExtra == sizeof(void *), "Unexpected window bytes %d.\n", exW.cbWndExtra);
1045 
1046  /* check that versioned class is also accessible */
1048  ok(lstrcmpW(nameW, WC_BUTTONW), "got %s\n", wine_dbgstr_w(nameW));
1049 
1050  ret = GetClassInfoExW(NULL, nameW, &ex2W);
1051  ok(ret, "got %d\n", ret);
1052  ok(ex2W.lpfnWndProc == exW.lpfnWndProc, "got %p, %p\n", exW.lpfnWndProc, ex2W.lpfnWndProc);
1053 
1054  /* Check reported class name */
1056  len = GetClassNameA(hwnd, buffA, sizeof(buffA));
1057  ok(len == strlen(buffA), "got %d\n", len);
1058  ok(!strcmp(buffA, "Button"), "got %s\n", buffA);
1059 
1060  len = RealGetWindowClassA(hwnd, buffA, sizeof(buffA));
1061  ok(len == strlen(buffA), "got %d\n", len);
1062  ok(!strcmp(buffA, "Button"), "got %s\n", buffA);
1064 
1065  /* explicitly create with versioned class name */
1066  hwnd = CreateWindowExW(0, nameW, testW, BS_CHECKBOX, 0, 0, 50, 14, NULL, 0, 0, NULL);
1067  ok(hwnd != NULL, "failed to create a window %s\n", wine_dbgstr_w(nameW));
1068 
1069  len = GetClassNameA(hwnd, buffA, sizeof(buffA));
1070  ok(len == strlen(buffA), "got %d\n", len);
1071  ok(!strcmp(buffA, "Button"), "got %s\n", buffA);
1072 
1073  len = RealGetWindowClassA(hwnd, buffA, sizeof(buffA));
1074  ok(len == strlen(buffA), "got %d\n", len);
1075  ok(!strcmp(buffA, "Button"), "got %s\n", buffA);
1076 
1078 }
1079 
1080 static void test_note(void)
1081 {
1082  HWND hwnd;
1083  BOOL ret;
1084  WCHAR test_w[] = {'t', 'e', 's', 't', 0};
1085  WCHAR tes_w[] = {'t', 'e', 's', 0};
1086  WCHAR deadbeef_w[] = {'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f', 0};
1087  WCHAR buffer_w[10];
1088  DWORD size;
1089  DWORD error;
1090  INT type;
1091 
1093  ok(hwnd != NULL, "Expect hwnd not null\n");
1094  SetLastError(0xdeadbeef);
1095  size = ARRAY_SIZE(buffer_w);
1096  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1097  error = GetLastError();
1098  if (!ret && error == 0xdeadbeef)
1099  {
1100  win_skip("BCM_GETNOTE message is unavailable. Skipping note tests\n"); /* xp or 2003 */
1102  return;
1103  }
1105 
1107  {
1109  {
1111  ok(hwnd != NULL, "Expect hwnd not null\n");
1112 
1113  /* Get note when note hasn't been not set yet */
1114  SetLastError(0xdeadbeef);
1115  lstrcpyW(buffer_w, deadbeef_w);
1116  size = ARRAY_SIZE(buffer_w);
1117  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1118  error = GetLastError();
1119  ok(!ret, "Expect BCM_GETNOTE return false\n");
1120  ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
1121  wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
1122  ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
1123  ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
1125 
1126  /* Get note length when note is not set */
1128  ok(ret == 0, "Expect note length: %d, got: %d\n", 0, ret);
1129 
1130  /* Successful set note, get note and get note length */
1131  SetLastError(0xdeadbeef);
1133  ok(ret, "Expect BCM_SETNOTE return true\n");
1134  error = GetLastError();
1135  ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
1136 
1137  SetLastError(0xdeadbeef);
1138  lstrcpyW(buffer_w, deadbeef_w);
1139  size = ARRAY_SIZE(buffer_w);
1140  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1141  ok(ret, "Expect BCM_GETNOTE return true\n");
1142  ok(!lstrcmpW(buffer_w, test_w), "Expect note: %s, got: %s\n", wine_dbgstr_w(test_w),
1143  wine_dbgstr_w(buffer_w));
1144  ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
1145  error = GetLastError();
1146  ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
1147 
1149  ok(ret == ARRAY_SIZE(test_w) - 1, "Got: %d\n", ret);
1150 
1151  /* Insufficient buffer, return partial string */
1152  SetLastError(0xdeadbeef);
1153  lstrcpyW(buffer_w, deadbeef_w);
1154  size = ARRAY_SIZE(test_w) - 1;
1155  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1156  ok(!ret, "Expect BCM_GETNOTE return false\n");
1157  ok(!lstrcmpW(buffer_w, tes_w), "Expect note: %s, got: %s\n", wine_dbgstr_w(tes_w),
1158  wine_dbgstr_w(buffer_w));
1159  ok(size == ARRAY_SIZE(test_w), "Got: %d\n", size);
1160  error = GetLastError();
1161  ok(error == ERROR_INSUFFICIENT_BUFFER, "Expect last error: 0x%08x, got: 0x%08x\n",
1163 
1164  /* Set note with NULL buffer */
1165  SetLastError(0xdeadbeef);
1166  ret = SendMessageA(hwnd, BCM_SETNOTE, 0, 0);
1167  ok(ret, "Expect BCM_SETNOTE return false\n");
1168  error = GetLastError();
1169  ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
1170 
1171  /* Check that set note with NULL buffer make note empty */
1172  SetLastError(0xdeadbeef);
1173  lstrcpyW(buffer_w, deadbeef_w);
1174  size = ARRAY_SIZE(buffer_w);
1175  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1176  ok(ret, "Expect BCM_GETNOTE return true\n");
1177  ok(lstrlenW(buffer_w) == 0, "Expect note length 0\n");
1178  ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
1179  error = GetLastError();
1180  ok(error == NO_ERROR, "Expect last error: 0x%08x, got: 0x%08x\n", NO_ERROR, error);
1182  ok(ret == 0, "Expect note length: %d, got: %d\n", 0, ret);
1183 
1184  /* Get note with NULL buffer */
1185  SetLastError(0xdeadbeef);
1186  size = ARRAY_SIZE(buffer_w);
1188  ok(!ret, "Expect BCM_SETNOTE return false\n");
1189  ok(size == ARRAY_SIZE(buffer_w), "Got: %d\n", size);
1190  error = GetLastError();
1191  ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
1193 
1194  /* Get note with NULL size */
1195  SetLastError(0xdeadbeef);
1196  lstrcpyW(buffer_w, deadbeef_w);
1197  ret = SendMessageA(hwnd, BCM_GETNOTE, 0, (LPARAM)buffer_w);
1198  ok(!ret, "Expect BCM_SETNOTE return false\n");
1199  ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
1200  wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
1201  error = GetLastError();
1202  ok(error == ERROR_INVALID_PARAMETER, "Expect last error: 0x%08x, got: 0x%08x\n",
1204 
1205  /* Get note with zero size */
1206  SetLastError(0xdeadbeef);
1207  size = 0;
1208  lstrcpyW(buffer_w, deadbeef_w);
1209  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1210  ok(!ret, "Expect BCM_GETNOTE return false\n");
1211  ok(!lstrcmpW(buffer_w, deadbeef_w), "Expect note: %s, got: %s\n",
1212  wine_dbgstr_w(deadbeef_w), wine_dbgstr_w(buffer_w));
1213  ok(size == 1, "Got: %d\n", size);
1214  error = GetLastError();
1215  ok(error == ERROR_INSUFFICIENT_BUFFER, "Expect last error: 0x%08x, got: 0x%08x\n",
1217 
1219  }
1220  else
1221  {
1223  ok(hwnd != NULL, "Expect hwnd not null\n");
1224  SetLastError(0xdeadbeef);
1225  size = ARRAY_SIZE(buffer_w);
1226  ret = SendMessageA(hwnd, BCM_GETNOTE, (WPARAM)&size, (LPARAM)buffer_w);
1227  ok(!ret, "Expect BCM_GETNOTE return false\n");
1228  error = GetLastError();
1229  ok(error == ERROR_NOT_SUPPORTED, "Expect last error: 0x%08x, got: 0x%08x\n",
1232  }
1233  }
1234 }
1235 
1236 static void test_bm_get_set_image(void)
1237 {
1238  HWND hwnd;
1239  HDC hdc;
1240  HBITMAP hbmp1x1;
1241  HBITMAP hbmp2x2;
1242  HBITMAP hmask2x2;
1243  ICONINFO icon_info2x2;
1244  HICON hicon2x2;
1245  HBITMAP hbmp;
1246  HICON hicon;
1247  ICONINFO icon_info;
1248  BITMAP bm;
1249  static const DWORD default_style = BS_PUSHBUTTON | WS_TABSTOP | WS_POPUP | WS_VISIBLE;
1250 
1251  hdc = GetDC(0);
1252  hbmp1x1 = CreateCompatibleBitmap(hdc, 1, 1);
1253  hbmp2x2 = CreateCompatibleBitmap(hdc, 2, 2);
1254  ZeroMemory(&bm, sizeof(bm));
1255  ok(GetObjectW(hbmp1x1, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1256  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1257  bm.bmWidth, bm.bmHeight);
1258  ZeroMemory(&bm, sizeof(bm));
1259  ok(GetObjectW(hbmp2x2, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1260  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1261  bm.bmWidth, bm.bmHeight);
1262 
1263  hmask2x2 = CreateCompatibleBitmap(hdc, 2, 2);
1264  ZeroMemory(&icon_info2x2, sizeof(icon_info2x2));
1265  icon_info2x2.fIcon = TRUE;
1266  icon_info2x2.hbmMask = hmask2x2;
1267  icon_info2x2.hbmColor = hbmp2x2;
1268  hicon2x2 = CreateIconIndirect(&icon_info2x2);
1269  ok(hicon2x2 !=NULL, "Expect CreateIconIndirect() success\n");
1270 
1271  ZeroMemory(&icon_info, sizeof(icon_info));
1272  ok(GetIconInfo(hicon2x2, &icon_info), "Expect GetIconInfo() success\n");
1273  ZeroMemory(&bm, sizeof(bm));
1274  ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1275  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1276  bm.bmWidth, bm.bmHeight);
1277  DeleteObject(icon_info.hbmColor);
1278  DeleteObject(icon_info.hbmMask);
1279 
1280  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
1281  0, 0);
1282  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1283  /* Get image when image is not set */
1285  ok(hbmp == 0, "Expect hbmp == 0\n");
1286  /* Set image */
1288  ok(hbmp == 0, "Expect hbmp == 0\n");
1290  ok(hbmp != 0, "Expect hbmp != 0\n");
1291  /* Set null resets image */
1293  ok(hbmp != 0, "Expect hbmp != 0\n");
1295  ok(hbmp == 0, "Expect hbmp == 0\n");
1297 
1298  /* Set bitmap with BS_BITMAP */
1299  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
1300  0, 0);
1301  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1303  ok(hbmp == 0, "Expect hbmp == 0\n");
1305  ok(hbmp != 0, "Expect hbmp != 0\n");
1306  ZeroMemory(&bm, sizeof(bm));
1307  ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1308  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1309  bm.bmWidth, bm.bmHeight);
1311 
1312  /* Set bitmap without BS_BITMAP */
1313  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
1314  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1316  ok(hbmp == 0, "Expect hbmp == 0\n");
1318  if (hbmp == 0)
1319  {
1320  /* on xp or 2003*/
1321  win_skip("Show both image and text is not supported. Skip following tests.\n");
1323  goto done;
1324  }
1325  ok(hbmp != 0, "Expect hbmp != 0\n");
1326  ZeroMemory(&bm, sizeof(bm));
1327  ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1328  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1329  bm.bmWidth, bm.bmHeight);
1331 
1332  /* Set icon with BS_ICON */
1333  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
1334  0);
1335  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1336  hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
1337  ok(hicon == 0, "Expect hicon == 0\n");
1338  hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
1339  ok(hicon != 0, "Expect hicon != 0\n");
1340  ZeroMemory(&icon_info, sizeof(icon_info));
1341  ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
1342  ZeroMemory(&bm, sizeof(bm));
1343  ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1344  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1345  bm.bmWidth, bm.bmHeight);
1346  DeleteObject(icon_info.hbmColor);
1347  DeleteObject(icon_info.hbmMask);
1349 
1350  /* Set icon without BS_ICON */
1351  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style, 0, 0, 100, 100, 0, 0, 0, 0);
1352  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1353  hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
1354  ok(hicon == 0, "Expect hicon == 0\n");
1355  hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
1356  ok(hicon != 0, "Expect hicon != 0\n");
1357  ZeroMemory(&icon_info, sizeof(icon_info));
1358  ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
1359  ZeroMemory(&bm, sizeof(bm));
1360  ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1361  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1362  bm.bmWidth, bm.bmHeight);
1363  DeleteObject(icon_info.hbmColor);
1364  DeleteObject(icon_info.hbmMask);
1366 
1367  /* Set icon with BS_BITMAP */
1368  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
1369  0, 0);
1370  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1371  hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_ICON, (LPARAM)hicon2x2);
1372  ok(hicon == 0, "Expect hicon == 0\n");
1373  hicon = (HICON)SendMessageA(hwnd, BM_GETIMAGE, IMAGE_ICON, 0);
1374  ok(hicon != 0, "Expect hicon != 0\n");
1375  ZeroMemory(&icon_info, sizeof(icon_info));
1376  ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
1377  ZeroMemory(&bm, sizeof(bm));
1378  ok(GetObjectW(icon_info.hbmColor, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1379  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1380  bm.bmWidth, bm.bmHeight);
1381  DeleteObject(icon_info.hbmColor);
1382  DeleteObject(icon_info.hbmMask);
1384 
1385  /* Set bitmap with BS_ICON */
1386  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
1387  0);
1388  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1390  ok(hbmp == 0, "Expect hbmp == 0\n");
1392  ok(hbmp != 0, "Expect hbmp != 0\n");
1393  ZeroMemory(&bm, sizeof(bm));
1394  ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1395  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1396  bm.bmWidth, bm.bmHeight);
1398 
1399  /* Set bitmap with BS_BITMAP and IMAGE_ICON*/
1400  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0,
1401  0, 0);
1402  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1404  ok(hbmp == 0, "Expect hbmp == 0\n");
1406  ok(hbmp != 0, "Expect hbmp != 0\n");
1407  ZeroMemory(&bm, sizeof(bm));
1408  ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1409  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1410  bm.bmWidth, bm.bmHeight);
1412 
1413  /* Set icon with BS_ICON and IMAGE_BITMAP */
1414  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0,
1415  0);
1416  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1417  hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
1418  ok(hicon == 0, "Expect hicon == 0\n");
1420  ok(hicon != 0, "Expect hicon != 0\n");
1421  ZeroMemory(&icon_info, sizeof(icon_info));
1422  ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
1423  ZeroMemory(&bm, sizeof(bm));
1424  ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
1425  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1426  bm.bmWidth, bm.bmHeight);
1427  DeleteObject(icon_info.hbmColor);
1428  DeleteObject(icon_info.hbmMask);
1430 
1431  /* Set bitmap with BS_ICON and IMAGE_ICON */
1432  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_ICON, 0, 0, 100, 100, 0, 0, 0, 0);
1433  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1435  ok(hbmp == 0, "Expect hbmp == 0\n");
1437  ok(hbmp != 0, "Expect hbmp != 0\n");
1438  ZeroMemory(&bm, sizeof(bm));
1439  ok(GetObjectW(hbmp, sizeof(bm), &bm), "Expect GetObjectW() success\n");
1440  ok(bm.bmWidth == 1 && bm.bmHeight == 1, "Expect bitmap size: %d,%d, got: %d,%d\n", 1, 1,
1441  bm.bmWidth, bm.bmHeight);
1443 
1444  /* Set icon with BS_BITMAP and IMAGE_BITMAP */
1445  hwnd = CreateWindowA(WC_BUTTONA, "test", default_style | BS_BITMAP, 0, 0, 100, 100, 0, 0, 0, 0);
1446  ok(hwnd != NULL, "Expect hwnd to be not NULL\n");
1447  hicon = (HICON)SendMessageA(hwnd, BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)hicon2x2);
1448  ok(hicon == 0, "Expect hicon == 0\n");
1450  ok(hicon != 0, "Expect hicon != 0\n");
1451  ZeroMemory(&icon_info, sizeof(icon_info));
1452  ok(GetIconInfo(hicon, &icon_info), "Expect GetIconInfo() success\n");
1453  ZeroMemory(&bm, sizeof(bm));
1454  ok(GetObjectW(icon_info.hbmColor, sizeof(BITMAP), &bm), "Expect GetObjectW() success\n");
1455  ok(bm.bmWidth == 2 && bm.bmHeight == 2, "Expect bitmap size: %d,%d, got: %d,%d\n", 2, 2,
1456  bm.bmWidth, bm.bmHeight);
1457  DeleteObject(icon_info.hbmColor);
1458  DeleteObject(icon_info.hbmMask);
1460 
1461 done:
1462  DestroyIcon(hicon2x2);
1463  DeleteObject(hmask2x2);
1464  DeleteObject(hbmp2x2);
1465  DeleteObject(hbmp1x1);
1466  ReleaseDC(0, hdc);
1467 }
1468 
1469 static void register_parent_class(void)
1470 {
1471  WNDCLASSA cls;
1472 
1473  cls.style = 0;
1475  cls.cbClsExtra = 0;
1476  cls.cbWndExtra = 0;
1477  cls.hInstance = GetModuleHandleA(0);
1478  cls.hIcon = 0;
1479  cls.hCursor = LoadCursorA(0, (LPCSTR)IDC_ARROW);
1481  cls.lpszMenuName = NULL;
1482  cls.lpszClassName = "TestParentClass";
1483  RegisterClassA(&cls);
1484 }
1485 
1487 {
1489  int glyph_size = GetSystemMetrics(SM_CYMENUCHECK);
1490  int border_w = GetSystemMetrics(SM_CXEDGE) * 2;
1492  HIMAGELIST img;
1493  BOOL ret;
1494 
1495  memset(&info, 0xCC, sizeof(info));
1496  info.mask = 0;
1497  memcpy(&dummy, &info, sizeof(info));
1498 
1500  if (ret != TRUE)
1501  {
1502  static BOOL once;
1503  if (!once)
1504  win_skip("BCM_GETSPLITINFO message is unavailable. Skipping related tests\n"); /* Pre-Vista */
1505  once = TRUE;
1506  return;
1507  }
1508  ok(!memcmp(&info, &dummy, sizeof(info)), "[%u] split info struct was changed with mask = 0\n", button);
1509 
1511  ok(ret == FALSE, "[%u] expected FALSE, got %d\n", button, ret);
1513  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1514 
1517  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1518  ok(info.mask == (BCSIF_GLYPH | BCSIF_SIZE | BCSIF_STYLE), "[%u] wrong mask, got %u\n", button, info.mask);
1519  ok(info.himlGlyph == (HIMAGELIST)0x36, "[%u] expected 0x36 default glyph, got 0x%p\n", button, info.himlGlyph);
1520  ok(info.uSplitStyle == BCSS_STRETCH, "[%u] expected 0x%08x default style, got 0x%08x\n", button, BCSS_STRETCH, info.uSplitStyle);
1521  ok(info.size.cx == glyph_size, "[%u] expected %d default size.cx, got %d\n", button, glyph_size, info.size.cx);
1522  ok(info.size.cy == 0, "[%u] expected 0 default size.cy, got %d\n", button, info.size.cy);
1523 
1524  info.mask = BCSIF_SIZE;
1525  info.size.cx = glyph_size + 7;
1526  info.size.cy = 0;
1528  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1529  info.size.cx = info.size.cy = 0xdeadbeef;
1531  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1532  ok(info.mask == BCSIF_SIZE, "[%u] wrong mask, got %u\n", button, info.mask);
1533  ok(info.size.cx == glyph_size + 7, "[%u] expected %d, got %d\n", button, glyph_size + 7, info.size.cx);
1534  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1535 
1536  /* Invalid size.cx resets it to default glyph size, while size.cy is stored */
1537  info.size.cx = 0;
1538  info.size.cy = -20;
1540  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1541  info.size.cx = info.size.cy = 0xdeadbeef;
1543  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1544  ok(info.mask == BCSIF_SIZE, "[%u] wrong mask, got %u\n", button, info.mask);
1545  ok(info.size.cx == glyph_size, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1546  ok(info.size.cy == -20, "[%u] expected -20, got %d\n", button, info.size.cy);
1547 
1548  info.size.cx = -glyph_size - 7;
1549  info.size.cy = -10;
1551  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1552  info.size.cx = info.size.cy = 0xdeadbeef;
1554  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1555  ok(info.mask == BCSIF_SIZE, "[%u] wrong mask, got %u\n", button, info.mask);
1556  ok(info.size.cx == glyph_size, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1557  ok(info.size.cy == -10, "[%u] expected -10, got %d\n", button, info.size.cy);
1558 
1559  /* Set to a valid size other than glyph_size */
1560  info.mask = BCSIF_SIZE;
1561  info.size.cx = glyph_size + 7;
1562  info.size.cy = 11;
1564  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1565  info.size.cx = info.size.cy = 0xdeadbeef;
1567  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1568  ok(info.mask == BCSIF_SIZE, "[%u] wrong mask, got %u\n", button, info.mask);
1569  ok(info.size.cx == glyph_size + 7, "[%u] expected %d, got %d\n", button, glyph_size + 7, info.size.cx);
1570  ok(info.size.cy == 11, "[%u] expected 11, got %d\n", button, info.size.cy);
1571 
1572  /* Change the glyph, size.cx should be automatically adjusted and size.cy set to 0 */
1573  dummy.mask = BCSIF_GLYPH;
1574  dummy.himlGlyph = (HIMAGELIST)0x35;
1576  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1577  info.mask = BCSIF_GLYPH | BCSIF_SIZE;
1579  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1580  ok(info.mask == (BCSIF_GLYPH | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1581  ok(info.himlGlyph == (HIMAGELIST)0x35, "[%u] expected 0x35, got %p\n", button, info.himlGlyph);
1582  ok(info.size.cx == glyph_size, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1583  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1584 
1585  /* Unless the size is specified manually */
1586  dummy.mask = BCSIF_GLYPH | BCSIF_SIZE;
1587  dummy.himlGlyph = (HIMAGELIST)0x34;
1588  dummy.size.cx = glyph_size + 11;
1589  dummy.size.cy = 7;
1591  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1593  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1594  ok(info.mask == (BCSIF_GLYPH | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1595  ok(info.himlGlyph == (HIMAGELIST)0x34, "[%u] expected 0x34, got %p\n", button, info.himlGlyph);
1596  ok(info.size.cx == glyph_size + 11, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1597  ok(info.size.cy == 7, "[%u] expected 7, got %d\n", button, info.size.cy);
1598 
1599  /* Add the BCSS_IMAGE style manually with the wrong BCSIF_GLYPH mask, should treat it as invalid image */
1600  info.mask = BCSIF_GLYPH | BCSIF_STYLE;
1601  info.himlGlyph = (HIMAGELIST)0x37;
1602  info.uSplitStyle = BCSS_IMAGE;
1604  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1605  info.mask |= BCSIF_SIZE;
1607  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1608  ok(info.mask == (BCSIF_GLYPH | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1609  ok(info.himlGlyph == (HIMAGELIST)0x37, "[%u] expected 0x37, got %p\n", button, info.himlGlyph);
1610  ok(info.uSplitStyle == BCSS_IMAGE, "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_IMAGE, info.uSplitStyle);
1611  ok(info.size.cx == border_w, "[%u] expected %d, got %d\n", button, border_w, info.size.cx);
1612  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1613 
1614  /* Change the size to prevent ambiguity */
1615  dummy.mask = BCSIF_SIZE;
1616  dummy.size.cx = glyph_size + 5;
1617  dummy.size.cy = 4;
1619  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1621  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1622  ok(info.mask == (BCSIF_GLYPH | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1623  ok(info.himlGlyph == (HIMAGELIST)0x37, "[%u] expected 0x37, got %p\n", button, info.himlGlyph);
1624  ok(info.uSplitStyle == BCSS_IMAGE, "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_IMAGE, info.uSplitStyle);
1625  ok(info.size.cx == glyph_size + 5, "[%u] expected %d, got %d\n", button, glyph_size + 5, info.size.cx);
1626  ok(info.size.cy == 4, "[%u] expected 4, got %d\n", button, info.size.cy);
1627 
1628  /* Now remove the BCSS_IMAGE style manually with the wrong BCSIF_IMAGE mask */
1629  info.mask = BCSIF_IMAGE | BCSIF_STYLE;
1630  info.himlGlyph = (HIMAGELIST)0x35;
1631  info.uSplitStyle = BCSS_STRETCH;
1633  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1634  info.mask |= BCSIF_SIZE;
1636  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1637  ok(info.mask == (BCSIF_IMAGE | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1638  ok(info.himlGlyph == (HIMAGELIST)0x35, "[%u] expected 0x35, got %p\n", button, info.himlGlyph);
1639  ok(info.uSplitStyle == BCSS_STRETCH, "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_STRETCH, info.uSplitStyle);
1640  ok(info.size.cx == glyph_size, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1641  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1642 
1643  /* Add a proper valid image, the BCSS_IMAGE style should be set automatically */
1644  img = pImageList_Create(42, 33, ILC_COLOR, 1, 1);
1645  ok(img != NULL, "[%u] failed to create ImageList\n", button);
1646  info.mask = BCSIF_IMAGE;
1647  info.himlGlyph = img;
1649  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1650  info.mask |= BCSIF_STYLE | BCSIF_SIZE;
1652  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1653  ok(info.mask == (BCSIF_IMAGE | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1654  ok(info.himlGlyph == img, "[%u] expected %p, got %p\n", button, img, info.himlGlyph);
1655  ok(info.uSplitStyle == (BCSS_IMAGE | BCSS_STRETCH), "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_IMAGE | BCSS_STRETCH, info.uSplitStyle);
1656  ok(info.size.cx == 42 + border_w, "[%u] expected %d, got %d\n", button, 42 + border_w, info.size.cx);
1657  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1658  pImageList_Destroy(img);
1659  dummy.mask = BCSIF_SIZE;
1660  dummy.size.cx = glyph_size + 5;
1661  dummy.size.cy = 4;
1663  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1664 
1665  /* Change it to a glyph; when both specified, BCSIF_GLYPH takes priority */
1666  info.mask = BCSIF_GLYPH | BCSIF_IMAGE;
1667  info.himlGlyph = (HIMAGELIST)0x37;
1669  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1670  info.mask |= BCSIF_STYLE | BCSIF_SIZE;
1672  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1673  ok(info.mask == (BCSIF_GLYPH | BCSIF_IMAGE | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1674  ok(info.himlGlyph == (HIMAGELIST)0x37, "[%u] expected 0x37, got %p\n", button, info.himlGlyph);
1675  ok(info.uSplitStyle == BCSS_STRETCH, "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_STRETCH, info.uSplitStyle);
1676  ok(info.size.cx == glyph_size, "[%u] expected %d, got %d\n", button, glyph_size, info.size.cx);
1677  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1678 
1679  /* Try a NULL image */
1680  info.mask = BCSIF_IMAGE;
1681  info.himlGlyph = NULL;
1683  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1684  info.mask |= BCSIF_STYLE | BCSIF_SIZE;
1686  ok(ret == TRUE, "[%u] expected TRUE, got %d\n", button, ret);
1687  ok(info.mask == (BCSIF_IMAGE | BCSIF_STYLE | BCSIF_SIZE), "[%u] wrong mask, got %u\n", button, info.mask);
1688  ok(info.himlGlyph == NULL, "[%u] expected NULL, got %p\n", button, info.himlGlyph);
1689  ok(info.uSplitStyle == (BCSS_IMAGE | BCSS_STRETCH), "[%u] expected 0x%08x style, got 0x%08x\n", button, BCSS_IMAGE | BCSS_STRETCH, info.uSplitStyle);
1690  ok(info.size.cx == border_w, "[%u] expected %d, got %d\n", button, border_w, info.size.cx);
1691  ok(info.size.cy == 0, "[%u] expected 0, got %d\n", button, info.size.cy);
1692 }
1693 
1694 static void test_button_data(void)
1695 {
1696  static const DWORD styles[] =
1697  {
1698  BS_PUSHBUTTON,
1700  BS_CHECKBOX,
1703  BS_3STATE,
1704  BS_AUTO3STATE,
1705  BS_GROUPBOX,
1706  BS_USERBUTTON,
1708  BS_OWNERDRAW,
1713  };
1714 
1715  struct button_desc
1716  {
1717  HWND self;
1718  HWND parent;
1719  LONG style;
1720  };
1721  unsigned int i;
1722  HWND parent;
1723 
1724  parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
1725  100, 100, 200, 200, 0, 0, 0, NULL);
1726  ok(parent != 0, "Failed to create parent window\n");
1727 
1728  for (i = 0; i < ARRAY_SIZE(styles); i++)
1729  {
1730  struct button_desc *desc;
1731  HWND hwnd;
1732 
1733  hwnd = create_button(styles[i], parent);
1734  ok(hwnd != NULL, "Failed to create a button.\n");
1735 
1736  desc = (void *)GetWindowLongPtrA(hwnd, 0);
1737  ok(desc != NULL, "Expected window data.\n");
1738 
1739  if (desc)
1740  {
1741  ok(desc->self == hwnd, "Unexpected 'self' field.\n");
1742  ok(desc->parent == parent, "Unexpected 'parent' field.\n");
1743  ok(desc->style == (WS_CHILD | BS_NOTIFY | styles[i]), "Unexpected 'style' field.\n");
1744  }
1745 
1746  /* Data set and retrieved by these messages is valid for all buttons */
1748 
1750  }
1751 
1753 }
1754 
1755 static void test_get_set_imagelist(void)
1756 {
1757  HWND hwnd;
1758  HIMAGELIST himl;
1759  BUTTON_IMAGELIST biml = {0};
1760  HDC hdc;
1761  HBITMAP hbmp;
1762  INT width = 16;
1763  INT height = 16;
1764  INT index;
1765  DWORD type;
1766  BOOL ret;
1767 
1768  hdc = GetDC(0);
1770  ok(hbmp != NULL, "Expect hbmp not null\n");
1771 
1772  himl = pImageList_Create(width, height, ILC_COLOR, 1, 0);
1773  ok(himl != NULL, "Expect himl not null\n");
1774  index = pImageList_Add(himl, hbmp, NULL);
1775  ok(index == 0, "Expect index == 0\n");
1776  DeleteObject(hbmp);
1777  ReleaseDC(0, hdc);
1778 
1780  {
1782  ok(hwnd != NULL, "Expect hwnd not null\n");
1783 
1784  /* Get imagelist when imagelist is unset yet */
1785  ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
1786  ok(ret, "Expect BCM_GETIMAGELIST return true\n");
1787  ok(biml.himl == 0 && IsRectEmpty(&biml.margin) && biml.uAlign == 0,
1788  "Expect BUTTON_IMAGELIST is empty\n");
1789 
1790  /* Set imagelist with himl null */
1791  biml.himl = 0;
1792  biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
1793  ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
1794  ok(ret || broken(!ret), /* xp or 2003 */
1795  "Expect BCM_SETIMAGELIST return true\n");
1796 
1797  /* Set imagelist with uAlign invalid */
1798  biml.himl = himl;
1799  biml.uAlign = -1;
1800  ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
1801  ok(ret, "Expect BCM_SETIMAGELIST return true\n");
1802 
1803  /* Successful get and set imagelist */
1804  biml.himl = himl;
1805  biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
1806  ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
1807  ok(ret, "Expect BCM_SETIMAGELIST return true\n");
1808  ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
1809  ok(ret, "Expect BCM_GETIMAGELIST return true\n");
1810  ok(biml.himl == himl, "Expect himl to be same\n");
1811  ok(biml.uAlign == BUTTON_IMAGELIST_ALIGN_CENTER, "Expect uAlign to be %x\n",
1813 
1814  /* BCM_SETIMAGELIST null pointer handling */
1816  ok(!ret, "Expect BCM_SETIMAGELIST return false\n");
1817  ret = SendMessageA(hwnd, BCM_GETIMAGELIST, 0, (LPARAM)&biml);
1818  ok(ret, "Expect BCM_GETIMAGELIST return true\n");
1819  ok(biml.himl == himl, "Expect himl to be same\n");
1820 
1821  /* BCM_GETIMAGELIST null pointer handling */
1822  biml.himl = himl;
1823  biml.uAlign = BUTTON_IMAGELIST_ALIGN_CENTER;
1824  ret = SendMessageA(hwnd, BCM_SETIMAGELIST, 0, (LPARAM)&biml);
1825  ok(ret, "Expect BCM_SETIMAGELIST return true\n");
1827  ok(!ret, "Expect BCM_GETIMAGELIST return false\n");
1828 
1830  }
1831 
1832  pImageList_Destroy(himl);
1833 }
1834 
1835 static void test_get_set_textmargin(void)
1836 {
1837  HWND hwnd;
1838  RECT margin_in;
1839  RECT margin_out;
1840  BOOL ret;
1841  DWORD type;
1842 
1843  SetRect(&margin_in, 2, 1, 3, 4);
1845  {
1847  ok(hwnd != NULL, "Expect hwnd not null\n");
1848 
1849  /* Get text margin when it is unset */
1850  ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
1851  ok(ret, "Expect ret to be true\n");
1852  ok(IsRectEmpty(&margin_out), "Expect margin empty\n");
1853 
1854  /* Successful get and set text margin */
1855  ret = SendMessageA(hwnd, BCM_SETTEXTMARGIN, 0, (LPARAM)&margin_in);
1856  ok(ret, "Expect ret to be true\n");
1857  SetRectEmpty(&margin_out);
1858  ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
1859  ok(ret, "Expect ret to be true\n");
1860  ok(EqualRect(&margin_in, &margin_out), "Expect margins to be equal\n");
1861 
1862  /* BCM_SETTEXTMARGIN null pointer handling */
1864  ok(!ret, "Expect ret to be false\n");
1865  SetRectEmpty(&margin_out);
1866  ret = SendMessageA(hwnd, BCM_GETTEXTMARGIN, 0, (LPARAM)&margin_out);
1867  ok(ret, "Expect ret to be true\n");
1868  ok(EqualRect(&margin_in, &margin_out), "Expect margins to be equal\n");
1869 
1870  /* BCM_GETTEXTMARGIN null pointer handling */
1871  ret = SendMessageA(hwnd, BCM_SETTEXTMARGIN, 0, (LPARAM)&margin_in);
1872  ok(ret, "Expect ret to be true\n");
1874  ok(!ret, "Expect ret to be true\n");
1875 
1877  }
1878 }
1879 
1880 static void test_state(void)
1881 {
1882  HWND hwnd;
1883  DWORD type;
1884  LONG state;
1885 
1886  /* Initial button state */
1888  {
1890  state = SendMessageA(hwnd, BM_GETSTATE, 0, 0);
1891  ok(state == BST_UNCHECKED, "Expect state 0x%08x, got 0x%08x\n", BST_UNCHECKED, state);
1893  }
1894 }
1895 
1896 static void test_bcm_get_ideal_size(void)
1897 {
1898  static const char *button_text2 = "WWWW\nWWWW";
1899  static const char *button_text = "WWWW";
1900  static const WCHAR button_note_short[] = { 'W',0 };
1901  static const WCHAR button_note_long[] = { 'W','W','W','W','W','W','W','W','W','W','W','W','W','W','W','W',0 };
1902  static const WCHAR button_note_wordy[] = { 'T','h','i','s',' ','i','s',' ','a',' ','l','o','n','g',' ','n','o','t','e',' ','f','o','r',' ','t','h','e',' ','b','u','t','t','o','n',',',' ',
1903  'w','i','t','h',' ','m','a','n','y',' ','w','o','r','d','s',',',' ','w','h','i','c','h',' ','s','h','o','u','l','d',' ','b','e',' ',
1904  'o','v','e','r','a','l','l',' ','l','o','n','g','e','r',' ','t','h','a','n',' ','t','h','e',' ','t','e','x','t',' ','(','g','i','v','e','n',' ',
1905  't','h','e',' ','s','m','a','l','l','e','r',' ','f','o','n','t',')',' ','a','n','d',' ','t','h','u','s',' ','w','r','a','p','.',0 };
1906  static const DWORD imagelist_aligns[] = {BUTTON_IMAGELIST_ALIGN_LEFT, BUTTON_IMAGELIST_ALIGN_RIGHT,
1909  static const DWORD aligns[] = {0, BS_TOP, BS_LEFT, BS_RIGHT, BS_BOTTOM,
1911  DWORD default_style = WS_TABSTOP | WS_POPUP | WS_VISIBLE;
1912  const LONG client_width = 400, client_height = 200, extra_width = 123, large_height = 500;
1913  struct
1914  {
1915  DWORD style;
1916  LONG extra_width;
1917  } pushtype[] =
1918  {
1919  { BS_PUSHBUTTON, 0 },
1920  { BS_DEFPUSHBUTTON, 0 },
1921  { BS_SPLITBUTTON, extra_width * 2 + GetSystemMetrics(SM_CXEDGE) },
1922  { BS_DEFSPLITBUTTON, extra_width * 2 + GetSystemMetrics(SM_CXEDGE) }
1923  };
1924  LONG image_width = 48, height = 48, line_count, text_width;
1925  HFONT hfont, prev_font;
1926  DWORD style, type;
1927  BOOL ret;
1928  HWND hwnd;
1929  HDC hdc;
1930  LOGFONTA lf;
1931  TEXTMETRICA tm;
1932  SIZE size;
1933  HBITMAP hmask, hbmp;
1934  ICONINFO icon_info;
1935  HICON hicon;
1936  HIMAGELIST himl;
1937  BUTTON_IMAGELIST biml = {0};
1938  RECT rect;
1939  INT i, j, k;
1940 
1941  /* Check for NULL pointer handling */
1942  hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_PUSHBUTTON | default_style, 0, 0, client_width, client_height,
1943  NULL, NULL, 0, NULL);
1945  ok(!ret, "Expect BCM_GETIDEALSIZE message to return false.\n");
1946 
1947  /* Set font so that the test is consistent on Wine and Windows */
1948  ZeroMemory(&lf, sizeof(lf));
1949  lf.lfWeight = FW_NORMAL;
1950  lf.lfHeight = 20;
1951  lstrcpyA(lf.lfFaceName, "Tahoma");
1952  hfont = CreateFontIndirectA(&lf);
1953  ok(hfont != NULL, "Failed to create test font.\n");
1954 
1955  /* Get tmHeight */
1956  hdc = GetDC(hwnd);
1957  prev_font = SelectObject(hdc, hfont);
1958  GetTextMetricsA(hdc, &tm);
1959  SelectObject(hdc, prev_font);
1960  DrawTextA(hdc, button_text, -1, &rect, DT_CALCRECT);
1961  text_width = rect.right - rect.left;
1962  ReleaseDC(hwnd, hdc);
1964 
1965  /* XP and 2003 doesn't support command links, getting ideal size with button having only text returns client size on these platforms. */
1966  hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_DEFCOMMANDLINK | default_style, 0, 0, client_width, client_height, NULL,
1967  NULL, 0, NULL);
1968  ok(hwnd != NULL, "Expect hwnd not NULL\n");
1970  ZeroMemory(&size, sizeof(size));
1972  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
1973  if (size.cx == client_width && size.cy == client_height)
1974  {
1975  /* on XP and 2003, buttons with image are not supported */
1976  win_skip("Skipping further tests on XP and 2003\n");
1977  return;
1978  }
1979 
1980  /* Tests for image placements */
1981  /* Prepare bitmap */
1982  hdc = GetDC(0);
1985  himl = pImageList_Create(image_width, height, ILC_COLOR, 1, 1);
1986  pImageList_Add(himl, hbmp, 0);
1987 
1988 #define set_split_info(hwnd) do { \
1989  BUTTON_SPLITINFO _info; \
1990  int _ret; \
1991  _info.mask = BCSIF_SIZE; \
1992  _info.size.cx = extra_width; \
1993  _info.size.cy = large_height; \
1994  _ret = SendMessageA(hwnd, BCM_SETSPLITINFO, 0, (LPARAM)&_info); \
1995  ok(_ret == TRUE, "Expected BCM_SETSPLITINFO message to return true\n"); \
1996 } while (0)
1997 
1998  for (k = 0; k < ARRAY_SIZE(pushtype); k++)
1999  {
2000  /* Only bitmap for push button, ideal size should be enough for image and text */
2001  hwnd = CreateWindowA(WC_BUTTONA, button_text, pushtype[k].style | BS_BITMAP | default_style, 0, 0, client_width,
2002  client_height, NULL, NULL, 0, NULL);
2003  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2007  ZeroMemory(&size, sizeof(size));
2009  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2010  /* Ideal size contains text rect even show bitmap only */
2011  ok(size.cx >= image_width + text_width + pushtype[k].extra_width && size.cy >= max(height, tm.tmHeight),
2012  "Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx,
2013  image_width + text_width + pushtype[k].extra_width, size.cy, max(height, tm.tmHeight));
2014  ok(size.cy < large_height, "Expect ideal cy %d < %d\n", size.cy, large_height);
2016 
2017  /* Image alignments when button has bitmap and text*/
2018  for (i = 0; i < ARRAY_SIZE(aligns); i++)
2019  for (j = 0; j < ARRAY_SIZE(aligns); j++)
2020  {
2021  style = pushtype[k].style | default_style | aligns[i] | aligns[j];
2022  hwnd = CreateWindowA(WC_BUTTONA, button_text, style, 0, 0, client_width, client_height, NULL, NULL, 0, NULL);
2023  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2027  ZeroMemory(&size, sizeof(size));
2029  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2030  if (!(style & (BS_CENTER | BS_VCENTER)) || ((style & BS_CENTER) && (style & BS_CENTER) != BS_CENTER)
2031  || !(style & BS_VCENTER) || (style & BS_VCENTER) == BS_VCENTER)
2032  ok(size.cx >= image_width + text_width + pushtype[k].extra_width && size.cy >= max(height, tm.tmHeight),
2033  "Style: 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n", style, size.cx,
2034  image_width + text_width + pushtype[k].extra_width, size.cy, max(height, tm.tmHeight));
2035  else
2036  ok(size.cx >= max(text_width, height) + pushtype[k].extra_width && size.cy >= height + tm.tmHeight,
2037  "Style: 0x%08x expect ideal cx %d >= %d and ideal cy %d >= %d\n", style, size.cx,
2038  max(text_width, height) + pushtype[k].extra_width, size.cy, height + tm.tmHeight);
2039  ok(size.cy < large_height, "Expect ideal cy %d < %d\n", size.cy, large_height);
2041  }
2042 
2043  /* Image list alignments */
2044  biml.himl = himl;
2045  for (i = 0; i < ARRAY_SIZE(imagelist_aligns); i++)
2046  {
2047  biml.uAlign = imagelist_aligns[i];
2048  hwnd = CreateWindowA(WC_BUTTONA, button_text, pushtype[k].style | default_style, 0, 0, client_width,
2049  client_height, NULL, NULL, 0, NULL);
2050  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2054  ZeroMemory(&size, sizeof(size));
2056  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2057  if (biml.uAlign == BUTTON_IMAGELIST_ALIGN_TOP || biml.uAlign == BUTTON_IMAGELIST_ALIGN_BOTTOM)
2058  ok(size.cx >= max(text_width, height) + pushtype[k].extra_width && size.cy >= height + tm.tmHeight,
2059  "Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n", biml.uAlign, size.cx,
2060  max(text_width, height) + pushtype[k].extra_width, size.cy, height + tm.tmHeight);
2061  else if (biml.uAlign == BUTTON_IMAGELIST_ALIGN_LEFT || biml.uAlign == BUTTON_IMAGELIST_ALIGN_RIGHT)
2062  ok(size.cx >= image_width + text_width + pushtype[k].extra_width && size.cy >= max(height, tm.tmHeight),
2063  "Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n", biml.uAlign, size.cx,
2064  image_width + text_width + pushtype[k].extra_width, size.cy, max(height, tm.tmHeight));
2065  else
2066  ok(size.cx >= image_width + pushtype[k].extra_width && size.cy >= height,
2067  "Align:%d expect ideal cx %d >= %d and ideal cy %d >= %d\n",
2068  biml.uAlign, size.cx, image_width + pushtype[k].extra_width, size.cy, height);
2069  ok(size.cy < large_height, "Expect ideal cy %d < %d\n", size.cy, large_height);
2071  }
2072 
2073  /* Icon as image */
2074  /* Create icon from bitmap */
2075  ZeroMemory(&icon_info, sizeof(icon_info));
2076  icon_info.fIcon = TRUE;
2077  icon_info.hbmMask = hmask;
2078  icon_info.hbmColor = hbmp;
2079  hicon = CreateIconIndirect(&icon_info);
2080 
2081  /* Only icon, ideal size should be enough for image and text */
2082  hwnd = CreateWindowA(WC_BUTTONA, button_text, pushtype[k].style | BS_ICON | default_style, 0, 0, client_width,
2083  client_height, NULL, NULL, 0, NULL);
2084  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2088  ZeroMemory(&size, sizeof(size));
2090  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2091  /* Ideal size contains text rect even show icons only */
2092  ok(size.cx >= image_width + text_width + pushtype[k].extra_width && size.cy >= max(height, tm.tmHeight),
2093  "Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx,
2094  image_width + text_width + pushtype[k].extra_width, size.cy, max(height, tm.tmHeight));
2095  ok(size.cy < large_height, "Expect ideal cy %d < %d\n", size.cy, large_height);
2097 
2098  /* Show icon and text */
2099  hwnd = CreateWindowA(WC_BUTTONA, button_text, pushtype[k].style | default_style, 0, 0, client_width,
2100  client_height, NULL, NULL, 0, NULL);
2101  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2105  ZeroMemory(&size, sizeof(size));
2107  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2108  ok(size.cx >= image_width + text_width + pushtype[k].extra_width && size.cy >= max(height, tm.tmHeight),
2109  "Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx,
2110  image_width + text_width + pushtype[k].extra_width, size.cy, max(height, tm.tmHeight));
2111  ok(size.cy < large_height, "Expect ideal cy %d < %d\n", size.cy, large_height);
2113  DestroyIcon(hicon);
2114  }
2115 
2116 #undef set_split_info
2117 
2118  /* Checkbox */
2119  /* Both bitmap and text for checkbox, ideal size is only enough for text because it doesn't support image(but not image list)*/
2120  hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | default_style, 0, 0, client_width, client_height,
2121  NULL, NULL, 0, NULL);
2122  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2125  ZeroMemory(&size, sizeof(size));
2127  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2128  ok((size.cx <= image_width + text_width && size.cx >= text_width && size.cy <= max(height, tm.tmHeight)
2129  && size.cy >= tm.tmHeight),
2130  "Expect ideal cx %d within range (%d, %d ) and ideal cy %d within range (%d, %d )\n", size.cx,
2131  text_width, image_width + text_width, size.cy, tm.tmHeight, max(height, tm.tmHeight));
2133 
2134  /* Both image list and text for checkbox, ideal size should have enough for image list and text */
2136  hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | BS_BITMAP | default_style, 0, 0, client_width,
2137  client_height, NULL, NULL, 0, NULL);
2138  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2141  ZeroMemory(&size, sizeof(size));
2143  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2144  ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
2145  "Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
2146  max(height, tm.tmHeight));
2148 
2149  /* Only bitmap for checkbox, ideal size should have enough for image and text */
2150  hwnd = CreateWindowA(WC_BUTTONA, button_text, BS_AUTOCHECKBOX | BS_BITMAP | default_style, 0, 0, client_width,
2151  client_height, NULL, NULL, 0, NULL);
2152  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2155  ZeroMemory(&size, sizeof(size));
2157  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2158  ok((size.cx >= image_width + text_width && size.cy >= max(height, tm.tmHeight)),
2159  "Expect ideal cx %d >= %d and ideal cy %d >= %d\n", size.cx, image_width + text_width, size.cy,
2160  max(height, tm.tmHeight));
2162 
2163  /* Test button with only text */
2164  /* No text */
2166  {
2167  style = type | default_style;
2168  hwnd = CreateWindowA(WC_BUTTONA, "", style, 0, 0, client_width, client_height, NULL, NULL, 0, NULL);
2169  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2171 
2172  ZeroMemory(&size, sizeof(size));
2174  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2175 
2177  {
2178  ok((size.cx == 0 && size.cy > 0), "Style 0x%08x expect ideal cx %d == %d and ideal cy %d > %d\n",
2179  style, size.cx, 0, size.cy, 0);
2180  }
2181  else
2182  {
2183  ok(size.cx == client_width && size.cy == client_height,
2184  "Style 0x%08x expect size.cx == %d and size.cy == %d, got size.cx: %d size.cy: %d\n", style,
2185  client_width, client_height, size.cx, size.cy);
2186  }
2188  }
2189 
2190  /* Single line and multiple lines text */
2191  for (line_count = 1; line_count <= 2; line_count++)
2192  {
2194  {
2195  style = line_count > 1 ? type | BS_MULTILINE : type;
2196  style |= default_style;
2197 
2198  hwnd = CreateWindowA(WC_BUTTONA, (line_count == 2 ? button_text2 : button_text), style, 0, 0, client_width,
2199  client_height, NULL, NULL, 0, NULL);
2200  ok(hwnd != NULL, "Expect hwnd not NULL\n");
2202  ZeroMemory(&size, sizeof(size));
2204  ok(ret, "Expect BCM_GETIDEALSIZE message to return true\n");
2205 
2206  if (type == BS_3STATE || type == BS_AUTO3STATE || type == BS_GROUPBOX || type == BS_PUSHBOX
2207  || type == BS_OWNERDRAW)
2208  {
2209  ok(size.cx == client_width && size.cy == client_height,
2210  "Style 0x%08x expect ideal size (%d,%d), got (%d,%d)\n", style, client_width, client_height, size.cx,
2211  size.cy);
2212  }
2213  else if (type == BS_COMMANDLINK || type == BS_DEFCOMMANDLINK)
2214  {
2215  ok((size.cx == 0 && size.cy > 0),
2216  "Style 0x%08x expect ideal cx %d == %d and ideal cy %d > %d\n", style, size.cx, 0,
2217  size.cy, 0);
2218  }
2219  else
2220  {
2221  height = line_count == 2 ? 2 * tm.tmHeight : tm.tmHeight;
2222  ok(size.cx >= 0 && size.cy >= height, "Style 0x%08x expect ideal cx %d >= 0 and ideal cy %d >= %d\n",
2223  style, size.cx, size.cy, height);
2224  }
2226  }
2227  }
2228 
2229  /* Command Link with note */
2230  hwnd = CreateWindowA(WC_BUTTONA, "a", style, 0, 0, client_width, client_height, NULL, NULL, 0, NULL);
2231  ok(hwnd != NULL, "Expected hwnd not NULL\n");
2233  ret = SendMessageA(hwnd, BCM_SETNOTE, 0, (LPARAM)button_note_short);
2234  ok(ret == TRUE, "Expected BCM_SETNOTE to return true\n");
2235  size.cx = 13;
2236  size.cy = 0;
2238  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2239  ok(size.cx == 13 && size.cy > 0, "Expected ideal cx %d == %d and ideal cy %d > %d\n", size.cx, 13, size.cy, 0);
2240  height = size.cy;
2241  size.cx = 32767;
2242  size.cy = 7;
2244  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2245  ok(size.cx < 32767, "Expected ideal cx to have been adjusted\n");
2246  ok(size.cx > image_width && size.cy == height, "Expected ideal cx %d > %d and ideal cy %d == %d\n", size.cx, image_width, size.cy, height);
2247 
2248  /* Try longer note without word breaks, shouldn't extend height because no word splitting */
2249  ret = SendMessageA(hwnd, BCM_SETNOTE, 0, (LPARAM)button_note_long);
2250  ok(ret == TRUE, "Expected BCM_SETNOTE to return true\n");
2251  k = size.cx;
2252  size.cy = 0;
2254  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2255  ok(size.cx == k && size.cy == height, "Expected ideal cx %d == %d and ideal cy %d == %d\n", size.cx, k, size.cy, height);
2256 
2257  /* Now let it extend the width */
2258  size.cx = 32767;
2259  size.cy = 0;
2261  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2262  ok(size.cx > k && size.cy == height, "Expected ideal cx %d > %d and ideal cy %d == %d\n", size.cx, k, size.cy, height);
2263 
2264  /* Use a very long note with words and the same width, should extend the height due to word wrap */
2265  ret = SendMessageA(hwnd, BCM_SETNOTE, 0, (LPARAM)button_note_wordy);
2266  ok(ret == TRUE, "Expected BCM_SETNOTE to return true\n");
2267  k = size.cx;
2269  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2270  ok(size.cx <= k && size.cy > height, "Expected ideal cx %d <= %d and ideal cy %d > %d\n", size.cx, k, size.cy, height);
2271 
2272  /* Now try the wordy note with a width smaller than the image itself, which prevents wrapping */
2273  size.cx = 13;
2275  ok(ret == TRUE, "Expected BCM_GETIDEALSIZE message to return true\n");
2276  ok(size.cx == 13 && size.cy == height, "Expected ideal cx %d == %d and ideal cy %d == %d\n", size.cx, 13, size.cy, height);
2278 
2279 
2280  pImageList_Destroy(himl);
2281  DeleteObject(hbmp);
2282  DeleteObject(hmask);
2283  ReleaseDC(0, hdc);
2285 }
2286 
2288 {
2289  ULONG_PTR ctx_cookie;
2290  HANDLE hCtx;
2291 
2292  if (!load_v6_module(&ctx_cookie, &hCtx))
2293  return;
2294 
2296 
2297  init_functions();
2299 
2302  test_note();
2303  test_button_data();
2307  test_state();
2309 
2310  unload_v6_module(ctx_cookie, hCtx);
2311 }
HGDIOBJ WINAPI GetStockObject(_In_ int)
#define BS_NOTIFY
Definition: winuser.h:268
#define BCM_SETDROPDOWNSTATE
Definition: commctrl.h:4652
#define WM_SYNCPAINT
Definition: winuser.h:1672
HIMAGELIST himl
Definition: commctrl.h:4630
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define WM_GETTEXTLENGTH
Definition: winuser.h:1601
#define BS_3STATE
Definition: pedump.c:656
#define BS_LEFT
Definition: winuser.h:265
static const struct message setstate_user_seq[]
Definition: button.c:484
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static const struct message setstate_static_seq[]
Definition: button.c:474
#define BM_SETSTATE
Definition: winuser.h:1905
#define WM_IME_NOTIFY
Definition: winuser.h:1812
GLint GLint GLsizei width
Definition: gl.h:1546
static const struct message setstate_seq[]
Definition: button.c:465
return
Definition: dirsup.c:529
#define max(a, b)
Definition: svc.c:63
#define BS_OWNERDRAW
Definition: pedump.c:661
#define set_test_cd_state(s)
Definition: button.c:173
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
static HICON
Definition: imagelist.c:84
#define BCSS_IMAGE
Definition: commctrl.h:251
#define TRUE
Definition: types.h:120
#define DLGC_UNDEFPUSHBUTTON
Definition: winuser.h:2591
#define MAKEWPARAM(l, h)
Definition: winuser.h:3984
static const struct message pre_post_pre_post_cd_seq[]
Definition: button.c:595
BOOL WINAPI GetClassInfoExW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _Out_ LPWNDCLASSEXW)
static const struct message pre_cd_seq[]
Definition: button.c:566
#define IMAGE_ICON
Definition: winuser.h:212
static void test_button_data(void)
Definition: button.c:1694
static void test_bcm_splitinfo(HWND hwnd)
Definition: button.c:1486
static const struct message lbuttonup_seq[]
Definition: button.c:400
#define BS_DEFCOMMANDLINK
Definition: commctrl.h:4669
int WINAPI GetClassNameA(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPSTR lpClassName, _In_ int nMaxCount)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int cbWndExtra
Definition: winuser.h:3195
#define WM_GETDLGCODE
Definition: winuser.h:1671
#define WM_LBUTTONDOWN
Definition: winuser.h:1758
WNDPROC lpfnWndProc
Definition: winuser.h:3178
#define error(str)
Definition: mkdosfs.c:1605
INT WINAPI ImageList_Add(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:448
#define LOBYTE(W)
Definition: jmemdos.c:487
#define CDDS_POSTERASE
Definition: commctrl.h:279
#define BCM_SETTEXTMARGIN
Definition: commctrl.h:4644
static LRESULT(WINAPI *pDefSubclassProc)(HWND
#define BS_DEFSPLITBUTTON
Definition: commctrl.h:4667
Definition: http.c:7098
#define CDRF_NOTIFYPOSTPAINT
Definition: commctrl.h:270
HDC WINAPI GetDC(_In_opt_ HWND)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define BS_RIGHT
Definition: winuser.h:274
#define BS_RADIOBUTTON
Definition: pedump.c:655
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2022
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
UINT state
Definition: button.c:168
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
char * wine_dbgstr_w(const wchar_t *wstr)
Definition: atltest.h:87
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static struct cd_image cd
Definition: cdmake.c:182
#define BM_GETSTATE
Definition: winuser.h:1902
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
#define WM_GETTEXT
Definition: winuser.h:1600
static const struct message setstyle_static_seq[]
Definition: button.c:428
Definition: msg.h:39
#define IS_WNDPROC_HANDLE(x)
Definition: button.c:38
#define BCM_GETTEXTMARGIN
Definition: commctrl.h:4646
#define WM_CAPTURECHANGED
Definition: winuser.h:1790
DWORD button
Definition: button.c:166
static void test_get_set_textmargin(void)
Definition: button.c:1835
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
static HDC
Definition: imagelist.c:92
#define DLGC_RADIOBUTTON
Definition: winuser.h:2592
#define CALLBACK
Definition: compat.h:27
#define BS_DEFPUSHBUTTON
Definition: pedump.c:652
BOOL WINAPI UpdateWindow(_In_ HWND)
BOOL todo
Definition: filedlg.c:313
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
HANDLE HWND
Definition: compat.h:13
#define check_cd_seq(type, context)
#define CDDS_POSTPAINT
Definition: commctrl.h:277
#define set_split_info(hwnd)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1497
int cbClsExtra
Definition: winuser.h:3140
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
static void disable_test_cd(void)
Definition: button.c:185
#define BUTTON_IMAGELIST_ALIGN_TOP
Definition: commctrl.h:4625
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
LPCSTR lpszMenuName
Definition: winuser.h:3146
#define SM_CXEDGE
Definition: winuser.h:998
static struct @1601 test_cd
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:63
#define WHITE_BRUSH
Definition: wingdi.h:901
static const struct message setfocus_ownerdraw_seq[]
Definition: button.c:364
HWND WINAPI SetFocus(_In_opt_ HWND)
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
UINT_PTR WPARAM
Definition: windef.h:207
#define VK_DOWN
Definition: winuser.h:2202
HBRUSH hbrBackground
Definition: winuser.h:3145
#define WS_CHILD
Definition: pedump.c:617
__u16 time
Definition: mkdosfs.c:366
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
static LRESULT WINAPI test_parent_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: button.c:190
static HWND create_button(DWORD style, HWND parent)
Definition: button.c:618
#define CDRF_SKIPDEFAULT
Definition: commctrl.h:266
#define BS_CENTER
Definition: winuser.h:260
#define NO_ERROR
Definition: dderror.h:5
#define lstrlenW
Definition: compat.h:415
#define BM_GETIMAGE
Definition: winuser.h:1901
#define WS_EX_RIGHT
Definition: winuser.h:400
HIMAGELIST himl
BOOL WINAPI DestroyWindow(_In_ HWND)
#define BM_SETIMAGE
Definition: winuser.h:1904
int32_t INT
Definition: typedefs.h:56
static const struct message setstyle_seq[]
Definition: button.c:415
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2014
#define BS_GROUPBOX
Definition: pedump.c:658
#define BN_UNHILITE
Definition: winuser.h:1916
& rect
Definition: startmenu.cpp:1413
WPARAM wParam
Definition: combotst.c:138
DWORD WINAPI GetVersion(VOID)
Definition: version.c:22
#define WM_ENABLE
Definition: winuser.h:1597
#define WM_PRINTCLIENT
Definition: richedit.h:70
static DWORD_PTR
Definition: button.c:40
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
struct _test_info info[]
Definition: SetCursorPos.c:19
uint32_t ULONG_PTR
Definition: typedefs.h:63
UINT code
Definition: winuser.h:3134
#define WM_NCPAINT
Definition: winuser.h:1669
#define NUM_MSG_SEQUENCES
Definition: button.c:52
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtGuid, ULONG ulId, LPCWSTR lpSearchStr, PACTCTX_SECTION_KEYED_DATA pInfo)
Definition: actctx.c:156
#define BCSIF_SIZE
Definition: commctrl.h:248
UINT line
Definition: button.c:167
int cbWndExtra
Definition: winuser.h:3141
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 const struct message setstate_ownerdraw_seq[]
Definition: button.c:493
static void test_bm_get_set_image(void)
Definition: button.c:1236
#define BCM_SETNOTE
Definition: commctrl.h:4655
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define SM_CYMENUCHECK
Definition: winuser.h:1022
static BOOL(WINAPI *pSetWindowSubclass)(HWND
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define DT_CALCRECT
Definition: winuser.h:526
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:71
#define WM_PARENTNOTIFY
Definition: winuser.h:1785
unsigned int BOOL
Definition: ntddk_ex.h:94
#define BCN_DROPDOWN
Definition: commctrl.h:257
long LONG
Definition: pedump.c:60
#define COMBINED_SEQ_INDEX
Definition: button.c:50
#define set_test_cd_ret(r)
Definition: button.c:179
LONG lfHeight
Definition: dimm.idl:42
static const WCHAR desc[]
Definition: protectdata.c:36
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
UINT_PTR idFrom
Definition: winuser.h:3133
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
#define BUTTON_IMAGELIST_ALIGN_CENTER
Definition: commctrl.h:4627
HBITMAP hbmMask
Definition: winuser.h:3101
HWND WINAPI GetCapture(void)
Definition: message.c:2879
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define ILC_COLOR
Definition: commctrl.h:348
static const struct message setstyle_ownerdraw_seq[]
Definition: button.c:452
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4290
int image_width
HCURSOR hCursor
Definition: winuser.h:3144
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
Definition: msg.h:45
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
static const struct message bcn_dropdown_seq[]
Definition: button.c:604
static const struct message setstyle_user_seq[]
Definition: button.c:440
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define BCM_GETSPLITINFO
Definition: commctrl.h:4654
static int
Definition: button.c:43
LONG lfWeight
Definition: dimm.idl:46
UINT WINAPI RealGetWindowClassA(_In_ HWND hwnd, _Out_writes_to_(cchClassNameMax, return) LPSTR ptszClassName, _In_ UINT cchClassNameMax)
smooth NULL
Definition: ftsmooth.c:416
#define WM_GETFONT
Definition: winuser.h:1633
#define WC_BUTTONA
Definition: commctrl.h:4618
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
static const struct message setcheck_static_seq[]
Definition: button.c:534
static const struct message clearstate_seq[]
Definition: button.c:504
#define CDIS_SELECTED
Definition: commctrl.h:287
#define BS_CHECKBOX
Definition: pedump.c:653
#define BS_AUTO3STATE
Definition: pedump.c:657
#define SYSTEM_FONT
Definition: wingdi.h:910
#define WM_KEYDOWN
Definition: winuser.h:1697
LONG_PTR LPARAM
Definition: windef.h:208
static void test_state(void)
Definition: button.c:1880
HBITMAP hbmColor
Definition: winuser.h:3102
static const struct message setcheck_ignored_seq[]
Definition: button.c:526
int cbClsExtra
Definition: winuser.h:3194
#define BM_GETCHECK
Definition: winuser.h:1900
#define BCM_GETNOTE
Definition: commctrl.h:4656
static BOOL ignore_message(UINT message)
Definition: button.c:115
LRESULT WINAPI DefSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: commctrl.c:1496
GLuint index
Definition: glext.h:6031
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
const char * LPCSTR
Definition: xmlstorage.h:183
#define SW_SHOW
Definition: winuser.h:769
static const struct message setfocus_seq[]
Definition: button.c:304
static HFONT hfont
Definition: msg.h:41
static LRESULT CALLBACK button_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR id, DWORD_PTR ref_data)
Definition: button.c:129
#define BN_HILITE
Definition: winuser.h:1911
GLuint GLfloat * val
Definition: glext.h:7180
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 GLint GLint j
Definition: glfuncs.h:250
static void test_get_set_imagelist(void)
Definition: button.c:1755
static const WCHAR nameW[]
Definition: main.c:46
static const struct message lbuttondown_seq[]
Definition: button.c:389
#define GetWindowLongPtrA
Definition: winuser.h:4803
HBITMAP hbmp
BOOL WINAPI SetWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIDSubclass, DWORD_PTR dwRef)
Definition: commctrl.c:1261
static const struct message killfocus_static_seq[]
Definition: button.c:353
BOOL fIcon
Definition: winuser.h:3098
#define DLGC_DEFPUSHBUTTON
Definition: winuser.h:2590
#define BM_SETCHECK
Definition: winuser.h:1903
#define WM_ENTERIDLE
Definition: winuser.h:1731
#define BS_COMMANDLINK
Definition: commctrl.h:4668
#define WM_KILLFOCUS
Definition: winuser.h:1596
GLsizeiptr size
Definition: glext.h:5919
r parent
Definition: btrfs.c:2869
#define BS_MULTILINE
Definition: winuser.h:267
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define BM_SETSTYLE
Definition: winuser.h:1906
GLint GLvoid * img
Definition: gl.h:1956
#define BST_PUSHED
Definition: winuser.h:201
#define WM_IME_SETCONTEXT
Definition: winuser.h:1811
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2546
#define WM_NCDESTROY
Definition: winuser.h:1666
#define WINAPI
Definition: msvc.h:6
#define ok_sequence(seq, index, exp, contx, todo)
Definition: msg.h:387
#define BS_TOP
Definition: winuser.h:277
#define BCSIF_GLYPH
Definition: commctrl.h:245
#define WM_KEYUP
Definition: winuser.h:1698
const char * wine_dbgstr_rect(const RECT *rect)
int WINAPI GetSystemMetrics(_In_ int)
#define BN_CLICKED
Definition: winuser.h:1907
unsigned long DWORD
Definition: ntddk_ex.h:95
int cbWndExtra
Definition: winuser.h:3180
#define CDIS_FOCUS
Definition: commctrl.h:291
#define SetLastError(x)
Definition: compat.h:417
#define PARENT_CD_SEQ_INDEX
Definition: button.c:51
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define CDRF_DODEFAULT
Definition: commctrl.h:264
#define OBJ_FONT
Definition: objidl.idl:1414
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
#define BCM_GETNOTELENGTH
Definition: commctrl.h:4657
#define WAIT_TIMEOUT
Definition: dderror.h:14
static LPARAM
Definition: button.c:42
#define BN_KILLFOCUS
Definition: winuser.h:1912
#define WM_PAINT
Definition: winuser.h:1602
#define MAKEFUNC_ORD(f, ord)
static HIMAGELIST(WINAPI *pImageList_Create)(int
#define BS_SPLITBUTTON
Definition: commctrl.h:4666
#define X(f)
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
static void test_note(void)
Definition: button.c:1080
static const struct message setcheck_radio_seq[]
Definition: button.c:544
#define NM_CUSTOMDRAW
Definition: commctrl.h:137
#define CDDS_PREPAINT
Definition: commctrl.h:276
#define BUTTON_IMAGELIST_ALIGN_LEFT
Definition: commctrl.h:4623
#define BS_ICON
Definition: winuser.h:264
#define index(s, c)
Definition: various.h:29
Definition: msg.h:34
#define BCM_GETIMAGELIST
Definition: commctrl.h:4641
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR 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)
HDC hdc
Definition: main.c:9
static const struct message setfont_seq[]
Definition: button.c:409
#define BS_BITMAP
Definition: winuser.h:258
#define BCSIF_STYLE
Definition: commctrl.h:247
static const struct message pre_pre_post_cd_seq[]
Definition: button.c:587
static void flush_events(void)
Definition: button.c:100
#define WM_CANCELMODE
Definition: winuser.h:1617
static SUBCLASSPROC
Definition: button.c:40
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:821
unsigned char BYTE
Definition: mem.h:68
#define WM_APP
Definition: eventvwr.h:70
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define WS_TABSTOP
Definition: pedump.c:634
Definition: time.h:76
#define WM_COMMAND
Definition: winuser.h:1722
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
LPCSTR lpszClassName
Definition: winuser.h:3147
HWND hwndFrom
Definition: winuser.h:3132
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define BS_VCENTER
Definition: winuser.h:279
#define BST_UNCHECKED
Definition: winuser.h:199
static UINT_PTR
Definition: button.c:40
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2059
DWORD ret
Definition: button.c:169
static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: button.c:54
#define BS_PUSHBUTTON
Definition: pedump.c:651
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
WNDPROC lpfnWndProc
Definition: winuser.h:3193
#define broken(x)
Definition: _sntprintf.h:21
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:141
static const struct message setfocus_static_seq[]
Definition: button.c:327
UINT style
Definition: winuser.h:3138
#define GWL_STYLE
Definition: winuser.h:846
#define BUTTON_IMAGELIST_ALIGN_BOTTOM
Definition: commctrl.h:4626
#define ID_BUTTON
Definition: button.c:48
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define BN_SETFOCUS
Definition: winuser.h:1915
BOOL WINAPI GetClassInfoExA(_In_opt_ HINSTANCE, _In_ LPCSTR, _Out_ LPWNDCLASSEXA)
INT WINAPI DrawTextA(HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags)
Definition: font.c:373
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
int cbClsExtra
Definition: winuser.h:3179
#define BS_AUTORADIOBUTTON
Definition: pedump.c:660
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
static void init_functions(void)
Definition: button.c:81
static WCHAR test_w[]
Definition: pager.c:33
#define CDDS_ITEM
Definition: commctrl.h:280
BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
Definition: commctrl.c:1390
#define lstrcpyW
Definition: compat.h:414
BOOL WINAPI DeleteDC(_In_ HDC)
HINSTANCE hInstance
Definition: winuser.h:3142
#define add_message(msg)
Definition: msg.c:2113
#define ARRAY_SIZE(a)
Definition: main.h:24
unsigned char dummy
Definition: maze.c:118
#define BS_TYPEMASK
Definition: winuser.h:270
#define WC_BUTTONW
Definition: commctrl.h:4619
static void register_parent_class(void)
Definition: button.c:1469
#define DLGC_BUTTON
Definition: winuser.h:2595
#define QS_ALLINPUT
Definition: winuser.h:874
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define ok(value,...)
Definition: atltest.h:57
#define WM_LBUTTONUP
Definition: winuser.h:1759
Definition: bl.h:1331
static const struct message killfocus_seq[]
Definition: button.c:316
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
static const struct message setcheck_radio_redraw_seq[]
Definition: button.c:553
#define WS_POPUP
Definition: pedump.c:616
unsigned int UINT
Definition: ndis.h:50
#define VK_SPACE
Definition: winuser.h:2194
#define BCSIF_IMAGE
Definition: commctrl.h:246
BOOL empty
Definition: button.c:170
#define BS_BOTTOM
Definition: winuser.h:259
#define IMAGE_BITMAP
Definition: winuser.h:211
#define CDRF_NOTIFYPOSTERASE
Definition: commctrl.h:273
#define BST_CHECKED
Definition: winuser.h:197
#define WM_SETFONT
Definition: winuser.h:1632
#define WM_DEVICECHANGE
Definition: winuser.h:1793
#define FW_NORMAL
Definition: wingdi.h:372
WNDPROC lpfnWndProc
Definition: winuser.h:3139
#define BUTTON_IMAGELIST_ALIGN_RIGHT
Definition: commctrl.h:4624
#define WM_DRAWITEM
Definition: winuser.h:1627
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
START_TEST(button)
Definition: button.c:925
static void test_bcm_get_ideal_size(void)
Definition: button.c:1896
HWND WINAPI GetFocus(void)
Definition: window.c:1905
#define msg(x)
Definition: auth_time.c:54
#define IDC_ARROW
Definition: winuser.h:682
#define BCM_SETSPLITINFO
Definition: commctrl.h:4653
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2888
#define ERROR_NOT_SUPPORTED
Definition: compat.h:90
Definition: name.c:38
#define BCSS_STRETCH
Definition: commctrl.h:250
static const struct message setfocus_groupbox_seq[]
Definition: button.c:340
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 WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
unsigned int ULONG
Definition: retypes.h:1
GLenum GLuint id
Definition: glext.h:5579
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
Definition: msg.h:40
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define CDIS_SHOWKEYBOARDCUES
Definition: commctrl.h:296
#define BCM_GETIDEALSIZE
Definition: commctrl.h:4635
static HBITMAP
Definition: button.c:44
static void test_button_messages(void)
Definition: button.c:634
#define BS_USERBUTTON
Definition: pedump.c:659
#define PM_REMOVE
Definition: winuser.h:1182
#define WM_ERASEBKGND
Definition: winuser.h:1607
#define WM_SETFOCUS
Definition: winuser.h:1595
LONG_PTR LRESULT
Definition: windef.h:209
static WCHAR * get_versioned_classname(const WCHAR *name)
Definition: button.c:67
Arabic default style
Definition: afstyles.h:93
#define WS_VISIBLE
Definition: pedump.c:620
#define BCM_SETIMAGELIST
Definition: commctrl.h:4638
#define memset(x, y, z)
Definition: compat.h:39
static const struct message empty_cd_seq[]
Definition: button.c:564
static WPARAM
Definition: button.c:42
static const struct message pre_post_pre_cd_seq[]
Definition: button.c:579
#define BS_RIGHTBUTTON
Definition: winuser.h:275
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define win_skip
Definition: test.h:150
static const struct message killfocus_ownerdraw_seq[]
Definition: button.c:377
LPARAM lParam
Definition: combotst.c:139
int k
Definition: mpi.c:3369
#define LOWORD(l)
Definition: pedump.c:82
static void test_button_class(void)
Definition: button.c:1023
#define WM_DWMNCRENDERINGCHANGED
Definition: winuser.h:1867
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define DLGC_WANTARROWS
Definition: winuser.h:2585
#define DLGC_STATIC
Definition: winuser.h:2594
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:439
static const struct message pre_pre_cd_seq[]
Definition: button.c:572
#define WM_NOTIFY
Definition: richedit.h:61
static const WCHAR testW[]
Definition: jsregexp.c:44
static UINT WPARAM wparam
Definition: combo.c:716
#define CDDS_PREERASE
Definition: commctrl.h:278
#define ok_(x1, x2)
Definition: atltest.h:61
HICON hIcon
Definition: winuser.h:3143
#define CDRF_DOERASE
Definition: commctrl.h:267
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
static const struct message clearstate_ownerdraw_seq[]
Definition: button.c:515
#define WM_TIMECHANGE
Definition: winuser.h:1616
static UINT
Definition: button.c:42