From: Fabian Maurer Subject: [v3 04/12] comctl32: Extend TaskDialog, add simple callback and tests Message-Id: <20170310182204.20127-4-dark.shadow4@web.de> Date: Fri, 10 Mar 2017 19:21:56 +0100 In-Reply-To: <20170310182204.20127-1-dark.shadow4@web.de> References: <20170310182204.20127-1-dark.shadow4@web.de> v3: Rewrite to implement Nikolay Sivov's suggestions Signed-off-by: Fabian Maurer --- 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