From: Fabian Maurer Subject: [04/18] comctl32: Extend TaskDialog, add simple callback and tests Message-Id: <20170224200412.12968-4-dark.shadow4@web.de> Date: Fri, 24 Feb 2017 21:03:58 +0100 In-Reply-To: <20170224200412.12968-1-dark.shadow4@web.de> References: <20170224200412.12968-1-dark.shadow4@web.de> Signed-off-by: Fabian Maurer --- 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 54c75ed061..5b593ecd90 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.11.1