From: Fabian Maurer Subject: [PATCH 14/18] comctl32: TaskDialog - Changed tests to make them more reliable Message-Id: <20170225160146.32556-14-dark.shadow4@web.de> Date: Sat, 25 Feb 2017 17:01:42 +0100 In-Reply-To: <20170225160146.32556-1-dark.shadow4@web.de> References: <20170225160146.32556-1-dark.shadow4@web.de> Messages can now be synchronized to make sure they're properly processed v2: Create event before thread so it can be accessed safely in ThreadProc Signed-off-by: Fabian Maurer # Conflicts: # dlls/comctl32/tests/taskdialog.c --- dlls/comctl32/tests/taskdialog.c | 74 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c index de9661315c..586b182a36 100644 --- a/dlls/comctl32/tests/taskdialog.c +++ b/dlls/comctl32/tests/taskdialog.c @@ -34,12 +34,21 @@ static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, in #define TDN_NO_MORE_MESSAGES 0xffffffff +/* How the message is sent to the dialog */ +typedef enum +{ + SEND_NORMAL = 0, /* Using PostMessageW */ + SEND_SYNCRONIZED = 1, /* Using PostMessageW, but waiting until it's processed */ + SEND_MAINTHREAD = 2, /* Using SendMessageW in main thread */ +}send_info; + typedef struct { UINT msg; WPARAM wparam; LPARAM lparam; HRESULT ret; + BOOL sync; /* Whether the message resets the event that synchronizes message sending or not */ struct list entry; }message_data; @@ -50,6 +59,7 @@ typedef struct WPARAM wparam; LPARAM lparam; const CHAR *title_target; /* control text, 0 means it's send to the dialog form instead */ + send_info send; }message_send_data; static struct list messages = LIST_INIT(messages); @@ -186,10 +196,47 @@ static void ok_sequence_(const message_data *expected_list, const char *file, in static LONG_PTR backup_ref_data; /* Copy of dwRefData to test against */ static const message_data *message_list; static const message_send_data *message_send_list; +static HWND dialog_hwnd; + +static DWORD WINAPI ThreadProc(LPVOID unused) +{ + const message_send_data *message = message_send_list; + HANDLE event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "MessageEvent"); + + WaitForSingleObject(event, INFINITE); /* Wait until dialog is ready */ + Sleep(50); + while(message->message) /* Iterate over all messages */ + { + if(message->send == SEND_MAINTHREAD) + { + message++; + continue; + } + + if(message->title_target) + { + HWND hwndChild = get_child_from_title(dialog_hwnd, message->title_target); + ok(hwndChild != NULL, "Can't find child window.\n"); + PostMessageW(hwndChild, message->message, message->wparam, message->lparam); + } + else + PostMessageW(dialog_hwnd, message->message, message->wparam, message->lparam); + + + if(message->send == SEND_SYNCRONIZED) + WaitForSingleObject(event, INFINITE); /* Wait until message is processed */ + + message++; + } + + CloseHandle(event); + return 0; +} static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, UINT uNotification, WPARAM wParam, LPARAM lParam, LONG_PTR dwRefData) { + HANDLE event = OpenEventA(EVENT_ALL_ACCESS, FALSE, "MessageEvent"); int max_messages = 0; int message_number = list_count(&messages); @@ -200,25 +247,30 @@ static HRESULT CALLBACK TaskDialogCallbackProc(HWND hwnd, UINT uNotification, WP if(uNotification == TDN_CREATED) /* Send test messages */ { const message_send_data *message = message_send_list; + while(message->message) /* Iterate over all messages */ { - if(message->title_target) + if(message->send == SEND_MAINTHREAD) { - HWND hwndChild = get_child_from_title(hwnd, message->title_target); - ok(hwndChild != NULL, "Can't find child window.\n"); - PostMessageW(hwndChild, message->message, message->wparam, message->lparam); + SendMessageW(hwnd, message->message, message->wparam, message->lparam); } - else - PostMessageW(hwnd, message->message, message->wparam, message->lparam); - message++; } + + dialog_hwnd = hwnd; + SetEvent(event); } /* Return the value we specified for that message */ while(message_list[max_messages].msg != TDN_NO_MORE_MESSAGES) max_messages++; if(message_number < max_messages) + { + if(message_list[message_number].sync) + SetEvent(event); + CloseHandle(event); return message_list[message_number].ret; + } + CloseHandle(event); return S_OK; /* Fallback in case we got a message mismatch */ } @@ -248,6 +300,7 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radi const char *file, int line) { HRESULT ret; + HANDLE thread, event; int ret_button = 0; int ret_radio = 0; BOOL ret_checkbox = 0; @@ -257,6 +310,9 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radi message_list = expect_messages; message_send_list = send_messages; + event = CreateEventA(NULL, FALSE, FALSE, "MessageEvent"); + thread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); + ret = pTaskDialogIndirect(info, &ret_button, &ret_radio, &ret_checkbox); ok_( file, line)(ret == S_OK, "Expected S_OK, got %x\n", ret); ok_sequence_(message_list, file, line); @@ -266,6 +322,10 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radi "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); + + TerminateThread(thread, 0); + CloseHandle(thread); + CloseHandle(event); } static void test_TaskDialogIndirect(void) -- 2.12.0