[v3 04/12] comctl32: Extend TaskDialog, add simple callback and tests

Fabian Maurer dark.shadow4 at web.de
Fri Mar 10 12:21:56 CST 2017


v3: Rewrite to implement Nikolay Sivov's suggestions

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/comctl32/taskdialog.c       | 29 +++++++++++++++++++++++--
 dlls/comctl32/tests/taskdialog.c | 46 +++++++++++++++++++++++++++++++++-------
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 2166ce1898..c5f410716e 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -147,17 +147,41 @@ static void controls_add(struct list *controls, WORD id, const WCHAR *class, con
     list_add_tail(controls, &data->entry);
 }
 
+/* FIXME: Make thread safe */
+static const TASKDIALOGCONFIG *task_config = 0;
+static HRESULT callback(HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam)
+{
+    if(task_config->pfCallback)
+        return task_config->pfCallback(hwnd, uNotification, wParam, lParam, task_config->lpCallbackData);
+    return S_OK;
+}
+
 static INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
+    HRESULT ret_callback;
+
     switch (uMsg)
     {
+        case WM_INITDIALOG:
+            callback(hwndDlg, TDN_DIALOG_CONSTRUCTED, 0, 0);
+            callback(hwndDlg, TDN_CREATED, 0, 0);
+            return TRUE;
         case WM_COMMAND:
-            if(HIWORD(wParam) == BN_CLICKED && LOWORD(wParam) == IDOK)
+            if(HIWORD(wParam) == BN_CLICKED)
             {
-                EndDialog(hwndDlg, 0);
+                WORD command_id = LOWORD(wParam);
+
+                ret_callback = callback(hwndDlg, TDN_BUTTON_CLICKED, command_id, 0);
+                if(ret_callback == S_OK) /* FIXME */
+                {
+                    EndDialog(hwndDlg, command_id);
+                }
                 return TRUE;
             }
             break;
+        case WM_DESTROY:
+            callback(hwndDlg, TDN_DESTROYED, 0, 0);
+            break;
     }
     return FALSE;
 }
@@ -179,6 +203,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
     if (!pTaskConfig || pTaskConfig->cbSize != sizeof(TASKDIALOGCONFIG))
         return E_INVALIDARG;
 
+    task_config = pTaskConfig;
     list_init(&controls);
 
     /* Start creating controls */
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index c1336bf710..6b8419045e 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -24,14 +24,47 @@
 #include "winuser.h"
 #include "commctrl.h"
 
+#include "wine/list.h"
 #include "wine/test.h"
 #include "v6util.h"
+#include "msg.h"
+
+#define WM_TD_CALLBACK (WM_APP) /* Custom dummy message to wrap callback notifications */
+
+#define NUM_MSG_SEQUENCES     1
+#define TASKDIALOG_SEQ_INDEX  0
 
 static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
 
+static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
+
+/* Message lists to test against */
+
+static const struct message mes_simple_show[] = {
+    { WM_TD_CALLBACK, sent|id, 0, 0, TDN_DIALOG_CONSTRUCTED },
+    { WM_TD_CALLBACK, sent|id, 0, 0, TDN_CREATED },
+    { WM_TD_CALLBACK, sent|id|wparam, IDOK, 0, TDN_BUTTON_CLICKED },
+    { WM_TD_CALLBACK, sent|id, 0, 0, TDN_DESTROYED },
+    { 0 }
+};
+
+
+static LONG_PTR backup_ref_data; /* Copy of dwRefData to test against */
+
 static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, UINT uNotification, WPARAM wParam,
                                                LPARAM lParam, LONG_PTR dwRefData)
 {
+    struct message msg;
+
+    msg.message = WM_TD_CALLBACK;
+    msg.flags   = sent|wparam|lparam|id;
+    msg.wParam  = wParam;
+    msg.lParam  = lParam;
+    msg.id      = uNotification;
+    add_message(sequences, TASKDIALOG_SEQ_INDEX, &msg);
+
+    ok(backup_ref_data == dwRefData, "dwRefData is wrong, expected %lu, got %lu\n", backup_ref_data, dwRefData);
+
     if(uNotification == TDN_CREATED)
     {
         PostMessageW(hwnd, WM_KEYDOWN, VK_RETURN, 0);
@@ -52,15 +85,11 @@ static void test_TaskDialogIndirect(void)
 
     info.cbSize = sizeof(TASKDIALOGCONFIG);
     info.pfCallback = TaskDialogCallbackProc;
+    info.lpCallbackData = backup_ref_data = 0x12345678; /* Set data for callback tests */
 
-    /* Skip this test on wine, because it doesn't really fail,
-     * it would displays a dialog that doesn't automatically close */
-    if (strcmp(winetest_platform, "wine"))
-    {
-        ret = pTaskDialogIndirect(&info, NULL, NULL, NULL);
-        ok(ret == S_OK, "Expected S_OK, got %x\n", ret);
-    }
-
+    ret = pTaskDialogIndirect(&info, NULL, NULL, NULL);
+    ok(ret == S_OK, "Expected S_OK, got %x\n", ret);
+    ok_sequence(sequences, TASKDIALOG_SEQ_INDEX, mes_simple_show, "Simple test with parameters null", FALSE);
 }
 
 START_TEST(taskdialog)
@@ -87,6 +116,7 @@ START_TEST(taskdialog)
     ok(pTaskDialogIndirect == ptr_ordinal, "got wrong pointer for ordinal 345, %p expected %p\n",
                                             ptr_ordinal, pTaskDialogIndirect);
 
+    init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
     test_TaskDialogIndirect();
 
     unload_v6_module(ctx_cookie, hCtx);
-- 
2.12.0




More information about the wine-patches mailing list