ReactOS 0.4.16-dev-197-g92996da
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
40static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
41static BOOL (WINAPI *pRemoveWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR);
42static LRESULT (WINAPI *pDefSubclassProc)(HWND, UINT, WPARAM, LPARAM);
43static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
44static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
45static 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
81static 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 */
100static 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 ||
122 message == WM_DISPLAYCHANGE ||
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
164static struct
165{
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
185static 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:
249 ret &= ~CDRF_NOTIFYPOSTPAINT;
250 cd->dwItemSpec = 0xdeadbeef;
251 break;
252 case CDDS_PREPAINT:
253 ret &= ~CDRF_NOTIFYPOSTERASE;
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
304static const struct message setfocus_seq[] =
305{
308 { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
312 { WM_PAINT, sent },
313 { 0 }
314};
315
316static 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
327static const struct message setfocus_static_seq[] =
328{
331 { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
332 { WM_SETFOCUS, sent|wparam, 0 },
335 { WM_APP, sent|wparam|lparam, 0, 0 },
336 { WM_PAINT, sent },
337 { 0 }
338};
339
340static const struct message setfocus_groupbox_seq[] =
341{
344 { BM_GETSTATE, sent|optional }, /* when touchscreen is present */
345 { WM_SETFOCUS, sent|wparam, 0 },
348 { WM_APP, sent|wparam|lparam, 0, 0 },
349 { WM_PAINT, sent },
350 { 0 }
351};
352
353static 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
364static 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
377static 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
389static 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
400static const struct message lbuttonup_seq[] =
401{
402 { WM_LBUTTONUP, sent|wparam|lparam, 0, 0 },
406 { 0 }
407};
408
409static const struct message setfont_seq[] =
410{
411 { WM_SETFONT, sent },
412 { 0 }
413};
414
415static 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 */
425 { 0 }
426};
427
428static 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
440static 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
452static 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
465static const struct message setstate_seq[] =
466{
467 { BM_SETSTATE, sent },
468 { WM_APP, sent|wparam|lparam, 0, 0 },
469 { WM_PAINT, sent },
471 { 0 }
472};
473
474static 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
484static 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
493static 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
504static 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
515static 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
526static const struct message setcheck_ignored_seq[] =
527{
528 { BM_SETCHECK, sent },
529 { WM_APP, sent|wparam|lparam, 0, 0 },
531 { 0 }
532};
533
534static 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
544static 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
553static 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
564static const struct message empty_cd_seq[] = { { 0 } };
565
566static const struct message pre_cd_seq[] =
567{
569 { 0 }
570};
571
572static const struct message pre_pre_cd_seq[] =
573{
576 { 0 }
577};
578
579static const struct message pre_post_pre_cd_seq[] =
580{
584 { 0 }
585};
586
587static const struct message pre_pre_post_cd_seq[] =
588{
592 { 0 }
593};
594
595static const struct message pre_post_pre_post_cd_seq[] =
596{
601 { 0 }
602};
603
604static 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
634static 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;
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");
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;
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
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 ||
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
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 {
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
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
1012 ok_sequence(sequences, COMBINED_SEQ_INDEX, lbuttonup_seq, "WM_LBUTTONUP on a button", TRUE);
1013
1015 zfont = GetStockObject(SYSTEM_FONT);
1018 ok_sequence(sequences, COMBINED_SEQ_INDEX, setfont_seq, "WM_SETFONT on a button", FALSE);
1019
1021}
1022
1023static 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
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
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
1080static 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
1236static 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");
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");
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");
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
1461done:
1462 DestroyIcon(hicon2x2);
1463 DeleteObject(hmask2x2);
1464 DeleteObject(hbmp2x2);
1465 DeleteObject(hbmp1x1);
1466 ReleaseDC(0, hdc);
1467}
1468
1469static 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;
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;
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
1694static void test_button_data(void)
1695{
1696 static const DWORD styles[] =
1697 {
1703 BS_3STATE,
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
1755static void test_get_set_imagelist(void)
1756{
1757 HWND hwnd;
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");
1777 ReleaseDC(0, hdc);
1778
1780 {
1782 ok(hwnd != NULL, "Expect hwnd not null\n");
1783
1784 /* Get imagelist when imagelist is unset yet */
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;
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;
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;
1807 ok(ret, "Expect BCM_SETIMAGELIST return true\n");
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");
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;
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
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
1880static void test_state(void)
1881{
1882 HWND hwnd;
1883 DWORD type;
1884 LONG state;
1885
1886 /* Initial button state */
1888 {
1891 ok(state == BST_UNCHECKED, "Expect state 0x%08x, got 0x%08x\n", BST_UNCHECKED, state);
1893 }
1894}
1895
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;
1932 SIZE size;
1933 HBITMAP hmask, hbmp;
1934 ICONINFO icon_info;
1935 HICON hicon;
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");
1953 ok(hfont != NULL, "Failed to create test font.\n");
1954
1955 /* Get tmHeight */
1956 hdc = GetDC(hwnd);
1957 prev_font = SelectObject(hdc, hfont);
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);
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
2299
2302 test_note();
2307 test_state();
2309
2310 unload_v6_module(ctx_cookie, hCtx);
2311}
static HFONT hfont
InitDirComponents & cd
@ sent
Definition: SystemMenu.c:27
@ beginpaint
Definition: SystemMenu.c:33
@ defwinproc
Definition: SystemMenu.c:32
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
@ optional
Definition: SystemMenu.c:34
#define add_message(msg)
Definition: SystemMenu.c:98
#define ok_sequence(exp, contx, todo)
Definition: SystemMenu.c:275
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
#define ok(value,...)
Definition: atltest.h:57
#define broken(x)
Definition: atltest.h:178
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
static const WCHAR nameW[]
Definition: main.c:49
#define index(s, c)
Definition: various.h:29
#define ARRAY_SIZE(A)
Definition: main.h:20
HBITMAP hbmp
HIMAGELIST himl
return
Definition: dirsup.c:529
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
@ custdraw
Definition: msg.h:47
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:393
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:99
BOOL WINAPI SetWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uIDSubclass, DWORD_PTR dwRef)
Definition: commctrl.c:1268
BOOL WINAPI RemoveWindowSubclass(HWND hWnd, SUBCLASSPROC pfnSubclass, UINT_PTR uID)
Definition: commctrl.c:1397
LRESULT WINAPI DefSubclassProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: commctrl.c:1503
#define NO_ERROR
Definition: dderror.h:5
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
INT WINAPI ImageList_Add(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:448
BOOL WINAPI ImageList_Destroy(HIMAGELIST himl)
Definition: imagelist.c:928
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
HANDLE HWND
Definition: compat.h:19
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
HMODULE WINAPI DECLSPEC_HOTPATCH GetModuleHandleA(LPCSTR lpModuleName)
Definition: loader.c:812
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtGuid, ULONG ulId, LPCWSTR lpSearchStr, PACTCTX_SECTION_KEYED_DATA pInfo)
Definition: actctx.c:238
int WINAPI lstrcmpW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4243
r parent
Definition: btrfs.c:3010
#define WM_APP
Definition: eventvwr.h:73
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLint GLvoid * img
Definition: gl.h:1956
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
GLuint id
Definition: glext.h:5910
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
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
#define LOBYTE(W)
Definition: jmemdos.c:487
static const WCHAR testW[]
Definition: jsregexp.c:44
#define wine_dbgstr_w
Definition: kernel32.h:34
int image_width
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
__u16 time
Definition: mkdosfs.c:8
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
HDC hdc
Definition: main.c:9
static PEXPLICIT_ACCESSW *static HMODULE hmod
Definition: security.c:143
static const struct message clearstate_seq[]
Definition: button.c:504
static void test_get_set_imagelist(void)
Definition: button.c:1755
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
static const struct message setstate_static_seq[]
Definition: button.c:474
static LRESULT WINAPI test_parent_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
Definition: button.c:190
static const struct message setfocus_ownerdraw_seq[]
Definition: button.c:364
#define ID_BUTTON
Definition: button.c:48
static const struct message pre_pre_cd_seq[]
Definition: button.c:572
static void test_button_messages(void)
Definition: button.c:634
static const struct message setcheck_static_seq[]
Definition: button.c:534
#define NUM_MSG_SEQUENCES
Definition: button.c:52
#define set_split_info(hwnd)
static void test_bm_get_set_image(void)
Definition: button.c:1236
#define IS_WNDPROC_HANDLE(x)
Definition: button.c:38
static const struct message pre_pre_post_cd_seq[]
Definition: button.c:587
#define X(f)
#define set_test_cd_ret(r)
Definition: button.c:179
static const struct message lbuttonup_seq[]
Definition: button.c:400
static BOOL ignore_message(UINT message)
Definition: button.c:115
static const struct message setfocus_groupbox_seq[]
Definition: button.c:340
static const struct message clearstate_ownerdraw_seq[]
Definition: button.c:515
static void disable_test_cd(void)
Definition: button.c:185
static const struct message setcheck_radio_seq[]
Definition: button.c:544
static void test_bcm_splitinfo(HWND hwnd)
Definition: button.c:1486
static SUBCLASSPROC
Definition: button.c:40
static const struct message setfocus_seq[]
Definition: button.c:304
static HWND create_button(DWORD style, HWND parent)
Definition: button.c:618
static int
Definition: button.c:43
static const struct message pre_post_pre_cd_seq[]
Definition: button.c:579
static DWORD_PTR
Definition: button.c:40
BOOL empty
Definition: button.c:170
static const struct message setfocus_static_seq[]
Definition: button.c:327
static void test_note(void)
Definition: button.c:1080
static const struct message setstyle_user_seq[]
Definition: button.c:440
static WPARAM
Definition: button.c:42
static const struct message lbuttondown_seq[]
Definition: button.c:389
static void test_state(void)
Definition: button.c:1880
static const struct message setcheck_ignored_seq[]
Definition: button.c:526
#define MAKEFUNC_ORD(f, ord)
static HBITMAP
Definition: button.c:44
static const struct message pre_cd_seq[]
Definition: button.c:566
static void test_bcm_get_ideal_size(void)
Definition: button.c:1896
static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: button.c:54
static const struct message setstyle_seq[]
Definition: button.c:415
static void flush_events(void)
Definition: button.c:100
static WCHAR * get_versioned_classname(const WCHAR *name)
Definition: button.c:67
static const struct message killfocus_ownerdraw_seq[]
Definition: button.c:377
#define check_cd_seq(type, context)
static struct @1646 test_cd
UINT line
Definition: button.c:167
#define COMBINED_SEQ_INDEX
Definition: button.c:50
static const struct message killfocus_static_seq[]
Definition: button.c:353
static void test_button_data(void)
Definition: button.c:1694
static const struct message setstate_seq[]
Definition: button.c:465
static const struct message pre_post_pre_post_cd_seq[]
Definition: button.c:595
static const struct message setstyle_static_seq[]
Definition: button.c:428
static void test_button_class(void)
Definition: button.c:1023
static UINT_PTR
Definition: button.c:40
static const struct message setstate_user_seq[]
Definition: button.c:484
static void test_get_set_textmargin(void)
Definition: button.c:1835
static const struct message killfocus_seq[]
Definition: button.c:316
#define PARENT_CD_SEQ_INDEX
Definition: button.c:51
static const struct message setfont_seq[]
Definition: button.c:409
static const struct message setstate_ownerdraw_seq[]
Definition: button.c:493
static void register_parent_class(void)
Definition: button.c:1469
static const struct message setstyle_ownerdraw_seq[]
Definition: button.c:452
static const struct message setcheck_radio_redraw_seq[]
Definition: button.c:553
static void init_functions(void)
Definition: button.c:81
#define set_test_cd_state(s)
Definition: button.c:173
DWORD button
Definition: button.c:166
static const struct message bcn_dropdown_seq[]
Definition: button.c:604
static const struct message empty_cd_seq[]
Definition: button.c:564
static UINT
Definition: button.c:42
static HDC
Definition: imagelist.c:88
static HICON
Definition: imagelist.c:80
static const WCHAR test_w[]
Definition: pager.c:34
BOOL todo
Definition: filedlg.c:313
static const WCHAR desc[]
Definition: protectdata.c:36
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
int k
Definition: mpi.c:3369
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define BOOL
Definition: nt_native.h:43
#define OBJ_FONT
Definition: objidl.idl:1414
#define LRESULT
Definition: ole.h:14
#define LOWORD(l)
Definition: pedump.c:82
#define BS_AUTORADIOBUTTON
Definition: pedump.c:660
#define WS_CHILD
Definition: pedump.c:617
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define BS_USERBUTTON
Definition: pedump.c:659
#define WS_TABSTOP
Definition: pedump.c:634
#define WS_POPUP
Definition: pedump.c:616
#define WS_VISIBLE
Definition: pedump.c:620
#define BS_AUTOCHECKBOX
Definition: pedump.c:654
long LONG
Definition: pedump.c:60
#define BS_GROUPBOX
Definition: pedump.c:658
#define BS_OWNERDRAW
Definition: pedump.c:661
#define BS_3STATE
Definition: pedump.c:656
#define BS_CHECKBOX
Definition: pedump.c:653
#define BS_AUTO3STATE
Definition: pedump.c:657
#define BS_RADIOBUTTON
Definition: pedump.c:655
#define BS_PUSHBUTTON
Definition: pedump.c:651
#define BS_DEFPUSHBUTTON
Definition: pedump.c:652
#define WC_BUTTONW
Definition: commctrl.h:4628
#define CDDS_ITEM
Definition: commctrl.h:284
#define CDRF_NOTIFYPOSTERASE
Definition: commctrl.h:277
#define BCN_DROPDOWN
Definition: commctrl.h:261
#define BCM_SETNOTE
Definition: commctrl.h:4664
#define BS_SPLITBUTTON
Definition: commctrl.h:4675
#define BCM_GETNOTE
Definition: commctrl.h:4665
#define BUTTON_IMAGELIST_ALIGN_CENTER
Definition: commctrl.h:4636
#define BS_DEFCOMMANDLINK
Definition: commctrl.h:4678
#define BUTTON_IMAGELIST_ALIGN_TOP
Definition: commctrl.h:4634
#define CDRF_DODEFAULT
Definition: commctrl.h:268
struct _IMAGELIST * HIMAGELIST
Definition: commctrl.h:324
#define BUTTON_IMAGELIST_ALIGN_LEFT
Definition: commctrl.h:4632
#define CDIS_SELECTED
Definition: commctrl.h:291
#define CDRF_NOTIFYPOSTPAINT
Definition: commctrl.h:274
#define BCM_GETIDEALSIZE
Definition: commctrl.h:4644
#define WC_BUTTONA
Definition: commctrl.h:4627
#define CDDS_POSTERASE
Definition: commctrl.h:283
#define NM_CUSTOMDRAW
Definition: commctrl.h:137
#define BCM_GETSPLITINFO
Definition: commctrl.h:4663
#define BCM_SETIMAGELIST
Definition: commctrl.h:4647
#define CDIS_FOCUS
Definition: commctrl.h:295
#define BCSIF_GLYPH
Definition: commctrl.h:249
#define BCM_SETTEXTMARGIN
Definition: commctrl.h:4653
#define BS_DEFSPLITBUTTON
Definition: commctrl.h:4676
#define CDRF_DOERASE
Definition: commctrl.h:271
#define BCSS_IMAGE
Definition: commctrl.h:255
#define BCM_GETNOTELENGTH
Definition: commctrl.h:4666
#define CDDS_PREPAINT
Definition: commctrl.h:280
#define BCSS_STRETCH
Definition: commctrl.h:254
#define BCSIF_STYLE
Definition: commctrl.h:251
#define BUTTON_IMAGELIST_ALIGN_RIGHT
Definition: commctrl.h:4633
#define BCM_SETSPLITINFO
Definition: commctrl.h:4662
#define CDDS_POSTPAINT
Definition: commctrl.h:281
#define BCSIF_SIZE
Definition: commctrl.h:252
#define CDRF_SKIPDEFAULT
Definition: commctrl.h:270
#define BUTTON_IMAGELIST_ALIGN_BOTTOM
Definition: commctrl.h:4635
#define BS_COMMANDLINK
Definition: commctrl.h:4677
#define BCSIF_IMAGE
Definition: commctrl.h:250
#define BCM_SETDROPDOWNSTATE
Definition: commctrl.h:4661
#define CDDS_PREERASE
Definition: commctrl.h:282
#define BCM_GETTEXTMARGIN
Definition: commctrl.h:4655
#define BCM_GETIMAGELIST
Definition: commctrl.h:4650
#define ILC_COLOR
Definition: commctrl.h:352
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
#define WM_PRINTCLIENT
Definition: richedit.h:70
#define WM_NOTIFY
Definition: richedit.h:61
#define win_skip
Definition: test.h:163
#define memset(x, y, z)
Definition: compat.h:39
& rect
Definition: startmenu.cpp:1413
HIMAGELIST himl
Definition: commctrl.h:4639
LONG lfHeight
Definition: dimm.idl:42
LONG lfWeight
Definition: dimm.idl:46
CHAR lfFaceName[LF_FACESIZE]
Definition: dimm.idl:55
Definition: bl.h:1331
BOOL fIcon
Definition: winuser.h:3126
HBITMAP hbmColor
Definition: winuser.h:3130
HBITMAP hbmMask
Definition: winuser.h:3129
HBRUSH hbrBackground
Definition: winuser.h:3173
HICON hIcon
Definition: winuser.h:3171
HINSTANCE hInstance
Definition: winuser.h:3170
HCURSOR hCursor
Definition: winuser.h:3172
int cbWndExtra
Definition: winuser.h:3169
UINT style
Definition: winuser.h:3166
LPCSTR lpszMenuName
Definition: winuser.h:3174
LPCSTR lpszClassName
Definition: winuser.h:3175
WNDPROC lpfnWndProc
Definition: winuser.h:3167
int cbClsExtra
Definition: winuser.h:3168
int cbClsExtra
Definition: winuser.h:3207
int cbWndExtra
Definition: winuser.h:3208
WNDPROC lpfnWndProc
Definition: winuser.h:3206
WNDPROC lpfnWndProc
Definition: winuser.h:3221
int cbWndExtra
Definition: winuser.h:3223
int cbClsExtra
Definition: winuser.h:3222
Definition: http.c:7252
Definition: tftpd.h:60
UINT message
Definition: SystemMenu.c:42
Definition: name.c:39
UINT_PTR idFrom
Definition: winuser.h:3161
UINT code
Definition: winuser.h:3162
HWND hwndFrom
Definition: winuser.h:3160
Definition: time.h:68
#define max(a, b)
Definition: svc.c:63
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint32_t ULONG
Definition: typedefs.h:59
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
Definition: v6util.h:73
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:65
int ret
INT WINAPI DrawTextA(HDC hdc, LPCSTR str, INT count, LPRECT rect, UINT flags)
Definition: font.c:373
#define ZeroMemory
Definition: winbase.h:1736
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
#define WINAPI
Definition: msvc.h:6
HGDIOBJ WINAPI GetStockObject(_In_ int)
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
HFONT WINAPI CreateFontIndirectA(_In_ const LOGFONTA *)
HGDIOBJ WINAPI GetCurrentObject(_In_ HDC, _In_ UINT)
Definition: dc.c:428
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1546
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define WHITE_BRUSH
Definition: wingdi.h:902
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define FW_NORMAL
Definition: wingdi.h:373
#define SYSTEM_FONT
Definition: wingdi.h:911
BOOL WINAPI GetTextMetricsA(_In_ HDC, _Out_ LPTEXTMETRICA)
Definition: text.c:200
BOOL WINAPI DeleteDC(_In_ HDC)
#define WM_PAINT
Definition: winuser.h:1623
HWND WINAPI GetFocus(void)
Definition: window.c:1865
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define WM_ERASEBKGND
Definition: winuser.h:1628
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define BS_BITMAP
Definition: winuser.h:258
#define MAKEWPARAM(l, h)
Definition: winuser.h:4012
#define WM_GETTEXTLENGTH
Definition: winuser.h:1622
#define BM_GETSTATE
Definition: winuser.h:1923
#define IMAGE_BITMAP
Definition: winuser.h:211
#define WM_ENABLE
Definition: winuser.h:1618
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2633
#define WM_KEYUP
Definition: winuser.h:1719
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)
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
#define BS_RIGHT
Definition: winuser.h:274
LONG WINAPI GetWindowLongA(_In_ HWND, _In_ int)
#define DLGC_BUTTON
Definition: winuser.h:2623
#define WM_IME_NOTIFY
Definition: winuser.h:1833
LRESULT WINAPI DefWindowProcA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SM_CXEDGE
Definition: winuser.h:1011
UINT WINAPI RealGetWindowClassA(_In_ HWND hwnd, _Out_writes_to_(cchClassNameMax, return) LPSTR ptszClassName, _In_ UINT cchClassNameMax)
#define BST_UNCHECKED
Definition: winuser.h:199
#define IMAGE_ICON
Definition: winuser.h:212
#define BN_SETFOCUS
Definition: winuser.h:1936
BOOL WINAPI GetIconInfo(_In_ HICON, _Out_ PICONINFO)
Definition: cursoricon.c:2097
#define WM_CAPTURECHANGED
Definition: winuser.h:1811
#define CreateWindowA(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4318
#define WM_SYNCPAINT
Definition: winuser.h:1693
#define BS_ICON
Definition: winuser.h:264
#define VK_SPACE
Definition: winuser.h:2222
#define BM_SETSTATE
Definition: winuser.h:1926
int WINAPI GetClassNameA(_In_ HWND hWnd, _Out_writes_to_(nMaxCount, return) LPSTR lpClassName, _In_ int nMaxCount)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define WM_CANCELMODE
Definition: winuser.h:1638
#define BS_TYPEMASK
Definition: winuser.h:270
#define WM_DWMNCRENDERINGCHANGED
Definition: winuser.h:1888
#define WM_COMMAND
Definition: winuser.h:1743
#define DLGC_UNDEFPUSHBUTTON
Definition: winuser.h:2619
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define IDC_ARROW
Definition: winuser.h:687
#define BS_BOTTOM
Definition: winuser.h:259
#define BN_KILLFOCUS
Definition: winuser.h:1933
LRESULT WINAPI SendMessageA(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
#define WM_SETFOCUS
Definition: winuser.h:1616
#define QS_ALLINPUT
Definition: winuser.h:906
BOOL WINAPI GetClassInfoExA(_In_opt_ HINSTANCE, _In_ LPCSTR, _Out_ LPWNDCLASSEXA)
#define BN_HILITE
Definition: winuser.h:1932
#define WM_GETTEXT
Definition: winuser.h:1621
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define BS_RIGHTBUTTON
Definition: winuser.h:275
#define GetWindowLongPtrA
Definition: winuser.h:4831
#define BS_NOTIFY
Definition: winuser.h:268
#define WM_LBUTTONDOWN
Definition: winuser.h:1779
#define WM_DEVICECHANGE
Definition: winuser.h:1814
BOOL WINAPI GetClassInfoExW(_In_opt_ HINSTANCE, _In_ LPCWSTR, _Out_ LPWNDCLASSEXW)
#define DLGC_DEFPUSHBUTTON
Definition: winuser.h:2618
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
#define WM_GETFONT
Definition: winuser.h:1654
#define WM_DRAWITEM
Definition: winuser.h:1648
#define BM_SETCHECK
Definition: winuser.h:1924
#define BS_MULTILINE
Definition: winuser.h:267
#define BM_SETIMAGE
Definition: winuser.h:1925
#define WM_TIMECHANGE
Definition: winuser.h:1637
#define WM_IME_SETCONTEXT
Definition: winuser.h:1832
#define BN_UNHILITE
Definition: winuser.h:1937
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
ATOM WINAPI RegisterClassA(_In_ CONST WNDCLASSA *)
#define SM_CYMENUCHECK
Definition: winuser.h:1035
HWND WINAPI SetFocus(_In_opt_ HWND)
HWND WINAPI SetActiveWindow(_In_ HWND)
#define DLGC_RADIOBUTTON
Definition: winuser.h:2620
#define BS_LEFT
Definition: winuser.h:265
#define WM_SETFONT
Definition: winuser.h:1653
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)
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define DLGC_WANTARROWS
Definition: winuser.h:2613
#define BST_PUSHED
Definition: winuser.h:201
#define BM_GETIMAGE
Definition: winuser.h:1922
#define PM_REMOVE
Definition: winuser.h:1199
BOOL WINAPI UpdateWindow(_In_ HWND)
#define BM_SETSTYLE
Definition: winuser.h:1927
#define BS_VCENTER
Definition: winuser.h:279
HDC WINAPI GetDC(_In_opt_ HWND)
#define BS_TOP
Definition: winuser.h:277
#define DLGC_STATIC
Definition: winuser.h:2622
#define WM_LBUTTONUP
Definition: winuser.h:1780
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define WM_NCDESTROY
Definition: winuser.h:1687
#define VK_DOWN
Definition: winuser.h:2230
BOOL WINAPI PeekMessageA(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define BN_CLICKED
Definition: winuser.h:1928
#define SW_SHOW
Definition: winuser.h:778
#define WM_KEYDOWN
Definition: winuser.h:1718
#define BS_CENTER
Definition: winuser.h:260
#define WM_PARENTNOTIFY
Definition: winuser.h:1806
#define DT_CALCRECT
Definition: winuser.h:526
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
#define GWL_STYLE
Definition: winuser.h:855
#define WM_ENTERIDLE
Definition: winuser.h:1752
BOOL WINAPI DestroyWindow(_In_ HWND)
#define WM_KILLFOCUS
Definition: winuser.h:1617
BOOL WINAPI EqualRect(_In_ LPCRECT, _In_ LPCRECT)
int WINAPI GetSystemMetrics(_In_ int)
#define WM_GETDLGCODE
Definition: winuser.h:1692
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define BST_CHECKED
Definition: winuser.h:197
HCURSOR WINAPI LoadCursorA(_In_opt_ HINSTANCE, _In_ LPCSTR)
Definition: cursoricon.c:2142
#define WM_NCPAINT
Definition: winuser.h:1690
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define BM_GETCHECK
Definition: winuser.h:1921
#define WS_EX_RIGHT
Definition: winuser.h:400
BOOL WINAPI DestroyIcon(_In_ HICON)
Definition: cursoricon.c:2105
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193