From d2fb18166d8595d53d45f7d08d535bd3af67c296 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Thu, 19 Jul 2018 11:03:51 +0800 Subject: [PATCH] comctl32/taskdialog: Use window handle to identify control internally. Use window handle to identify control when handling BN_CLICKED notification to support buttons with id larger than 0xFFFF. Signed-off-by: Zhiyi Zhang Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/comctl32/taskdialog.c | 20 ++++++++++++++------ dlls/comctl32/tests/taskdialog.c | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c index 856a0b39bfd..1c32a4b3fa3 100644 --- a/dlls/comctl32/taskdialog.c +++ b/dlls/comctl32/taskdialog.c @@ -82,6 +82,8 @@ struct button_layout_info LONG line; }; +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, HWND hwnd); + static void taskdialog_du_to_px(struct taskdialog_info *dialog_info, LONG *width, LONG *height) { if (width) *width = MulDiv(*width, dialog_info->m.x_baseunit, 4); @@ -191,6 +193,13 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info, if (hwnd) EnableWindow(hwnd, enable); } +static void taskdialog_click_button(struct taskdialog_info *dialog_info, INT id) +{ + HWND hwnd = taskdialog_find_button(dialog_info->command_links, dialog_info->command_link_count, id); + if (!hwnd) hwnd = taskdialog_find_button(dialog_info->buttons, dialog_info->button_count, id); + if (hwnd) taskdialog_on_button_click(dialog_info, hwnd); +} + 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); @@ -211,8 +220,9 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif : S_OK; } -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, INT command_id) +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, HWND hwnd) { + INT command_id = GetWindowLongW(hwnd, GWLP_ID); HWND radio_button; radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id); @@ -389,7 +399,6 @@ static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialo { const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig; HWND default_button; - INT id; if (!dialog_info->radio_button_count) return; @@ -402,8 +411,7 @@ static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialo if (default_button) { SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0); - id = GetWindowLongW(default_button, GWLP_ID); - taskdialog_on_button_click(dialog_info, id); + taskdialog_on_button_click(dialog_info, default_button); } } @@ -844,7 +852,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR switch (msg) { case TDM_CLICK_BUTTON: - taskdialog_on_button_click(dialog_info, LOWORD(wParam)); + taskdialog_click_button(dialog_info, wParam); break; case TDM_ENABLE_BUTTON: taskdialog_enable_button(dialog_info, wParam, lParam); @@ -899,7 +907,7 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR case WM_COMMAND: if (HIWORD(wParam) == BN_CLICKED) { - taskdialog_on_button_click(dialog_info, LOWORD(wParam)); + taskdialog_on_button_click(dialog_info, (HWND)lParam); break; } return FALSE; diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index 33d3757308f..7fb8f3dcfcd 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -215,6 +215,20 @@ static const struct message_info msg_return_no_default_radio_button_id_and_flag[ { 0 } }; +static const struct message_info msg_select_negative_id_radio_button[] = +{ + { TDM_CLICK_RADIO_BUTTON, -2, 0 }, + { 0 } +}; + +static const struct message_info msg_return_press_negative_id_radio_button[] = +{ + { TDN_CREATED, 0, 0, S_OK, msg_select_negative_id_radio_button }, + { TDN_RADIO_BUTTON_CLICKED, -2, 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; @@ -451,6 +465,11 @@ static void test_buttons(void) 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"); + + info.nDefaultRadioButton = 0; + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON; + run_test(&info, IDOK, -2, msg_return_press_negative_id_radio_button, + "radio button: manually click radio button with negative id"); } static void test_help(void)