[PATCH] comctl32/taskdialog: Add callback tests

Fabian Maurer <[email protected]>
Newsgroups gmane.comp.emulators.wine.patches
Message-ID <[email protected]>
Simplified the testing structure further.

Signed-off-by: Fabian Maurer <[email protected]>
---
 dlls/comctl32/taskdialog.c       |   2 +-
 dlls/comctl32/tests/taskdialog.c | 120 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 5c4af2ab03..7abf1a8bc5 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -584,7 +584,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
 
     if (button) *button = ret;
     if (radio_button) *radio_button = taskconfig->nDefaultButton;
-    if (verification_flag_checked) *verification_flag_checked = TRUE;
+    if (verification_flag_checked) *verification_flag_checked = FALSE;
 
     return S_OK;
 }
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index 57f33f3835..4c55283047 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -24,13 +24,119 @@
 #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 HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
         TASKDIALOG_COMMON_BUTTON_FLAGS, const WCHAR *, int *);
 
+static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
+
+struct message_info
+{
+    UINT message;
+    WPARAM wparam;
+    LPARAM lparam;
+
+    HRESULT ret; /* Value the callback should return */
+    const struct message_info *send;  /* Message to send to trigger the next callback message */
+};
+
+static const struct message_info *current_message_info;
+
+/* Messages to send */
+
+static const struct message_info mes_send_return[] = {
+    { WM_KEYDOWN, VK_RETURN, 0 },
+    { 0 }
+};
+
+/* Messages to test against */
+
+static const struct message_info mes_return_press_ok[] = {
+    { TDN_CREATED,        0,    0, S_OK, mes_send_return },
+    { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+    { 0 }
+};
+
+/* Create a message to test against */
+static struct message create_test_message(UINT message, WPARAM wParam, LPARAM lParam)
+{
+    struct message mes = {WM_TD_CALLBACK, sent|wparam|lparam|id, wParam, lParam, message};
+    return mes;
+}
+
+#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].message, test_messages[i].wparam, test_messages[i].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_start);
+}
+
+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;
+    const struct message_info *msg_send;
+    int mes_pos = sequences[TASKDIALOG_SEQ_INDEX]->count -1; /* Skip implicit message */
+
+    ok(backup_ref_data == dwRefData, "dwRefData is wrong, expected %lu, got %lu\n", backup_ref_data, dwRefData);
+
+    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 */
+        return S_OK;
+
+    msg_send = current_message_info[mes_pos].send;
+    for(; msg_send && msg_send->message;  msg_send++)
+        PostMessageW(hwnd, msg_send->message, msg_send->wparam, msg_send->lparam);
+
+    return current_message_info[mes_pos].ret;
+}
+
 static void test_invalid_parameters(void)
 {
     TASKDIALOGCONFIG info = { 0 };
@@ -52,6 +158,17 @@ static void test_invalid_parameters(void)
     ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
 }
 
+static void test_callback(void)
+{
+    TASKDIALOGCONFIG info = {0};
+
+    info.cbSize = sizeof(TASKDIALOGCONFIG);
+    info.pfCallback = TaskDialogCallbackProc;
+    info.lpCallbackData = backup_ref_data = 0x12345678; /* Set data for callback tests */
+
+    run_test(&info, IDOK, 0, FALSE, mes_return_press_ok, "Simple callback test just sending return");
+}
+
 START_TEST(taskdialog)
 {
     ULONG_PTR ctx_cookie;
@@ -83,7 +200,10 @@ 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_invalid_parameters();
+    test_callback();
 
     unload_v6_module(ctx_cookie, hCtx);
 }
-- 
2.15.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.