ReactOS 0.4.16-dev-320-g3bd9ddc
taskdialog.c
Go to the documentation of this file.
1/* Unit tests for the task dialog control.
2 *
3 * Copyright 2017 Fabian Maurer for the Wine project
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20#include <stdarg.h>
21
22#include "windef.h"
23#include "winbase.h"
24#include "winuser.h"
25#include "commctrl.h"
26
27#include "wine/heap.h"
28#include "wine/test.h"
29#include "v6util.h"
30#include "msg.h"
31
32#ifdef __REACTOS__
33#undef WM_KEYF1
34#define WM_KEYF1 0x004d
35#endif
36
37#define WM_TD_CALLBACK (WM_APP) /* Custom dummy message to wrap callback notifications */
38
39#define NUM_MSG_SEQUENCES 1
40#define TASKDIALOG_SEQ_INDEX 0
41
42#define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
43#define TEST_NUM_RADIO_BUTTONS 3
44
45#define ID_START 20 /* Lower IDs might be used by the system */
46#define ID_START_BUTTON (ID_START + 0)
47#define ID_START_RADIO_BUTTON (ID_START + 20)
48
49static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
50static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
52
54
56{
60
62 const struct message_info *send; /* Message to send to trigger the next callback message */
63};
64
66
67/* Messages to send */
68static const struct message_info msg_send_return[] =
69{
70 { WM_KEYDOWN, VK_RETURN, 0 },
71 { 0 }
72};
73
74/* Messages to test against */
75static const struct message_info msg_return_press_ok[] =
76{
79 { 0 }
80};
81
82static const struct message_info msg_return_press_yes[] =
83{
86 { 0 }
87};
88
89static const struct message_info msg_return_press_no[] =
90{
93 { 0 }
94};
95
97{
100 { 0 }
101};
102
104{
105 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
107 { 0 }
108};
109
111{
112 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
114 { 0 }
115};
116
118{
119 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
121 { 0 }
122};
123
125{
126 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
127 { TDN_BUTTON_CLICKED, -1, 0, S_OK, NULL },
128 { 0 }
129};
130
131static const struct message_info msg_send_click_ok[] =
132{
133 { TDM_CLICK_BUTTON, IDOK, 0 },
134 { 0 }
135};
136
137static const struct message_info msg_send_f1[] =
138{
139 { WM_KEYF1, 0, 0, 0},
140 { 0 }
141};
142
143static const struct message_info msg_got_tdn_help[] =
144{
145 { TDN_CREATED, 0, 0, S_OK, msg_send_f1 },
146 { TDN_HELP, 0, 0, S_OK, msg_send_click_ok },
148 { 0 }
149};
150
151/* Three radio buttons */
153{
154 { TDN_CREATED, 0, 0, S_OK, NULL },
157 { 0 }
158};
159
161{
162 { TDN_CREATED, 0, 0, S_OK, NULL },
165 { 0 }
166};
167
169{
170 { TDN_CREATED, 0, 0, S_OK, NULL },
173 { 0 }
174};
175
177{
179 { 0 }
180};
181
183{
184 { TDN_CREATED, 0, 0, S_OK, NULL },
188 { 0 }
189};
190
192{
195 { TDM_CLICK_BUTTON, IDOK, 0 },
196 { 0 }
197};
198
200{
201 { TDN_CREATED, 0, 0, S_OK, NULL },
205 { 0 }
206};
207
209{
213 { 0 }
214};
215
217{
220 { 0 }
221};
222
224{
225 { TDM_CLICK_RADIO_BUTTON, -2, 0 },
226 { 0 }
227};
228
230{
234 { 0 }
235};
236
238{
239 { TDM_CLICK_BUTTON, IDOK, 0 },
240 { TDM_CLICK_BUTTON, IDYES, 0 },
241 { TDM_CLICK_BUTTON, IDNO, 0 },
244 { TDM_CLICK_BUTTON, IDCLOSE, 0 },
246 { 0 }
247};
248
250{
257 { TDN_BUTTON_CLICKED, IDCLOSE, 0, S_FALSE, NULL },
259 { 0 }
260};
261
263{
269 { WM_COMMAND, MAKEWORD(IDCLOSE, BN_CLICKED), 0 },
272 { 0 }
273};
274
276{
280 { 0 }
281};
282
284{
286 { TDM_CLICK_BUTTON, IDOK, 0 },
287 { 0 }
288};
289
291{
294 { 0 }
295};
296
298{
301 { 0 }
302};
303
305{
308 { 0 }
309};
310
312{
314 { 0 }
315};
316
318{
322 { 0 }
323};
324
326{
328 { 0 }
329};
330
332{
336 { 0 }
337};
338
340
341static const struct message_info msg_send_navigate[] =
342{
344 { 0 }
345};
346
348{
349 { TDN_CREATED, 0, 0, S_OK, NULL },
351 { TDN_DIALOG_CONSTRUCTED, 0, 0, S_OK, NULL },
355 { 0 }
356};
357
358static const struct message_info msg_send_close[] =
359{
360 { WM_CLOSE, 0, 0, 0},
361 { 0 }
362};
363
364static const struct message_info msg_handle_wm_close[] =
365{
366 { TDN_CREATED, 0, 0, S_OK, msg_send_close },
369 { 0 }
370};
371
373{
374 { WM_CLOSE, 0, 0, 0},
375 { TDM_CLICK_BUTTON, IDOK, 0 },
376 { 0 }
377};
378
380{
383 { 0 }
384};
385
387{
388 msg->message = WM_TD_CALLBACK;
389 msg->flags = sent|wparam|lparam|id;
390 msg->wParam = wParam;
391 msg->lParam = lParam;
392 msg->id = message;
393 msg->stage = 0;
394}
395
396#define run_test(info, expect_button, expect_radio_button, verification_checked, seq, context) \
397 run_test_(info, expect_button, expect_radio_button, verification_checked, seq, context, \
398 ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
399
400static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button, BOOL verification_checked,
401 const struct message_info *test_messages, const char *context, int test_messages_len,
402 const char *file, int line)
403{
404 struct message *msg, *msg_start;
405 int ret_button = 0;
406 int ret_radio = 0;
407 BOOL ret_verification = FALSE;
408 HRESULT hr;
409 int i;
410
411 /* Allocate messages to test against, plus 2 implicit and 1 empty */
412 msg_start = msg = heap_alloc_zero(sizeof(*msg) * (test_messages_len + 3));
413
414 /* Always needed, thus made implicit */
416 for (i = 0; i < test_messages_len; i++)
418 /* Always needed, thus made implicit */
420
423
424 hr = pTaskDialogIndirect(info, &ret_button, &ret_radio, &ret_verification);
425 ok_(file, line)(hr == S_OK, "TaskDialogIndirect() failed, got %#x.\n", hr);
426
428 ok_(file, line)(ret_button == expect_button,
429 "Wrong button. Expected %d, got %d\n", expect_button, ret_button);
430 ok_(file, line)(ret_radio == expect_radio_button,
431 "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
432
433 heap_free(msg_start);
434}
435
436static const LONG_PTR test_ref_data = 123456;
437
440{
441 int msg_pos = sequences[TASKDIALOG_SEQ_INDEX]->count - 1; /* Skip implicit message */
442 const struct message_info *msg_send;
443 struct message msg;
444
445 ok(test_ref_data == ref_data, "Unexpected ref data %lu.\n", ref_data);
446
449
450 if (notification == TDN_DIALOG_CONSTRUCTED || notification == TDN_DESTROYED) /* Skip implicit messages */
451 return S_OK;
452
453 msg_send = current_message_info[msg_pos].send;
454 for(; msg_send && msg_send->message; msg_send++)
455 PostMessageW(hwnd, msg_send->message, msg_send->wparam, msg_send->lparam);
456
457 return current_message_info[msg_pos].callback_retval;
458}
459
460static void test_invalid_parameters(void)
461{
462 TASKDIALOGCONFIG info = { 0 };
463 HRESULT hr;
464
465 hr = pTaskDialogIndirect(NULL, NULL, NULL, NULL);
466 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
467
468 info.cbSize = 0;
469 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
470 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
471
472 info.cbSize = sizeof(TASKDIALOGCONFIG) - 1;
473 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
474 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
475
476 info.cbSize = sizeof(TASKDIALOGCONFIG) + 1;
477 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
478 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
479}
480
481static void test_callback(void)
482{
484
485 info.cbSize = sizeof(TASKDIALOGCONFIG);
486 info.pfCallback = taskdialog_callback_proc;
487 info.lpCallbackData = test_ref_data;
488
489 run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "Press VK_RETURN.");
490}
491
492static void test_buttons(void)
493{
495 static const DWORD command_link_flags[] = {0, TDF_USE_COMMAND_LINKS, TDF_USE_COMMAND_LINKS_NO_ICON};
496 TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
497 const WCHAR button_format[] = {'%','0','2','d',0};
498 /* Each button has two digits as title, plus null-terminator */
499 WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
500 int i;
501
502 info.cbSize = sizeof(TASKDIALOGCONFIG);
503 info.pfCallback = taskdialog_callback_proc;
504 info.lpCallbackData = test_ref_data;
505
506 /* Init custom buttons */
507 for (i = 0; i < TEST_NUM_BUTTONS; i++)
508 {
509 WCHAR *text = &button_titles[i * 3];
510 wsprintfW(text, button_format, i);
511
512 custom_buttons[i].pszButtonText = text;
513 custom_buttons[i].nButtonID = ID_START_BUTTON + i;
514 }
515 custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
516
517 /* Init radio buttons */
518 for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
519 {
520 WCHAR *text = &radio_button_titles[i * 3];
521 wsprintfW(text, button_format, i);
522
523 radio_buttons[i].pszButtonText = text;
524 radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
525 }
526 radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
527
528 /* Test nDefaultButton */
529
530 /* Test common buttons with invalid default ID */
531 info.nDefaultButton = 0; /* Should default to first created button */
534 run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "default button: unset default");
535 info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
537 run_test(&info, IDYES, 0, FALSE, msg_return_press_yes, "default button: unset default");
539 run_test(&info, IDNO, 0, FALSE, msg_return_press_no, "default button: unset default");
541 run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: unset default");
542 info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
543 run_test(&info, IDCANCEL, 0, FALSE, msg_return_press_cancel, "default button: unset default");
544
545 /* Custom buttons could be command links */
546 for (i = 0; i < ARRAY_SIZE(command_link_flags); i++)
547 {
548 info.dwFlags = command_link_flags[i];
549
550 /* Test with all common and custom buttons and invalid default ID */
551 info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
552 info.cButtons = TEST_NUM_BUTTONS;
553 info.pButtons = custom_buttons;
555 "default button: invalid default, with common buttons - 1");
556
557 info.nDefaultButton = -1; /* Should work despite button ID -1 */
558 run_test(&info, -1, 0, FALSE, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
559
560 info.nDefaultButton = -2; /* Should also default to first created button */
562 "default button: invalid default, with common buttons - 3");
563
564 /* Test with only custom buttons and invalid default ID */
565 info.dwCommonButtons = 0;
567 "default button: invalid default, no common buttons");
568
569 /* Test with common and custom buttons and valid default ID */
572 info.nDefaultButton = IDRETRY;
573 run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: valid default - 1");
574
575 /* Test with common and custom buttons and valid default ID */
576 info.nDefaultButton = ID_START_BUTTON + 3;
577 run_test(&info, ID_START_BUTTON + 3, 0, FALSE, msg_return_press_custom4, "default button: valid default - 2");
578 }
579
580 /* Test radio buttons */
581 info.nDefaultButton = 0;
582 info.cButtons = 0;
583 info.pButtons = 0;
584 info.dwCommonButtons = TDCBF_OK_BUTTON;
585 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
586 info.pRadioButtons = radio_buttons;
587
588 /* Test default first radio button */
590 "default radio button: default first radio button");
591
592 /* Test default radio button */
593 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
595 "default radio button: default radio button");
596
597 /* Test default radio button with -2 */
598 info.nDefaultRadioButton = -2;
600 "default radio button: default radio button with id -2");
601
602 /* Test default radio button after clicking the first, messages still work even radio button is disabled */
603 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
605 "default radio button: radio button after clicking");
606
607 /* Test radio button after disabling and clicking the first */
608 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
610 "default radio button: disable radio button before clicking");
611
612 /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
613 info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
616 "default radio button: no default radio flag");
617
618 /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
619 * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
620 info.nDefaultRadioButton = 0;
623 "default radio button: no default radio id and flag");
624
625 /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
626 * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
627 info.nDefaultRadioButton = 0xff;
630 "default radio button: no default flag, invalid id");
631
632 info.nDefaultRadioButton = 0;
635 "radio button: manually click radio button with negative id");
636
637 /* Test sending clicks to non-existent buttons. Notification of non-existent buttons will be sent */
638 info.cButtons = TEST_NUM_BUTTONS;
639 info.pButtons = custom_buttons;
640 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
641 info.pRadioButtons = radio_buttons;
642 info.dwCommonButtons = 0;
644 run_test(&info, ID_START_BUTTON + 99, 0, FALSE, msg_press_nonexistent_buttons, "sends click to non-existent buttons");
645
646 /* Non-existent button clicks sent by WM_COMMAND won't generate TDN_BUTTON_CLICKED except IDOK.
647 * And will get the first existent button identifier instead of IDOK */
649 "sends click to non-existent buttons with WM_COMMAND");
650
651 /* Non-existent radio button won't get notifications */
652 run_test(&info, IDOK, 0, FALSE, msg_press_nonexistent_radio_button, "sends click to non-existent radio buttons");
653}
654
655static void test_help(void)
656{
658
659 info.cbSize = sizeof(TASKDIALOGCONFIG);
660 info.pfCallback = taskdialog_callback_proc;
661 info.lpCallbackData = test_ref_data;
662 info.dwCommonButtons = TDCBF_OK_BUTTON;
663
664 run_test(&info, IDOK, 0, FALSE, msg_got_tdn_help, "send f1");
665}
666
668{
671};
672
675{
676 struct timer_notification_data *data = (struct timer_notification_data *)ref_data;
677
678 if (notification == TDN_TIMER)
679 {
680 DWORD elapsed_ms;
681 int delta;
682
683 elapsed_ms = (DWORD)wParam;
684
685 if (data->num_fired == 3)
686 ok(data->last_elapsed_ms > elapsed_ms, "Expected reference time update.\n");
687 else
688 {
689 delta = elapsed_ms - data->last_elapsed_ms;
690 ok(delta > 0, "Expected positive time tick difference.\n");
691 }
692 data->last_elapsed_ms = elapsed_ms;
693
694 if (data->num_fired == 3)
696
697 ++data->num_fired;
698 return data->num_fired == 3 ? S_FALSE : S_OK;
699 }
700
701 return S_OK;
702}
703
704static void test_timer(void)
705{
706 struct timer_notification_data data = { 0 };
707 TASKDIALOGCONFIG info = { 0 };
708
709 info.cbSize = sizeof(TASKDIALOGCONFIG);
711 info.lpCallbackData = (LONG_PTR)&data;
712 info.dwFlags = TDF_CALLBACK_TIMER;
713 info.dwCommonButtons = TDCBF_OK_BUTTON;
714
715 pTaskDialogIndirect(&info, NULL, NULL, NULL);
716}
717
719 LPARAM lParam, LONG_PTR ref_data)
720{
721 unsigned long ret;
722 LONG flags = (LONG)ref_data;
724 {
725 /* TDM_SET_PROGRESS_BAR_STATE */
727 ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
729 ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
731 /* Progress bar has fixme on handling PBM_SETSTATE message */
732 todo_wine ok(ret == PBST_PAUSED, "Expect state: %d got state: %lx\n", PBST_PAUSED, ret);
734 todo_wine ok(ret == PBST_ERROR, "Expect state: %d got state: %lx\n", PBST_ERROR, ret);
735
736 /* TDM_SET_PROGRESS_BAR_RANGE */
738 ok(ret == MAKELONG(0, 100), "Expect range:%x got:%lx\n", MAKELONG(0, 100), ret);
740 ok(ret == MAKELONG(0, 200), "Expect range:%x got:%lx\n", MAKELONG(0, 200), ret);
741
742 /* TDM_SET_PROGRESS_BAR_POS */
744 {
746 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
748 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
749 }
750 else
751 {
753 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
755 ok(ret == 1, "Expect position:%x got:%lx\n", 1, ret);
756 }
757
759 }
760
761 return S_OK;
762}
763
764static void test_progress_bar(void)
765{
767
768 info.cbSize = sizeof(TASKDIALOGCONFIG);
769 info.dwFlags = TDF_SHOW_PROGRESS_BAR;
771 info.lpCallbackData = (LONG_PTR)info.dwFlags;
772 info.dwCommonButtons = TDCBF_OK_BUTTON;
773 pTaskDialogIndirect(&info, NULL, NULL, NULL);
774
776 info.lpCallbackData = (LONG_PTR)info.dwFlags;
777 pTaskDialogIndirect(&info, NULL, NULL, NULL);
778
780 info.lpCallbackData = (LONG_PTR)info.dwFlags;
781 pTaskDialogIndirect(&info, NULL, NULL, NULL);
782}
783
784static void test_verification_box(void)
785{
787 WCHAR textW[] = {'t', 'e', 'x', 't', 0};
788
789 info.cbSize = sizeof(TASKDIALOGCONFIG);
790 info.pfCallback = taskdialog_callback_proc;
791 info.lpCallbackData = test_ref_data;
792 info.dwCommonButtons = TDCBF_OK_BUTTON;
793
794 /* TDF_VERIFICATION_FLAG_CHECKED works even if pszVerificationText is not set */
795 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
796
798 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
799
800 info.pszVerificationText = textW;
801 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
802
804 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
805
807 "default verification box: default checked and then unchecked");
808
809 info.dwFlags = 0;
811 "default verification box: default unchecked and then checked");
812}
813
814static void test_navigate_page(void)
815{
817 static const WCHAR textW[] = {'t', 'e', 'x', 't', 0};
818 static const WCHAR button_format[] = {'%', '0', '2', 'd', 0};
820 WCHAR radio_button_titles[TEST_NUM_BUTTONS * 3];
821 int i;
822
823 /* Init radio buttons */
824 for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
825 {
826 WCHAR *text = &radio_button_titles[i * 3];
827 wsprintfW(text, button_format, i);
828
829 radio_buttons[i].pszButtonText = text;
830 radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
831 }
832
833 info.cbSize = sizeof(TASKDIALOGCONFIG);
834 info.pfCallback = taskdialog_callback_proc;
835 info.lpCallbackData = test_ref_data;
836 info.dwCommonButtons = TDCBF_OK_BUTTON;
837 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
838 info.pRadioButtons = radio_buttons;
839
843
845
846 /* TDM_NAVIGATE_PAGE doesn't check cbSize.
847 * And null taskconfig pointer crash applicatioin, thus doesn't check pointer either */
849 run_test(&info, IDOK, ID_START_RADIO_BUTTON, TRUE, msg_return_navigated_page, "navigate page: invalid taskconfig cbSize");
850}
851
852static void test_wm_close(void)
853{
855
856 info.cbSize = sizeof(TASKDIALOGCONFIG);
857 info.pfCallback = taskdialog_callback_proc;
858 info.lpCallbackData = test_ref_data;
859
860 /* WM_CLOSE can end the dialog only when a cancel button is present or dwFlags has TDF_ALLOW_DIALOG_CANCELLATION */
861 info.dwCommonButtons = TDCBF_OK_BUTTON;
862 run_test(&info, IDOK, 0, FALSE, msg_handle_wm_close_without_cancel_button, "send WM_CLOSE without cancel button");
863
865 run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with TDF_ALLOW_DIALOG_CANCELLATION");
866
867 info.dwFlags = 0;
868 info.dwCommonButtons = TDCBF_CANCEL_BUTTON;
869 run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with a cancel button");
870}
871
872START_TEST(taskdialog)
873{
874 ULONG_PTR ctx_cookie;
875 void *ptr_ordinal;
877 HANDLE hCtx;
878
879 if (!load_v6_module(&ctx_cookie, &hCtx))
880 return;
881
882 /* Check if task dialogs are available */
883 hinst = LoadLibraryA("comctl32.dll");
884
885 pTaskDialogIndirect = (void *)GetProcAddress(hinst, "TaskDialogIndirect");
886 if (!pTaskDialogIndirect)
887 {
888 win_skip("TaskDialogIndirect not exported by name\n");
889 unload_v6_module(ctx_cookie, hCtx);
890 return;
891 }
892
893 pTaskDialog = (void *)GetProcAddress(hinst, "TaskDialog");
894
895 ptr_ordinal = GetProcAddress(hinst, (const char *)344);
896 ok(pTaskDialog == ptr_ordinal, "got wrong pointer for ordinal 344, %p expected %p\n",
897 ptr_ordinal, pTaskDialog);
898
899 ptr_ordinal = GetProcAddress(hinst, (const char *)345);
900 ok(pTaskDialogIndirect == ptr_ordinal, "got wrong pointer for ordinal 345, %p expected %p\n",
901 ptr_ordinal, pTaskDialogIndirect);
902
904
907 test_buttons();
908 test_help();
909 test_timer();
914
915 unload_v6_module(ctx_cookie, hCtx);
916}
@ sent
Definition: SystemMenu.c:27
@ lparam
Definition: SystemMenu.c:31
@ wparam
Definition: SystemMenu.c:30
#define add_message(msg)
Definition: SystemMenu.c:98
static void ok_sequence_(const struct message *expected_list, const char *context, BOOL todo, const char *file, int line)
Definition: SystemMenu.c:279
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
#define ok_(x1, x2)
Definition: atltest.h:61
#define msg(x)
Definition: auth_time.c:54
#define ARRAY_SIZE(A)
Definition: main.h:20
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
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
#define E_INVALIDARG
Definition: ddrawi.h:101
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
HANDLE HWND
Definition: compat.h:19
#define GetProcAddress(x, y)
Definition: compat.h:753
#define CALLBACK
Definition: compat.h:35
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
const WCHAR * text
Definition: package.c:1794
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
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
#define S_OK
Definition: intsafe.h:52
static HINSTANCE hinst
Definition: edit.c:551
static void test_messages(void)
Definition: propsheet.c:790
static const struct message_info msg_return_verification_checked[]
Definition: taskdialog.c:331
static const struct message_info msg_return_press_retry[]
Definition: taskdialog.c:103
static void test_verification_box(void)
Definition: taskdialog.c:784
static const struct message_info msg_return_default_radio_button_clicking_disabled[]
Definition: taskdialog.c:199
static void test_progress_bar(void)
Definition: taskdialog.c:764
static HRESULT CALLBACK taskdialog_callback_proc_timer(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:673
static const struct message_info msg_got_tdn_help[]
Definition: taskdialog.c:143
static const struct message_info msg_select_negative_id_radio_button[]
Definition: taskdialog.c:223
static const struct message_info msg_press_nonexistent_buttons_with_command[]
Definition: taskdialog.c:275
static const struct message_info msg_send_click_ok[]
Definition: taskdialog.c:131
static const struct message_info msg_return_press_yes[]
Definition: taskdialog.c:82
#define NUM_MSG_SEQUENCES
Definition: taskdialog.c:39
static void test_navigate_page(void)
Definition: taskdialog.c:814
static const struct message_info msg_return_verification_unchecked[]
Definition: taskdialog.c:317
static const struct message_info msg_send_close_then_ok[]
Definition: taskdialog.c:372
static const struct message_info msg_return_press_negative_id_radio_button[]
Definition: taskdialog.c:229
static int int BOOL *static const WCHAR const WCHAR const WCHAR TASKDIALOG_COMMON_BUTTON_FLAGS
Definition: taskdialog.c:50
#define run_test(info, expect_button, expect_radio_button, verification_checked, seq, context)
Definition: taskdialog.c:396
static HRESULT CALLBACK taskdialog_callback_proc(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:438
static const struct message_info msg_return_press_no[]
Definition: taskdialog.c:89
static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[]
Definition: taskdialog.c:191
static const struct message_info msg_return_press_ok[]
Definition: taskdialog.c:75
static const struct message_info msg_return_default_verification_checked[]
Definition: taskdialog.c:304
static void test_buttons(void)
Definition: taskdialog.c:492
static const struct message_info msg_send_all_common_button_click_with_command[]
Definition: taskdialog.c:262
static void test_help(void)
Definition: taskdialog.c:655
static void test_invalid_parameters(void)
Definition: taskdialog.c:460
static const struct message_info msg_send_close[]
Definition: taskdialog.c:358
static const struct message_info msg_uncheck_verification[]
Definition: taskdialog.c:311
static const struct message_info msg_handle_wm_close_without_cancel_button[]
Definition: taskdialog.c:379
static const struct message_info msg_return_default_radio_button_2[]
Definition: taskdialog.c:160
static const struct message_info msg_return_no_default_radio_button_id_and_flag[]
Definition: taskdialog.c:216
static const struct message_info msg_send_f1[]
Definition: taskdialog.c:137
#define ID_START_BUTTON
Definition: taskdialog.c:46
static void test_wm_close(void)
Definition: taskdialog.c:852
static const struct message_info msg_handle_wm_close[]
Definition: taskdialog.c:364
#define TEST_NUM_RADIO_BUTTONS
Definition: taskdialog.c:43
static const struct message_info msg_return_first_radio_button[]
Definition: taskdialog.c:182
#define TEST_NUM_BUTTONS
Definition: taskdialog.c:42
static int int BOOL *static HINSTANCE
Definition: taskdialog.c:50
static const LONG_PTR test_ref_data
Definition: taskdialog.c:436
static const struct message_info msg_return_no_default_radio_button_flag[]
Definition: taskdialog.c:208
#define WM_TD_CALLBACK
Definition: taskdialog.c:37
static const struct message_info msg_send_navigate[]
Definition: taskdialog.c:341
static const struct message_info msg_return_default_verification_unchecked[]
Definition: taskdialog.c:297
static const struct message_info msg_send_return[]
Definition: taskdialog.c:68
static const struct message_info * current_message_info
Definition: taskdialog.c:65
static const struct message_info msg_return_press_custom10[]
Definition: taskdialog.c:124
static const struct message_info msg_send_nonexistent_radio_button_click[]
Definition: taskdialog.c:283
static TASKDIALOGCONFIG navigated_info
Definition: taskdialog.c:339
static const struct message_info msg_return_default_radio_button_3[]
Definition: taskdialog.c:168
static const struct message_info msg_press_nonexistent_buttons[]
Definition: taskdialog.c:249
static void test_callback(void)
Definition: taskdialog.c:481
static const struct message_info msg_return_default_radio_button_1[]
Definition: taskdialog.c:152
static const struct message_info msg_check_verification[]
Definition: taskdialog.c:325
static int int BOOL *static const WCHAR const WCHAR const WCHAR const WCHAR int *static struct msg_sequence * sequences[NUM_MSG_SEQUENCES]
Definition: taskdialog.c:53
static const struct message_info msg_press_nonexistent_radio_button[]
Definition: taskdialog.c:290
static const struct message_info msg_return_navigated_page[]
Definition: taskdialog.c:347
#define TASKDIALOG_SEQ_INDEX
Definition: taskdialog.c:40
static const struct message_info msg_select_first_radio_button[]
Definition: taskdialog.c:176
static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button, BOOL verification_checked, const struct message_info *test_messages, const char *context, int test_messages_len, const char *file, int line)
Definition: taskdialog.c:400
static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
Definition: taskdialog.c:386
static const struct message_info msg_send_all_common_button_click[]
Definition: taskdialog.c:237
static const struct message_info msg_return_press_custom1[]
Definition: taskdialog.c:110
static void test_timer(void)
Definition: taskdialog.c:704
static const struct message_info msg_return_press_cancel[]
Definition: taskdialog.c:96
#define ID_START_RADIO_BUTTON
Definition: taskdialog.c:47
static const struct message_info msg_return_press_custom4[]
Definition: taskdialog.c:117
static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:718
static const WCHAR textW[]
Definition: itemdlg.c:1559
#define todo_wine
Definition: custom.c:89
#define WM_KEYF1
Definition: msg.c:47
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
unsigned int UINT
Definition: ndis.h:50
#define DWORD
Definition: nt_native.h:44
long LONG
Definition: pedump.c:60
struct _TASKDIALOGCONFIG TASKDIALOGCONFIG
@ TDF_NO_DEFAULT_RADIO_BUTTON
Definition: commctrl.h:5117
@ TDF_ALLOW_DIALOG_CANCELLATION
Definition: commctrl.h:5106
@ TDF_CALLBACK_TIMER
Definition: commctrl.h:5114
@ TDF_SHOW_PROGRESS_BAR
Definition: commctrl.h:5112
@ TDF_USE_COMMAND_LINKS
Definition: commctrl.h:5107
@ TDF_USE_COMMAND_LINKS_NO_ICON
Definition: commctrl.h:5108
@ TDF_SHOW_MARQUEE_PROGRESS_BAR
Definition: commctrl.h:5113
@ TDF_VERIFICATION_FLAG_CHECKED
Definition: commctrl.h:5111
@ TDCBF_YES_BUTTON
Definition: commctrl.h:5180
@ TDCBF_OK_BUTTON
Definition: commctrl.h:5179
@ TDCBF_CLOSE_BUTTON
Definition: commctrl.h:5184
@ TDCBF_NO_BUTTON
Definition: commctrl.h:5181
@ TDCBF_RETRY_BUTTON
Definition: commctrl.h:5183
@ TDCBF_CANCEL_BUTTON
Definition: commctrl.h:5182
@ TDM_SET_PROGRESS_BAR_RANGE
Definition: commctrl.h:5130
@ TDM_CLICK_RADIO_BUTTON
Definition: commctrl.h:5134
@ TDM_ENABLE_RADIO_BUTTON
Definition: commctrl.h:5136
@ TDM_CLICK_BUTTON
Definition: commctrl.h:5127
@ TDM_SET_PROGRESS_BAR_POS
Definition: commctrl.h:5131
@ TDM_CLICK_VERIFICATION
Definition: commctrl.h:5137
@ TDM_SET_PROGRESS_BAR_STATE
Definition: commctrl.h:5129
@ TDM_NAVIGATE_PAGE
Definition: commctrl.h:5126
@ TDN_VERIFICATION_CLICKED
Definition: commctrl.h:5153
@ TDN_RADIO_BUTTON_CLICKED
Definition: commctrl.h:5151
@ TDN_DIALOG_CONSTRUCTED
Definition: commctrl.h:5152
@ TDN_TIMER
Definition: commctrl.h:5149
@ TDN_DESTROYED
Definition: commctrl.h:5150
@ TDN_NAVIGATED
Definition: commctrl.h:5146
@ TDN_CREATED
Definition: commctrl.h:5145
@ TDN_HELP
Definition: commctrl.h:5154
@ TDN_BUTTON_CLICKED
Definition: commctrl.h:5147
#define win_skip
Definition: test.h:163
HRESULT hr
Definition: shlfolder.c:183
PCWSTR pszVerificationText
Definition: commctrl.h:5223
TASKDIALOG_FLAGS dwFlags
Definition: commctrl.h:5207
PCWSTR pszButtonText
Definition: commctrl.h:5191
Definition: http.c:7252
Definition: fci.c:127
Definition: parser.c:49
UINT message
Definition: taskdialog.c:57
HRESULT callback_retval
Definition: taskdialog.c:61
WPARAM wparam
Definition: taskdialog.c:58
const struct message_info * send
Definition: taskdialog.c:62
LPARAM lparam
Definition: taskdialog.c:59
Definition: tftpd.h:60
#define LONG_PTR
Definition: treelist.c:79
#define MAKEWORD(a, b)
Definition: typedefs.h:248
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define MAKELONG(a, b)
Definition: typedefs.h:249
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
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
UINT_PTR WPARAM
Definition: windef.h:207
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define WM_CLOSE
Definition: winuser.h:1624
#define MAKELPARAM(l, h)
Definition: winuser.h:4011
#define IDCANCEL
Definition: winuser.h:834
BOOL WINAPI PostMessageW(_In_opt_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define WM_COMMAND
Definition: winuser.h:1743
#define IDOK
Definition: winuser.h:833
#define VK_RETURN
Definition: winuser.h:2204
#define IDNO
Definition: winuser.h:839
#define BN_CLICKED
Definition: winuser.h:1928
#define WM_KEYDOWN
Definition: winuser.h:1718
#define IDYES
Definition: winuser.h:838
#define IDRETRY
Definition: winuser.h:836
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180