[PATCH 2/3] comctl32/taskdialog: Add support for TDF_ALLOW_DIALOG_CANCELLATION.

Zhiyi Zhang zzhang at codeweavers.com
Mon Oct 29 02:25:21 CDT 2018


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/comctl32/taskdialog.c       | 17 +++++++++++
 dlls/comctl32/tests/taskdialog.c | 49 ++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 9bfdef939e..0adfb2f32c 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -84,6 +84,7 @@ struct taskdialog_info
     INT selected_radio_id;
     BOOL verification_checked;
     BOOL expanded;
+    BOOL has_cancel;
     WCHAR *expanded_text;
     WCHAR *collapsed_text;
 };
@@ -1197,6 +1198,13 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
     id = GetWindowLongW(dialog_info->default_button, GWLP_ID);
     SendMessageW(dialog_info->hwnd, DM_SETDEFID, id, 0);
 
+    dialog_info->has_cancel =
+        (taskconfig->dwFlags & TDF_ALLOW_DIALOG_CANCELLATION)
+        || taskdialog_find_button(dialog_info->command_links, dialog_info->command_link_count, IDCANCEL)
+        || taskdialog_find_button(dialog_info->buttons, dialog_info->button_count, IDCANCEL);
+
+    if (!dialog_info->has_cancel) DeleteMenu(GetSystemMenu(hwnd, FALSE), SC_CLOSE, MF_BYCOMMAND);
+
     taskdialog_layout(dialog_info);
 }
 
@@ -1369,6 +1377,15 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
             RemovePropW(hwnd, taskdialog_info_propnameW);
             taskdialog_destroy(dialog_info);
             break;
+        case WM_CLOSE:
+            if (dialog_info->has_cancel)
+            {
+                if(taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, IDCANCEL, 0) == S_OK)
+                    EndDialog(hwnd, IDCANCEL);
+                SetWindowLongPtrW(hwnd, DWLP_MSGRESULT, 0);
+                break;
+            }
+            return FALSE;
         default:
             return FALSE;
     }
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index 093671c30f..8f4c97b750 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -290,6 +290,34 @@ static const struct message_info msg_return_navigated_page[] =
     { 0 }
 };
 
+static const struct message_info msg_send_close[] =
+{
+    { WM_CLOSE, 0, 0, 0},
+    { 0 }
+};
+
+static const struct message_info msg_handle_wm_close[] =
+{
+    { TDN_CREATED, 0, 0, S_OK, msg_send_close },
+    { TDN_BUTTON_CLICKED, IDCANCEL, 0, S_FALSE, msg_send_close },
+    { TDN_BUTTON_CLICKED, IDCANCEL, 0, S_OK, NULL },
+    { 0 }
+};
+
+static const struct message_info msg_send_close_then_ok[] =
+{
+    { WM_CLOSE, 0, 0, 0},
+    { TDM_CLICK_BUTTON, IDOK, 0 },
+    { 0 }
+};
+
+static const struct message_info msg_handle_wm_close_without_cancel_button[] =
+{
+    { TDN_CREATED, 0, 0, S_OK, msg_send_close_then_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;
@@ -739,6 +767,26 @@ static void test_navigate_page(void)
     run_test(&info, IDOK, ID_START_RADIO_BUTTON, TRUE, msg_return_navigated_page, "navigate page: invalid taskconfig cbSize");
 }
 
+static void test_wm_close(void)
+{
+    TASKDIALOGCONFIG info = {0};
+
+    info.cbSize = sizeof(TASKDIALOGCONFIG);
+    info.pfCallback = taskdialog_callback_proc;
+    info.lpCallbackData = test_ref_data;
+
+    /* WM_CLOSE can end the dialog only when a cancel button is present or dwFlags has TDF_ALLOW_DIALOG_CANCELLATION */
+    info.dwCommonButtons = TDCBF_OK_BUTTON;
+    run_test(&info, IDOK, 0, FALSE, msg_handle_wm_close_without_cancel_button, "send WM_CLOSE without cancel button");
+
+    info.dwFlags = TDF_ALLOW_DIALOG_CANCELLATION;
+    run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with TDF_ALLOW_DIALOG_CANCELLATION");
+
+    info.dwFlags = 0;
+    info.dwCommonButtons = TDCBF_CANCEL_BUTTON;
+    run_test(&info, IDCANCEL, 0, FALSE, msg_handle_wm_close, "send WM_CLOSE with a cancel button");
+}
+
 START_TEST(taskdialog)
 {
     ULONG_PTR ctx_cookie;
@@ -780,6 +828,7 @@ START_TEST(taskdialog)
     test_progress_bar();
     test_verification_box();
     test_navigate_page();
+    test_wm_close();
 
     unload_v6_module(ctx_cookie, hCtx);
 }
-- 
2.19.1





More information about the wine-devel mailing list