ReactOS 0.4.15-dev-5666-gc548b97
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#define WM_KEYF1 0x004d
34#endif
35
36#define WM_TD_CALLBACK (WM_APP) /* Custom dummy message to wrap callback notifications */
37
38#define NUM_MSG_SEQUENCES 1
39#define TASKDIALOG_SEQ_INDEX 0
40
41#define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
42#define TEST_NUM_RADIO_BUTTONS 3
43
44#define ID_START 20 /* Lower IDs might be used by the system */
45#define ID_START_BUTTON (ID_START + 0)
46#define ID_START_RADIO_BUTTON (ID_START + 20)
47
48static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
49static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
51
53
55{
59
61 const struct message_info *send; /* Message to send to trigger the next callback message */
62};
63
65
66/* Messages to send */
67static const struct message_info msg_send_return[] =
68{
69 { WM_KEYDOWN, VK_RETURN, 0 },
70 { 0 }
71};
72
73/* Messages to test against */
74static const struct message_info msg_return_press_ok[] =
75{
78 { 0 }
79};
80
81static const struct message_info msg_return_press_yes[] =
82{
85 { 0 }
86};
87
88static const struct message_info msg_return_press_no[] =
89{
92 { 0 }
93};
94
96{
99 { 0 }
100};
101
103{
104 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
106 { 0 }
107};
108
110{
111 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
113 { 0 }
114};
115
117{
118 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
120 { 0 }
121};
122
124{
125 { TDN_CREATED, 0, 0, S_OK, msg_send_return },
126 { TDN_BUTTON_CLICKED, -1, 0, S_OK, NULL },
127 { 0 }
128};
129
130static const struct message_info msg_send_click_ok[] =
131{
132 { TDM_CLICK_BUTTON, IDOK, 0 },
133 { 0 }
134};
135
136static const struct message_info msg_send_f1[] =
137{
138 { WM_KEYF1, 0, 0, 0},
139 { 0 }
140};
141
142static const struct message_info msg_got_tdn_help[] =
143{
144 { TDN_CREATED, 0, 0, S_OK, msg_send_f1 },
145 { TDN_HELP, 0, 0, S_OK, msg_send_click_ok },
147 { 0 }
148};
149
150/* Three radio buttons */
152{
153 { TDN_CREATED, 0, 0, S_OK, NULL },
156 { 0 }
157};
158
160{
161 { TDN_CREATED, 0, 0, S_OK, NULL },
164 { 0 }
165};
166
168{
169 { TDN_CREATED, 0, 0, S_OK, NULL },
172 { 0 }
173};
174
176{
178 { 0 }
179};
180
182{
183 { TDN_CREATED, 0, 0, S_OK, NULL },
187 { 0 }
188};
189
191{
194 { TDM_CLICK_BUTTON, IDOK, 0 },
195 { 0 }
196};
197
199{
200 { TDN_CREATED, 0, 0, S_OK, NULL },
204 { 0 }
205};
206
208{
212 { 0 }
213};
214
216{
219 { 0 }
220};
221
223{
224 { TDM_CLICK_RADIO_BUTTON, -2, 0 },
225 { 0 }
226};
227
229{
233 { 0 }
234};
235
237{
238 { TDM_CLICK_BUTTON, IDOK, 0 },
239 { TDM_CLICK_BUTTON, IDYES, 0 },
240 { TDM_CLICK_BUTTON, IDNO, 0 },
243 { TDM_CLICK_BUTTON, IDCLOSE, 0 },
245 { 0 }
246};
247
249{
256 { TDN_BUTTON_CLICKED, IDCLOSE, 0, S_FALSE, NULL },
258 { 0 }
259};
260
262{
268 { WM_COMMAND, MAKEWORD(IDCLOSE, BN_CLICKED), 0 },
271 { 0 }
272};
273
275{
279 { 0 }
280};
281
283{
285 { TDM_CLICK_BUTTON, IDOK, 0 },
286 { 0 }
287};
288
290{
293 { 0 }
294};
295
297{
300 { 0 }
301};
302
304{
307 { 0 }
308};
309
311{
313 { 0 }
314};
315
317{
321 { 0 }
322};
323
325{
327 { 0 }
328};
329
331{
335 { 0 }
336};
337
339
340static const struct message_info msg_send_navigate[] =
341{
343 { 0 }
344};
345
347{
348 { TDN_CREATED, 0, 0, S_OK, NULL },
350 { TDN_DIALOG_CONSTRUCTED, 0, 0, S_OK, NULL },
354 { 0 }
355};
356
357static const struct message_info msg_send_close[] =
358{
359 { WM_CLOSE, 0, 0, 0},
360 { 0 }
361};
362
363static const struct message_info msg_handle_wm_close[] =
364{
365 { TDN_CREATED, 0, 0, S_OK, msg_send_close },
368 { 0 }
369};
370
372{
373 { WM_CLOSE, 0, 0, 0},
374 { TDM_CLICK_BUTTON, IDOK, 0 },
375 { 0 }
376};
377
379{
382 { 0 }
383};
384
386{
387 msg->message = WM_TD_CALLBACK;
388 msg->flags = sent|wparam|lparam|id;
389 msg->wParam = wParam;
390 msg->lParam = lParam;
391 msg->id = message;
392 msg->stage = 0;
393}
394
395#define run_test(info, expect_button, expect_radio_button, verification_checked, seq, context) \
396 run_test_(info, expect_button, expect_radio_button, verification_checked, seq, context, \
397 ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
398
399static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button, BOOL verification_checked,
400 const struct message_info *test_messages, const char *context, int test_messages_len,
401 const char *file, int line)
402{
403 struct message *msg, *msg_start;
404 int ret_button = 0;
405 int ret_radio = 0;
406 BOOL ret_verification = FALSE;
407 HRESULT hr;
408 int i;
409
410 /* Allocate messages to test against, plus 2 implicit and 1 empty */
411 msg_start = msg = heap_alloc_zero(sizeof(*msg) * (test_messages_len + 3));
412
413 /* Always needed, thus made implicit */
415 for (i = 0; i < test_messages_len; i++)
417 /* Always needed, thus made implicit */
419
422
423 hr = pTaskDialogIndirect(info, &ret_button, &ret_radio, &ret_verification);
424 ok_(file, line)(hr == S_OK, "TaskDialogIndirect() failed, got %#x.\n", hr);
425
427 ok_(file, line)(ret_button == expect_button,
428 "Wrong button. Expected %d, got %d\n", expect_button, ret_button);
429 ok_(file, line)(ret_radio == expect_radio_button,
430 "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
431
432 heap_free(msg_start);
433}
434
435static const LONG_PTR test_ref_data = 123456;
436
439{
440 int msg_pos = sequences[TASKDIALOG_SEQ_INDEX]->count - 1; /* Skip implicit message */
441 const struct message_info *msg_send;
442 struct message msg;
443
444 ok(test_ref_data == ref_data, "Unexpected ref data %lu.\n", ref_data);
445
448
449 if (notification == TDN_DIALOG_CONSTRUCTED || notification == TDN_DESTROYED) /* Skip implicit messages */
450 return S_OK;
451
452 msg_send = current_message_info[msg_pos].send;
453 for(; msg_send && msg_send->message; msg_send++)
454 PostMessageW(hwnd, msg_send->message, msg_send->wparam, msg_send->lparam);
455
456 return current_message_info[msg_pos].callback_retval;
457}
458
459static void test_invalid_parameters(void)
460{
461 TASKDIALOGCONFIG info = { 0 };
462 HRESULT hr;
463
464 hr = pTaskDialogIndirect(NULL, NULL, NULL, NULL);
465 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
466
467 info.cbSize = 0;
468 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
469 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
470
471 info.cbSize = sizeof(TASKDIALOGCONFIG) - 1;
472 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
473 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
474
475 info.cbSize = sizeof(TASKDIALOGCONFIG) + 1;
476 hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
477 ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
478}
479
480static void test_callback(void)
481{
483
484 info.cbSize = sizeof(TASKDIALOGCONFIG);
485 info.pfCallback = taskdialog_callback_proc;
486 info.lpCallbackData = test_ref_data;
487
488 run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "Press VK_RETURN.");
489}
490
491static void test_buttons(void)
492{
494 static const DWORD command_link_flags[] = {0, TDF_USE_COMMAND_LINKS, TDF_USE_COMMAND_LINKS_NO_ICON};
495 TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
496 const WCHAR button_format[] = {'%','0','2','d',0};
497 /* Each button has two digits as title, plus null-terminator */
498 WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
499 int i;
500
501 info.cbSize = sizeof(TASKDIALOGCONFIG);
502 info.pfCallback = taskdialog_callback_proc;
503 info.lpCallbackData = test_ref_data;
504
505 /* Init custom buttons */
506 for (i = 0; i < TEST_NUM_BUTTONS; i++)
507 {
508 WCHAR *text = &button_titles[i * 3];
509 wsprintfW(text, button_format, i);
510
511 custom_buttons[i].pszButtonText = text;
512 custom_buttons[i].nButtonID = ID_START_BUTTON + i;
513 }
514 custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
515
516 /* Init radio buttons */
517 for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
518 {
519 WCHAR *text = &radio_button_titles[i * 3];
520 wsprintfW(text, button_format, i);
521
522 radio_buttons[i].pszButtonText = text;
523 radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
524 }
525 radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
526
527 /* Test nDefaultButton */
528
529 /* Test common buttons with invalid default ID */
530 info.nDefaultButton = 0; /* Should default to first created button */
533 run_test(&info, IDOK, 0, FALSE, msg_return_press_ok, "default button: unset default");
534 info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
536 run_test(&info, IDYES, 0, FALSE, msg_return_press_yes, "default button: unset default");
538 run_test(&info, IDNO, 0, FALSE, msg_return_press_no, "default button: unset default");
540 run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: unset default");
541 info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
542 run_test(&info, IDCANCEL, 0, FALSE, msg_return_press_cancel, "default button: unset default");
543
544 /* Custom buttons could be command links */
545 for (i = 0; i < ARRAY_SIZE(command_link_flags); i++)
546 {
547 info.dwFlags = command_link_flags[i];
548
549 /* Test with all common and custom buttons and invalid default ID */
550 info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
551 info.cButtons = TEST_NUM_BUTTONS;
552 info.pButtons = custom_buttons;
554 "default button: invalid default, with common buttons - 1");
555
556 info.nDefaultButton = -1; /* Should work despite button ID -1 */
557 run_test(&info, -1, 0, FALSE, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
558
559 info.nDefaultButton = -2; /* Should also default to first created button */
561 "default button: invalid default, with common buttons - 3");
562
563 /* Test with only custom buttons and invalid default ID */
564 info.dwCommonButtons = 0;
566 "default button: invalid default, no common buttons");
567
568 /* Test with common and custom buttons and valid default ID */
571 info.nDefaultButton = IDRETRY;
572 run_test(&info, IDRETRY, 0, FALSE, msg_return_press_retry, "default button: valid default - 1");
573
574 /* Test with common and custom buttons and valid default ID */
575 info.nDefaultButton = ID_START_BUTTON + 3;
576 run_test(&info, ID_START_BUTTON + 3, 0, FALSE, msg_return_press_custom4, "default button: valid default - 2");
577 }
578
579 /* Test radio buttons */
580 info.nDefaultButton = 0;
581 info.cButtons = 0;
582 info.pButtons = 0;
583 info.dwCommonButtons = TDCBF_OK_BUTTON;
584 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
585 info.pRadioButtons = radio_buttons;
586
587 /* Test default first radio button */
589 "default radio button: default first radio button");
590
591 /* Test default radio button */
592 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
594 "default radio button: default radio button");
595
596 /* Test default radio button with -2 */
597 info.nDefaultRadioButton = -2;
599 "default radio button: default radio button with id -2");
600
601 /* Test default radio button after clicking the first, messages still work even radio button is disabled */
602 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
604 "default radio button: radio button after clicking");
605
606 /* Test radio button after disabling and clicking the first */
607 info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
609 "default radio button: disable radio button before clicking");
610
611 /* 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 */
612 info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
615 "default radio button: no default radio flag");
616
617 /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
618 * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
619 info.nDefaultRadioButton = 0;
622 "default radio button: no default radio id and flag");
623
624 /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
625 * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
626 info.nDefaultRadioButton = 0xff;
629 "default radio button: no default flag, invalid id");
630
631 info.nDefaultRadioButton = 0;
634 "radio button: manually click radio button with negative id");
635
636 /* Test sending clicks to non-existent buttons. Notification of non-existent buttons will be sent */
637 info.cButtons = TEST_NUM_BUTTONS;
638 info.pButtons = custom_buttons;
639 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
640 info.pRadioButtons = radio_buttons;
641 info.dwCommonButtons = 0;
643 run_test(&info, ID_START_BUTTON + 99, 0, FALSE, msg_press_nonexistent_buttons, "sends click to non-existent buttons");
644
645 /* Non-existent button clicks sent by WM_COMMAND won't generate TDN_BUTTON_CLICKED except IDOK.
646 * And will get the first existent button identifier instead of IDOK */
648 "sends click to non-existent buttons with WM_COMMAND");
649
650 /* Non-existent radio button won't get notifications */
651 run_test(&info, IDOK, 0, FALSE, msg_press_nonexistent_radio_button, "sends click to non-existent radio buttons");
652}
653
654static void test_help(void)
655{
657
658 info.cbSize = sizeof(TASKDIALOGCONFIG);
659 info.pfCallback = taskdialog_callback_proc;
660 info.lpCallbackData = test_ref_data;
661 info.dwCommonButtons = TDCBF_OK_BUTTON;
662
663 run_test(&info, IDOK, 0, FALSE, msg_got_tdn_help, "send f1");
664}
665
667{
670};
671
674{
675 struct timer_notification_data *data = (struct timer_notification_data *)ref_data;
676
677 if (notification == TDN_TIMER)
678 {
679 DWORD elapsed_ms;
680 int delta;
681
682 elapsed_ms = (DWORD)wParam;
683
684 if (data->num_fired == 3)
685 ok(data->last_elapsed_ms > elapsed_ms, "Expected reference time update.\n");
686 else
687 {
688 delta = elapsed_ms - data->last_elapsed_ms;
689 ok(delta > 0, "Expected positive time tick difference.\n");
690 }
691 data->last_elapsed_ms = elapsed_ms;
692
693 if (data->num_fired == 3)
695
696 ++data->num_fired;
697 return data->num_fired == 3 ? S_FALSE : S_OK;
698 }
699
700 return S_OK;
701}
702
703static void test_timer(void)
704{
705 struct timer_notification_data data = { 0 };
706 TASKDIALOGCONFIG info = { 0 };
707
708 info.cbSize = sizeof(TASKDIALOGCONFIG);
710 info.lpCallbackData = (LONG_PTR)&data;
711 info.dwFlags = TDF_CALLBACK_TIMER;
712 info.dwCommonButtons = TDCBF_OK_BUTTON;
713
714 pTaskDialogIndirect(&info, NULL, NULL, NULL);
715}
716
718 LPARAM lParam, LONG_PTR ref_data)
719{
720 unsigned long ret;
721 LONG flags = (LONG)ref_data;
723 {
724 /* TDM_SET_PROGRESS_BAR_STATE */
726 ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
728 ok(ret == PBST_NORMAL, "Expect state: %d got state: %lx\n", PBST_NORMAL, ret);
730 /* Progress bar has fixme on handling PBM_SETSTATE message */
731 todo_wine ok(ret == PBST_PAUSED, "Expect state: %d got state: %lx\n", PBST_PAUSED, ret);
733 todo_wine ok(ret == PBST_ERROR, "Expect state: %d got state: %lx\n", PBST_ERROR, ret);
734
735 /* TDM_SET_PROGRESS_BAR_RANGE */
737 ok(ret == MAKELONG(0, 100), "Expect range:%x got:%lx\n", MAKELONG(0, 100), ret);
739 ok(ret == MAKELONG(0, 200), "Expect range:%x got:%lx\n", MAKELONG(0, 200), ret);
740
741 /* TDM_SET_PROGRESS_BAR_POS */
743 {
745 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
747 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
748 }
749 else
750 {
752 ok(ret == 0, "Expect position:%x got:%lx\n", 0, ret);
754 ok(ret == 1, "Expect position:%x got:%lx\n", 1, ret);
755 }
756
758 }
759
760 return S_OK;
761}
762
763static void test_progress_bar(void)
764{
766
767 info.cbSize = sizeof(TASKDIALOGCONFIG);
768 info.dwFlags = TDF_SHOW_PROGRESS_BAR;
770 info.lpCallbackData = (LONG_PTR)info.dwFlags;
771 info.dwCommonButtons = TDCBF_OK_BUTTON;
772 pTaskDialogIndirect(&info, NULL, NULL, NULL);
773
775 info.lpCallbackData = (LONG_PTR)info.dwFlags;
776 pTaskDialogIndirect(&info, NULL, NULL, NULL);
777
779 info.lpCallbackData = (LONG_PTR)info.dwFlags;
780 pTaskDialogIndirect(&info, NULL, NULL, NULL);
781}
782
783static void test_verification_box(void)
784{
786 WCHAR textW[] = {'t', 'e', 'x', 't', 0};
787
788 info.cbSize = sizeof(TASKDIALOGCONFIG);
789 info.pfCallback = taskdialog_callback_proc;
790 info.lpCallbackData = test_ref_data;
791 info.dwCommonButtons = TDCBF_OK_BUTTON;
792
793 /* TDF_VERIFICATION_FLAG_CHECKED works even if pszVerificationText is not set */
794 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
795
797 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
798
799 info.pszVerificationText = textW;
800 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_unchecked, "default verification box: unchecked");
801
803 run_test(&info, IDOK, 0, FALSE, msg_return_default_verification_checked, "default verification box: checked");
804
806 "default verification box: default checked and then unchecked");
807
808 info.dwFlags = 0;
810 "default verification box: default unchecked and then checked");
811}
812
813static void test_navigate_page(void)
814{
816 static const WCHAR textW[] = {'t', 'e', 'x', 't', 0};
817 static const WCHAR button_format[] = {'%', '0', '2', 'd', 0};
819 WCHAR radio_button_titles[TEST_NUM_BUTTONS * 3];
820 int i;
821
822 /* Init radio buttons */
823 for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
824 {
825 WCHAR *text = &radio_button_titles[i * 3];
826 wsprintfW(text, button_format, i);
827
828 radio_buttons[i].pszButtonText = text;
829 radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
830 }
831
832 info.cbSize = sizeof(TASKDIALOGCONFIG);
833 info.pfCallback = taskdialog_callback_proc;
834 info.lpCallbackData = test_ref_data;
835 info.dwCommonButtons = TDCBF_OK_BUTTON;
836 info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
837 info.pRadioButtons = radio_buttons;
838
842
844
845 /* TDM_NAVIGATE_PAGE doesn't check cbSize.
846 * And null taskconfig pointer crash applicatioin, thus doesn't check pointer either */
848 run_test(&info, IDOK, ID_START_RADIO_BUTTON, TRUE, msg_return_navigated_page, "navigate page: invalid taskconfig cbSize");
849}
850
851static void test_wm_close(void)
852{
854
855 info.cbSize = sizeof(TASKDIALOGCONFIG);
856 info.pfCallback = taskdialog_callback_proc;
857 info.lpCallbackData = test_ref_data;
858
859 /* WM_CLOSE can end the dialog only when a cancel button is present or dwFlags has TDF_ALLOW_DIALOG_CANCELLATION */
860 info.dwCommonButtons = TDCBF_OK_BUTTON;
861 run_test(&info, IDOK, 0, FALSE, msg_handle_wm_close_without_cancel_button, "send WM_CLOSE without cancel button");
862
864 run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with TDF_ALLOW_DIALOG_CANCELLATION");
865
866 info.dwFlags = 0;
867 info.dwCommonButtons = TDCBF_CANCEL_BUTTON;
868 run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with a cancel button");
869}
870
871START_TEST(taskdialog)
872{
873 ULONG_PTR ctx_cookie;
874 void *ptr_ordinal;
876 HANDLE hCtx;
877
878 if (!load_v6_module(&ctx_cookie, &hCtx))
879 return;
880
881 /* Check if task dialogs are available */
882 hinst = LoadLibraryA("comctl32.dll");
883
884 pTaskDialogIndirect = (void *)GetProcAddress(hinst, "TaskDialogIndirect");
885 if (!pTaskDialogIndirect)
886 {
887 win_skip("TaskDialogIndirect not exported by name\n");
888 unload_v6_module(ctx_cookie, hCtx);
889 return;
890 }
891
892 pTaskDialog = (void *)GetProcAddress(hinst, "TaskDialog");
893
894 ptr_ordinal = GetProcAddress(hinst, (const char *)344);
895 ok(pTaskDialog == ptr_ordinal, "got wrong pointer for ordinal 344, %p expected %p\n",
896 ptr_ordinal, pTaskDialog);
897
898 ptr_ordinal = GetProcAddress(hinst, (const char *)345);
899 ok(pTaskDialogIndirect == ptr_ordinal, "got wrong pointer for ordinal 345, %p expected %p\n",
900 ptr_ordinal, pTaskDialogIndirect);
901
903
906 test_buttons();
907 test_help();
908 test_timer();
913
914 unload_v6_module(ctx_cookie, hCtx);
915}
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
#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:24
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
@ sent
Definition: msg.h:34
static void init_msg_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:391
static void ok_sequence_(struct msg_sequence **seq, int sequence_index, const struct message *expected_list, const char *context, BOOL todo, const char *file, int line)
Definition: msg.h:167
static void flush_sequences(struct msg_sequence **seq, int n)
Definition: msg.h:97
#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:1799
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 UINT WPARAM wparam
Definition: combo.c:716
static UINT WPARAM LPARAM lparam
Definition: combo.c:716
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:330
static const struct message_info msg_return_press_retry[]
Definition: taskdialog.c:102
static void test_verification_box(void)
Definition: taskdialog.c:783
static const struct message_info msg_return_default_radio_button_clicking_disabled[]
Definition: taskdialog.c:198
static void test_progress_bar(void)
Definition: taskdialog.c:763
static HRESULT CALLBACK taskdialog_callback_proc_timer(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:672
static const struct message_info msg_got_tdn_help[]
Definition: taskdialog.c:142
static const struct message_info msg_select_negative_id_radio_button[]
Definition: taskdialog.c:222
static const struct message_info msg_press_nonexistent_buttons_with_command[]
Definition: taskdialog.c:274
static const struct message_info msg_send_click_ok[]
Definition: taskdialog.c:130
static const struct message_info msg_return_press_yes[]
Definition: taskdialog.c:81
#define NUM_MSG_SEQUENCES
Definition: taskdialog.c:38
static void test_navigate_page(void)
Definition: taskdialog.c:813
static const struct message_info msg_return_verification_unchecked[]
Definition: taskdialog.c:316
static const struct message_info msg_send_close_then_ok[]
Definition: taskdialog.c:371
static const struct message_info msg_return_press_negative_id_radio_button[]
Definition: taskdialog.c:228
static int int BOOL *static const WCHAR const WCHAR const WCHAR TASKDIALOG_COMMON_BUTTON_FLAGS
Definition: taskdialog.c:49
#define run_test(info, expect_button, expect_radio_button, verification_checked, seq, context)
Definition: taskdialog.c:395
static HRESULT CALLBACK taskdialog_callback_proc(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:437
static const struct message_info msg_return_press_no[]
Definition: taskdialog.c:88
static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[]
Definition: taskdialog.c:190
static const struct message_info msg_return_press_ok[]
Definition: taskdialog.c:74
static const struct message_info msg_return_default_verification_checked[]
Definition: taskdialog.c:303
static void test_buttons(void)
Definition: taskdialog.c:491
static const struct message_info msg_send_all_common_button_click_with_command[]
Definition: taskdialog.c:261
static void test_help(void)
Definition: taskdialog.c:654
static void test_invalid_parameters(void)
Definition: taskdialog.c:459
static const struct message_info msg_send_close[]
Definition: taskdialog.c:357
static const struct message_info msg_uncheck_verification[]
Definition: taskdialog.c:310
static const struct message_info msg_handle_wm_close_without_cancel_button[]
Definition: taskdialog.c:378
static const struct message_info msg_return_default_radio_button_2[]
Definition: taskdialog.c:159
static const struct message_info msg_return_no_default_radio_button_id_and_flag[]
Definition: taskdialog.c:215
static const struct message_info msg_send_f1[]
Definition: taskdialog.c:136
#define ID_START_BUTTON
Definition: taskdialog.c:45
static void test_wm_close(void)
Definition: taskdialog.c:851
static const struct message_info msg_handle_wm_close[]
Definition: taskdialog.c:363
#define TEST_NUM_RADIO_BUTTONS
Definition: taskdialog.c:42
static const struct message_info msg_return_first_radio_button[]
Definition: taskdialog.c:181
#define TEST_NUM_BUTTONS
Definition: taskdialog.c:41
static int int BOOL *static HINSTANCE
Definition: taskdialog.c:49
static const LONG_PTR test_ref_data
Definition: taskdialog.c:435
static const struct message_info msg_return_no_default_radio_button_flag[]
Definition: taskdialog.c:207
#define WM_TD_CALLBACK
Definition: taskdialog.c:36
static const struct message_info msg_send_navigate[]
Definition: taskdialog.c:340
static const struct message_info msg_return_default_verification_unchecked[]
Definition: taskdialog.c:296
static const struct message_info msg_send_return[]
Definition: taskdialog.c:67
static const struct message_info * current_message_info
Definition: taskdialog.c:64
static const struct message_info msg_return_press_custom10[]
Definition: taskdialog.c:123
static const struct message_info msg_send_nonexistent_radio_button_click[]
Definition: taskdialog.c:282
static TASKDIALOGCONFIG navigated_info
Definition: taskdialog.c:338
static const struct message_info msg_return_default_radio_button_3[]
Definition: taskdialog.c:167
static const struct message_info msg_press_nonexistent_buttons[]
Definition: taskdialog.c:248
static void test_callback(void)
Definition: taskdialog.c:480
static const struct message_info msg_return_default_radio_button_1[]
Definition: taskdialog.c:151
static const struct message_info msg_check_verification[]
Definition: taskdialog.c:324
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:52
static const struct message_info msg_press_nonexistent_radio_button[]
Definition: taskdialog.c:289
static const struct message_info msg_return_navigated_page[]
Definition: taskdialog.c:346
#define TASKDIALOG_SEQ_INDEX
Definition: taskdialog.c:39
static const struct message_info msg_select_first_radio_button[]
Definition: taskdialog.c:175
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:399
static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
Definition: taskdialog.c:385
static const struct message_info msg_send_all_common_button_click[]
Definition: taskdialog.c:236
static const struct message_info msg_return_press_custom1[]
Definition: taskdialog.c:109
static void test_timer(void)
Definition: taskdialog.c:703
static const struct message_info msg_return_press_cancel[]
Definition: taskdialog.c:95
#define ID_START_RADIO_BUTTON
Definition: taskdialog.c:46
static const struct message_info msg_return_press_custom4[]
Definition: taskdialog.c:116
static HRESULT CALLBACK taskdialog_callback_proc_progress_bar(HWND hwnd, UINT notification, WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
Definition: taskdialog.c:717
static const WCHAR textW[]
Definition: itemdlg.c:1559
#define todo_wine
Definition: custom.c:79
#define add_message(msg)
Definition: msg.c:2109
#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:5112
@ TDF_ALLOW_DIALOG_CANCELLATION
Definition: commctrl.h:5101
@ TDF_CALLBACK_TIMER
Definition: commctrl.h:5109
@ TDF_SHOW_PROGRESS_BAR
Definition: commctrl.h:5107
@ TDF_USE_COMMAND_LINKS
Definition: commctrl.h:5102
@ TDF_USE_COMMAND_LINKS_NO_ICON
Definition: commctrl.h:5103
@ TDF_SHOW_MARQUEE_PROGRESS_BAR
Definition: commctrl.h:5108
@ TDF_VERIFICATION_FLAG_CHECKED
Definition: commctrl.h:5106
@ TDCBF_YES_BUTTON
Definition: commctrl.h:5175
@ TDCBF_OK_BUTTON
Definition: commctrl.h:5174
@ TDCBF_CLOSE_BUTTON
Definition: commctrl.h:5179
@ TDCBF_NO_BUTTON
Definition: commctrl.h:5176
@ TDCBF_RETRY_BUTTON
Definition: commctrl.h:5178
@ TDCBF_CANCEL_BUTTON
Definition: commctrl.h:5177
@ TDM_SET_PROGRESS_BAR_RANGE
Definition: commctrl.h:5125
@ TDM_CLICK_RADIO_BUTTON
Definition: commctrl.h:5129
@ TDM_ENABLE_RADIO_BUTTON
Definition: commctrl.h:5131
@ TDM_CLICK_BUTTON
Definition: commctrl.h:5122
@ TDM_SET_PROGRESS_BAR_POS
Definition: commctrl.h:5126
@ TDM_CLICK_VERIFICATION
Definition: commctrl.h:5132
@ TDM_SET_PROGRESS_BAR_STATE
Definition: commctrl.h:5124
@ TDM_NAVIGATE_PAGE
Definition: commctrl.h:5121
@ TDN_VERIFICATION_CLICKED
Definition: commctrl.h:5148
@ TDN_RADIO_BUTTON_CLICKED
Definition: commctrl.h:5146
@ TDN_DIALOG_CONSTRUCTED
Definition: commctrl.h:5147
@ TDN_TIMER
Definition: commctrl.h:5144
@ TDN_DESTROYED
Definition: commctrl.h:5145
@ TDN_NAVIGATED
Definition: commctrl.h:5141
@ TDN_CREATED
Definition: commctrl.h:5140
@ TDN_HELP
Definition: commctrl.h:5149
@ TDN_BUTTON_CLICKED
Definition: commctrl.h:5142
#define win_skip
Definition: test.h:160
HRESULT hr
Definition: shlfolder.c:183
PCWSTR pszVerificationText
Definition: commctrl.h:5218
TASKDIALOG_FLAGS dwFlags
Definition: commctrl.h:5202
PCWSTR pszButtonText
Definition: commctrl.h:5186
Definition: http.c:7252
Definition: fci.c:127
Definition: parser.c:49
UINT message
Definition: taskdialog.c:56
HRESULT callback_retval
Definition: taskdialog.c:60
WPARAM wparam
Definition: taskdialog.c:57
const struct message_info * send
Definition: taskdialog.c:61
LPARAM lparam
Definition: taskdialog.c:58
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:71
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
Definition: v6util.h:63
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:1611
#define MAKELPARAM(l, h)
Definition: winuser.h:3998
#define IDCANCEL
Definition: winuser.h:825
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:1730
#define IDOK
Definition: winuser.h:824
#define VK_RETURN
Definition: winuser.h:2191
#define IDNO
Definition: winuser.h:830
#define BN_CLICKED
Definition: winuser.h:1915
#define WM_KEYDOWN
Definition: winuser.h:1705
#define IDYES
Definition: winuser.h:829
#define IDRETRY
Definition: winuser.h:827
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
__wchar_t WCHAR
Definition: xmlstorage.h:180