From: Fabian Maurer Subject: [v3 09/12] comctl32: TaskDialog - Changed tests to allow sending messages Message-Id: <20170310182204.20127-9-dark.shadow4@web.de> Date: Fri, 10 Mar 2017 19:22:01 +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/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