[PATCH 04/18] comctl32: Extend TaskDialog, add simple callback and tests

Fabian Maurer dark.shadow4 at web.de
Sat Feb 25 10:01:32 CST 2017


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

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index d31e7d0b95..771eee7619 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -163,14 +163,37 @@ 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);
+
+                    callback(hwndDlg, TDN_DESTROYED, 0, 0);
+                }
                 return TRUE;
             }
             break;
@@ -196,6 +219,8 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *pTaskConfig, int *pnBu
     if (!pTaskConfig || pTaskConfig->cbSize != sizeof(TASKDIALOGCONFIG))
         return E_INVALIDARG;
 
+    task_config = pTaskConfig;
+
     controls_init(&controls);
 
     /* Start creating controls */
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index c1336bf710..f18afeb440 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -24,14 +24,115 @@
 #include "winuser.h"
 #include "commctrl.h"
 
+#include "wine/list.h"
 #include "wine/test.h"
 #include "v6util.h"
 
 static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
 
+/* For message checking we use a simplified version from the code used for user32 messages */
+
+#define TDN_NO_MORE_MESSAGES 0xffffffff
+
+typedef struct
+{
+   UINT   msg;
+   WPARAM wparam;
+   LPARAM lparam;
+
+   struct list entry;
+}message_data;
+
+static struct list messages = LIST_INIT(messages);
+
+/* Message lists to test against */
+
+static const message_data mes_simple_show[] = {
+    { TDN_DIALOG_CONSTRUCTED, 0, 0 },
+    { TDN_CREATED, 0, 0 },
+    { TDN_BUTTON_CLICKED, IDOK, 0 },
+    { TDN_DESTROYED, 0, 0 },
+    { TDN_NO_MORE_MESSAGES }
+};
+
+/* Functions handling message processing */
+
+static void message_add(UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    message_data *data = HeapAlloc(GetProcessHeap(), 0, sizeof(message_data));
+
+    data->msg = msg;
+    data->wparam = wparam;
+    data->lparam = lparam;
+
+    list_add_tail(&messages, &data->entry);
+}
+
+#define ok_sequence(exp ) \
+        ok_sequence_((exp), __FILE__, __LINE__)
+
+static void ok_sequence_(const message_data *expected_list, const char *file, int line)
+{
+    message_data *message;
+    BOOL dump = FALSE;
+    UINT count;
+
+    count = 0;
+    LIST_FOR_EACH_ENTRY(message, &messages, message_data, entry)
+    {
+        ok_(file, line)(expected_list->msg != TDN_NO_MORE_MESSAGES, "Got more messages than expected!\n");
+        if(expected_list->msg != TDN_NO_MORE_MESSAGES)
+        {
+            ok_(file, line)(expected_list->msg == message->msg,
+                    "  %u: Wrong message, expected %u, got %u\n", count, expected_list->msg, message->msg);
+            if(expected_list->msg == message->msg)
+            {
+                ok_(file, line)(expected_list->wparam == message->wparam,
+                    "  %u: Wrong wparam, expected %lu, got %lu\n", count, expected_list->wparam, message->wparam);
+                ok_(file, line)(expected_list->lparam == message->lparam,
+                    "  %u: Wrong lparam, expected %lu, got %lu\n", count, expected_list->lparam, message->lparam);
+            }
+
+            if(expected_list->msg    != message->msg)    dump = TRUE;
+            if(expected_list->wparam != message->wparam) dump = TRUE;
+            if(expected_list->lparam != message->lparam) dump = TRUE;
+
+            expected_list++;
+        }
+        else
+            dump = TRUE;
+
+        count++;
+    }
+
+    ok_(file, line)(expected_list->msg == TDN_NO_MORE_MESSAGES, "Got fewer messages than expected!\n");
+    if(expected_list->msg != TDN_NO_MORE_MESSAGES)
+        dump = TRUE;
+
+    /* Remove messages and reset list */
+    count = 0;
+    LIST_FOR_EACH_ENTRY(message, &messages, message_data, entry)
+    {
+        if(dump)
+            trace_(file, line) ("  %u: Msg: %u, wParam: %lu, lParam: %lu\n",
+                                count, message->msg, message->wparam, message->lparam);
+
+        HeapFree(GetProcessHeap(), 0, message);
+
+        count++;
+    }
+    list_init(&messages);
+}
+
+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)
 {
+    message_add(uNotification, wParam, lParam);
+
+    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,14 +153,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(mes_simple_show);
 
 }
 
-- 
2.12.0




More information about the wine-patches mailing list