From: Zhiyi Zhang Subject: [PATCH 2/3] comctl32/taskdialog: Add support for radio buttons. Message-Id: <1ccd4be6-b225-0ed4-1523-3cdeccd12d5d@codeweavers.com> Date: Sun, 17 Jun 2018 16:17:09 +0800 Signed-off-by: Zhiyi Zhang --- dlls/comctl32/taskdialog.c | 130 ++++++++++++++++++++++- dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++---- 2 files changed, 281 insertions(+), 21 deletions(-) diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index 33fb578910..c3c5fa0420 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -58,6 +58,8 @@ struct taskdialog_info HWND main_instruction; HWND content; HWND progress_bar; + HWND *radio_buttons; + INT radio_button_count; HWND *buttons; INT button_count; HWND default_button; @@ -69,6 +71,7 @@ struct taskdialog_info LONG h_spacing; LONG v_spacing; } m; + INT selected_radio_id; }; struct button_layout_info @@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info, if (hwnd) EnableWindow(hwnd, enable); } +static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable) +{ + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id); + if (hwnd) EnableWindow(hwnd, enable); +} + +static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id) +{ + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id); + if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0); +} + static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam) { const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; @@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif : S_OK; } -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id) +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, unsigned long command_id) { + HWND radio_button; + + radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id); + if (radio_button) + { + dialog_info->selected_radio_id = command_id; + taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0); + return; + } + if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK) EndDialog(dialog_info->hwnd, command_id); } @@ -260,6 +285,40 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND ReleaseDC(hwnd, hdc); } +static void taskdialog_get_checkbox_height(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size) +{ + DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK; + HFONT hfont, old_hfont; + HDC hdc; + RECT rect = {0}; + WCHAR text[1024]; + INT text_length; + LONG text_offset, checkbox_width, checkbox_height; + + hdc = GetDC(hwnd); + hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0); + old_hfont = SelectObject(hdc, hfont); + + checkbox_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1; + checkbox_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1; + GetCharWidthW(hdc, '0', '0', &text_offset); + text_offset /= 2; + + if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT) + style |= DT_RIGHT | DT_RTLREADING; + else + style |= DT_LEFT; + + rect.right = max_width - checkbox_width - text_offset; + text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text)); + size->cy = DrawTextW(hdc, text, text_length, &rect, style); + size->cx = min(max_width - checkbox_width - text_offset, rect.right - rect.left); + size->cx += checkbox_width + text_offset; + size->cy = max(size->cy, checkbox_height); + if (old_hfont) SelectObject(hdc, old_hfont); + ReleaseDC(hwnd, hdc); +} + static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon) { if (icon == TD_WARNING_ICON) @@ -300,6 +359,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element } } +static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info) +{ + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; + HWND default_button; + INT id; + + if (!dialog_info->radio_button_count) return; + + default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, + taskconfig->nDefaultRadioButton); + + if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON)) + default_button = dialog_info->radio_buttons[0]; + + if (default_button) + { + SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0); + id = GetWindowLongW(default_button, GWLP_ID); + taskdialog_on_button_click(dialog_info, id); + } +} + static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info) { if (!dialog_info->taskconfig->u.hMainIcon) return; @@ -363,6 +444,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info) CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL); } +static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info) +{ + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; + static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP; + WCHAR *textW; + INT i; + + if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return; + + dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons)); + if (!dialog_info->radio_buttons) return; + + dialog_info->radio_button_count = taskconfig->cRadioButtons; + for (i = 0; i < dialog_info->radio_button_count; i++) + { + textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText); + dialog_info->radio_buttons[i] = + CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd, + (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL); + SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0); + Free(textW); + } +} + static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text, BOOL custom_button) { @@ -487,6 +592,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info) dialog_height = y + size.cy; } + /* Radio buttons */ + for (i = 0; i < dialog_info->radio_button_count; i++) + { + x = main_icon_right + h_spacing; + y = dialog_height; + taskdialog_get_checkbox_height(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size); + size.cx = dialog_width - x - h_spacing; + SetWindowPos(dialog_info->radio_buttons[i], 0, x, y, size.cx, size.cy, SWP_NOZORDER); + dialog_height = y + size.cy; + } + dialog_height = max(dialog_height, main_icon_bottom); /* Common and custom buttons */ @@ -621,6 +737,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd) taskdialog_add_main_instruction(dialog_info); taskdialog_add_content(dialog_info); taskdialog_add_progress_bar(dialog_info); + taskdialog_add_radio_buttons(dialog_info); taskdialog_add_buttons(dialog_info); /* Set default button */ @@ -638,6 +755,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info) if (dialog_info->font) DeleteObject(dialog_info->font); if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font); if (dialog_info->buttons) Free(dialog_info->buttons); + if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons); } static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -689,6 +807,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case TDM_SET_PROGRESS_BAR_MARQUEE: SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam); break; + case TDM_CLICK_RADIO_BUTTON: + taskdialog_click_radio_button(dialog_info, wParam); + break; + case TDM_ENABLE_RADIO_BUTTON: + taskdialog_enable_radio_button(dialog_info, wParam, lParam); + break; case WM_INITDIALOG: dialog_info = (struct taskdialog_info *)lParam; @@ -697,6 +821,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR SetPropW(hwnd, taskdialog_info_propnameW, dialog_info); taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0); taskdialog_notify(dialog_info, TDN_CREATED, 0, 0); + /* Default radio button click notification sent after TDN_CREATED */ + taskdialog_check_default_radio_buttons(dialog_info); return FALSE; case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) @@ -762,7 +888,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto Free(template); if (button) *button = ret; - if (radio_button) *radio_button = taskconfig->nDefaultButton; + if (radio_button) *radio_button = dialog_info.selected_radio_id; if (verification_flag_checked) *verification_flag_checked = TRUE; return S_OK; diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index e91a878876..2cda04081f 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -35,9 +35,11 @@ #define TASKDIALOG_SEQ_INDEX 0 #define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */ +#define TEST_NUM_RADIO_BUTTONS 3 #define ID_START 20 /* Lower IDs might be used by the system */ #define ID_START_BUTTON (ID_START + 0) +#define ID_START_RADIO_BUTTON (ID_START + 20) static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *); static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *, @@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] = { 0 } }; +/* Three radio buttons */ +static const struct message_info msg_return_default_radio_button_1[] = +{ + { TDN_CREATED, 0, 0, S_OK, NULL }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_return_default_radio_button_2[] = +{ + { TDN_CREATED, 0, 0, S_OK, NULL }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_return_default_radio_button_3[] = +{ + { TDN_CREATED, 0, 0, S_OK, NULL }, + { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_select_first_radio_button[] = +{ + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 }, + { 0 } +}; + +static const struct message_info msg_return_first_radio_button[] = +{ + { TDN_CREATED, 0, 0, S_OK, NULL }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] = +{ + { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 }, + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 }, + { TDM_CLICK_BUTTON, IDOK, 0 }, + { 0 } +}; + +static const struct message_info msg_return_default_radio_button_clicking_disabled[] = +{ + { TDN_CREATED, 0, 0, S_OK, NULL }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_return_no_default_radio_button_flag[] = +{ + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok }, + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + +static const struct message_info msg_return_no_default_radio_button_id_and_flag[] = +{ + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok }, + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL }, + { 0 } +}; + static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg) { msg->message = WM_TD_CALLBACK; @@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct msg->stage = 0; } -#define run_test(info, expect_button, seq, context) \ - run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__) +#define run_test(info, expect_button, expect_radio_button, seq, context) \ + run_test_(info, expect_button, expect_radio_button, seq, context, \ + ARRAY_SIZE(seq) - 1, __FILE__, __LINE__) -static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages, - const char *context, int test_messages_len, const char *file, int line) +static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button, + const struct message_info *test_messages, const char *context, int test_messages_len, + const char *file, int line) { struct message *msg, *msg_start; int ret_button = 0; @@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line); ok_(file, line)(ret_button == expect_button, "Wrong button. Expected %d, got %d\n", expect_button, ret_button); + ok_(file, line)(ret_radio == expect_radio_button, + "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio); heap_free(msg_start); } @@ -239,16 +317,17 @@ static void test_callback(void) info.pfCallback = taskdialog_callback_proc; info.lpCallbackData = test_ref_data; - run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN."); + run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN."); } static void test_buttons(void) { TASKDIALOGCONFIG info = {0}; - TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS]; + TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS]; const WCHAR button_format[] = {'%','0','2','d',0}; - WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */ + /* Each button has two digits as title, plus null-terminator */ + WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3]; int i; info.cbSize = sizeof(TASKDIALOGCONFIG); @@ -266,48 +345,103 @@ static void test_buttons(void) } custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1; + /* Init radio buttons */ + for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++) + { + WCHAR *text = &radio_button_titles[i * 3]; + wsprintfW(text, button_format, i); + + radio_buttons[i].pszButtonText = text; + radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i; + } + radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2; + /* Test nDefaultButton */ /* Test common buttons with invalid default ID */ info.nDefaultButton = 0; /* Should default to first created button */ info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON; - run_test(&info, IDOK, msg_return_press_ok, "default button: unset default"); + run_test(&info, IDOK, 0, msg_return_press_ok, "default button: unset default"); info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON; - run_test(&info, IDYES, msg_return_press_yes, "default button: unset default"); + run_test(&info, IDYES, 0, msg_return_press_yes, "default button: unset default"); info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON; - run_test(&info, IDNO, msg_return_press_no, "default button: unset default"); + run_test(&info, IDNO, 0, msg_return_press_no, "default button: unset default"); info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON; - run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default"); + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: unset default"); info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON; - run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default"); + run_test(&info, IDCANCEL, 0, msg_return_press_cancel, "default button: unset default"); /* Test with all common and custom buttons and invalid default ID */ info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */ info.cButtons = TEST_NUM_BUTTONS; info.pButtons = custom_buttons; - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1"); + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 1"); info.nDefaultButton = -1; /* Should work despite button ID -1 */ - run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2"); + run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2"); info.nDefaultButton = -2; /* Should also default to first created button */ - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3"); + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 3"); /* Test with only custom buttons and invalid default ID */ info.dwCommonButtons = 0; - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons"); + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, no common buttons"); /* Test with common and custom buttons and valid default ID */ info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON; info.nDefaultButton = IDRETRY; - run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1"); + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1"); /* Test with common and custom buttons and valid default ID */ info.nDefaultButton = ID_START_BUTTON + 3; - run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2"); + run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2"); + + /* Test radio buttons */ + info.nDefaultButton = 0; + info.cButtons = 0; + info.pButtons = 0; + info.dwCommonButtons = TDCBF_OK_BUTTON; + info.cRadioButtons = TEST_NUM_RADIO_BUTTONS; + info.pRadioButtons = radio_buttons; + + /* Test default first radio button */ + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button"); + + /* Test default radio button */ + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1; + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button"); + + /* Test default radio button with -2 */ + info.nDefaultRadioButton = -2; + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2"); + + /* Test default radio button after clicking the first, messages still work even radio button is disabled */ + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1; + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking"); + + /* Test radio button after disabling and clicking the first */ + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1; + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking"); + + /* 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 */ + info.nDefaultRadioButton = ID_START_RADIO_BUTTON; + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag"); + + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0. + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */ + info.nDefaultRadioButton = 0; + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag"); + + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid. + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */ + info.nDefaultRadioButton = 0xff; + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id"); } static void test_help(void) @@ -319,7 +453,7 @@ static void test_help(void) info.lpCallbackData = test_ref_data; info.dwCommonButtons = TDCBF_OK_BUTTON; - run_test(&info, IDOK, msg_got_tdn_help, "send f1"); + run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1"); } struct timer_notification_data -- 2.17.1