[v3 09/12] comctl32: TaskDialog - Changed tests to allow sending messages

Fabian Maurer dark.shadow4 at web.de
Fri Mar 10 12:22:01 CST 2017


v3: Rewrite to implement Nikolay Sivov's suggestions

Signed-off-by: Fabian Maurer <dark.shadow4 at web.de>
---
 dlls/comctl32/tests/taskdialog.c | 154 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 137 insertions(+), 17 deletions(-)

diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index 6b8419045e..51a6451721 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -40,15 +40,122 @@ 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 },
+struct message_send_info
+{
+    UINT send_message;
+    WPARAM send_wparam;
+    LPARAM send_lparam;
+
+    BOOL post; /* post instead of send */
+    const CHAR *title_target; /* control text, 0 means it's send to the dialog form instead */
+};
+
+struct message_info
+{
+    UINT recv_message; /* Message the callback receives */
+    WPARAM recv_wparam;
+    LPARAM recv_lparam;
+
+    HRESULT ret; /* Value the callback should return */
+
+    struct message_send_info send[9];  /* Message to send to trigger the next callback message */
+};
+
+static const struct message_info *current_message_info;
+
+
+static const struct message_info mes_simple_show[] = {
+    { TDN_CREATED, 0, 0, S_OK, {
+        { WM_KEYDOWN, VK_RETURN, 0, TRUE },
+        { 0 }}},
+    { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, {{ 0 }}},
     { 0 }
 };
 
 
+/* Create a message to test against */
+static struct message create_test_message(UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct message mes;
+
+    mes.message = WM_TD_CALLBACK;
+    mes.id = message;
+    mes.flags = sent|wparam|lparam|id;
+    mes.wParam = wParam;
+    mes.lParam = lParam;
+
+    return mes;
+}
+
+/* Our only way to get a button handle, since GetDlgItem and FindWindowEx don't work for the official taskdialog */
+
+static HWND taskdialog_child;
+BOOL CALLBACK enum_taskdialog_children_proc(HWND hwnd, LPARAM lParam)
+{
+    CHAR text[100];
+    const CHAR *title = (const CHAR *)lParam;
+
+    GetWindowTextA(hwnd, text, sizeof(text));
+
+    if(lstrcmpA(text, title) == 0)
+    {
+        taskdialog_child = hwnd;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+static HWND get_child_from_title(HWND hwnd_parent, const CHAR *title)
+{
+    taskdialog_child = NULL;
+    EnumChildWindows(hwnd_parent, enum_taskdialog_children_proc, (LPARAM)title);
+    return taskdialog_child;
+}
+
+#define run_test(info, expect_button, expect_radio, expect_checkbox, seq, context) \
+        run_test_(info, expect_button, expect_radio, expect_checkbox, seq, context, \
+                  sizeof(seq)/sizeof(seq[0]) - 1 , __FILE__, __LINE__)
+
+void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio, BOOL expect_checkbox,
+               const struct message_info *test_messages, const char* context,
+               int test_messages_len, const char *file, int line)
+{
+    HRESULT ret;
+    int ret_button = 0;
+    int ret_radio = 0;
+    BOOL ret_checkbox = 0;
+
+    struct message *mes, *mes_start;
+    int i;
+
+    /* Allocate messages to test against, plus 2 implicit and 1 empty */
+    mes_start = mes = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct message) * (test_messages_len + 3));
+
+    *mes++ = create_test_message(TDN_DIALOG_CONSTRUCTED, 0, 0); /* Always needed, thus made implicit */
+    for(i = 0; i < test_messages_len; i++)
+    {
+        *mes++ = create_test_message(test_messages[i].recv_message,
+                                     test_messages[i].recv_wparam, test_messages[i].recv_lparam);
+    }
+    *mes++ = create_test_message(TDN_DESTROYED, 0, 0); /* Always needed, thus made implicit */
+
+    current_message_info = test_messages;
+    flush_sequences(sequences, NUM_MSG_SEQUENCES);
+    ret = pTaskDialogIndirect(info, &ret_button, &ret_radio, &ret_checkbox);
+
+    ok_( file, line)(ret == S_OK, "Expected S_OK, got %x\n", ret);
+    ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, mes_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,
+                     "Wrong radio button. Expected %d, got %d\n", expect_radio, ret_radio);
+    ok_( file, line)(ret_checkbox == expect_checkbox,
+                     "Wrong checkbox state. Expected %d, got %d\n", expect_checkbox, ret_checkbox);
+
+    HeapFree(GetProcessHeap(), 0, mes);
+}
+
 static LONG_PTR backup_ref_data; /* Copy of dwRefData to test against */
 
 static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, UINT uNotification, WPARAM wParam,
@@ -56,19 +163,34 @@ static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, UINT uNotification, WP
 {
     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)
+    msg = create_test_message(uNotification, wParam, lParam);
+    add_message(sequences, TASKDIALOG_SEQ_INDEX, &msg);
+
+    if(uNotification != TDN_DIALOG_CONSTRUCTED && uNotification != TDN_DESTROYED) /* Skip implicit messages */
     {
-        PostMessageW(hwnd, WM_KEYDOWN, VK_RETURN, 0);
+        int mes_pos = sequences[TASKDIALOG_SEQ_INDEX]->count - 2; /* Skip implicit message and the current one */
+        const struct message_send_info *msg_send = current_message_info[mes_pos].send;
+        while(msg_send->send_message)
+        {
+            if(msg_send->title_target)
+            {
+                hwnd = get_child_from_title(hwnd, msg_send->title_target);
+                ok(hwnd != NULL, "Can't find child window.\n");
+            }
+
+            if(msg_send->post)
+                PostMessageW(hwnd, msg_send->send_message, msg_send->send_wparam, msg_send->send_lparam);
+            else
+                SendMessageW(hwnd, msg_send->send_message, msg_send->send_wparam, msg_send->send_lparam);
+
+            msg_send++;
+        }
+
+        return current_message_info[mes_pos].ret;
     }
+
     return S_OK;
 }
 
@@ -87,9 +209,7 @@ static void test_TaskDialogIndirect(void)
     info.pfCallback = TaskDialogCallbackProc;
     info.lpCallbackData = backup_ref_data = 0x12345678; /* Set data for callback tests */
 
-    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);
+    run_test(&info, IDOK, 0, FALSE, mes_simple_show, "Simple test with parameters null");
 }
 
 START_TEST(taskdialog)
-- 
2.12.0




More information about the wine-patches mailing list