Author: gadamopoulos Date: Mon Aug 13 18:04:04 2012 New Revision: 57074
URL: http://svn.reactos.org/svn/reactos?rev=57074&view=rev Log: [user32_apitest] - Add support for logging messages in different threads - Add several tests for AttachThreadInput
Added: trunk/rostests/apitests/user32/AttachThreadInput.c (with props) Modified: trunk/rostests/apitests/user32/CMakeLists.txt trunk/rostests/apitests/user32/DeferWindowPos.c trunk/rostests/apitests/user32/SetActiveWindow.c trunk/rostests/apitests/user32/SystemParametersInfo.c trunk/rostests/apitests/user32/TrackMouseEvent.c trunk/rostests/apitests/user32/helper.c trunk/rostests/apitests/user32/helper.h trunk/rostests/apitests/user32/testlist.c
Added: trunk/rostests/apitests/user32/AttachThreadInput.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/AttachThre... ============================================================================== --- trunk/rostests/apitests/user32/AttachThreadInput.c (added) +++ trunk/rostests/apitests/user32/AttachThreadInput.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -1,0 +1,614 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for AttachThreadInput + * PROGRAMMERS: Giannis Adamopoulos + */ + +#include <windows.h> +#include <stdio.h> +#include <wine/test.h> +#include "helper.h" +#include <undocuser.h> + +#define DESKTOP_ALL_ACCESS 0x01ff + +typedef struct { + DWORD tid; + HANDLE hThread; + HWND hWnd; + WCHAR* Desktop; + HANDLE StartEvent; + HANDLE QueueStatusEvent; + DWORD LastQueueStatus; + + MSG_CACHE cache; +} THREAD_DATA; + +DWORD tidMouseMove; +THREAD_DATA data[5]; +HHOOK hMouseHookLL = NULL; +HHOOK hKbdHookLL = NULL; + + +#define EXPECT_FOREGROUND(expected) ok(GetForegroundWindow() == expected, \ + "Expected hwnd%d at the foreground, got hwnd%d\n", \ + get_iwnd(expected), get_iwnd(GetForegroundWindow())); + +#define EXPECT_ACTIVE(expected) ok(GetActiveWindow() == expected, \ + "Expected hwnd%d to be active, got hwnd%d\n", \ + get_iwnd(expected), get_iwnd(GetActiveWindow())); + +/* + * Helper functions + */ + +static int get_iwnd(HWND hWnd) +{ + if(hWnd == data[0].hWnd) return 0; + else if(hWnd == data[1].hWnd) return 1; + else if(hWnd == data[2].hWnd) return 2; + else if(hWnd == data[3].hWnd) return 3; + else if(hWnd == data[4].hWnd) return 4; + else return -1; +} + +LRESULT CALLBACK TestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + int iwnd = get_iwnd(hWnd); + + if(iwnd >= 0 && message > 0 && message < WM_APP && message != WM_TIMER) + record_message(&data[iwnd].cache, iwnd, message, SENT, wParam,0); + + return DefWindowProc(hWnd, message, wParam, lParam); +} + +static void FlushMessages() +{ + MSG msg; + + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) + { + int iwnd = get_iwnd(msg.hwnd); + if( iwnd >= 0 && msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER) + record_message(&data[0].cache, iwnd, msg.message, POST, msg.wParam,0); + DispatchMessageA( &msg ); + } + + /* Use SendMessage to sync with the other queues */ + SendMessage(data[1].hWnd, WM_APP, 0,0); + SendMessage(data[2].hWnd, WM_APP, 0,0); + SendMessage(data[3].hWnd, WM_APP, 0,0); + SendMessage(data[4].hWnd, WM_APP, 0,0); +} + +static DWORD WINAPI thread_proc(void *param) +{ + THREAD_DATA* current_data = (THREAD_DATA*)param; + MSG msg; + HDESK hdesk = NULL; + int iwnd; + + if(current_data->Desktop) + { + hdesk = CreateDesktopW(current_data->Desktop, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL ); + SetThreadDesktop(hdesk); + ok(GetThreadDesktop(current_data->tid) == hdesk, "Thread in wrong desktop. Following results may be bogus!\n"); + } + + /* create test window */ + current_data->hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW, + 100, 100, 500, 500, NULL, NULL, 0, NULL); + SetEvent( current_data->StartEvent ); + + iwnd = get_iwnd(current_data->hWnd); + + /* Use MsgWaitForMultipleObjects to let the thread process apcs */ + while( GetMessage(&msg, 0,0,0) ) + { + if(msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER ) + record_message(&data[iwnd].cache, iwnd, msg.message, POST, msg.wParam,0); + DispatchMessage(&msg); + } + + if(hdesk) + CloseDesktop(hdesk); + + return 0; +} + +BOOL CreateTestThread(int i, WCHAR* Desktop) +{ + DWORD ret; + + data[i].StartEvent = CreateEventW(NULL, 0, 0, NULL); + data[i].Desktop = Desktop; + data[i].hThread = CreateThread(NULL, 0, thread_proc, &data[i], 0, &data[i].tid); + if(!data[i].hThread) goto fail; + ret = WaitForSingleObject(data[i].StartEvent, 1000); + CloseHandle(data[i].StartEvent); + if(ret == WAIT_TIMEOUT) + { +fail: + win_skip("child thread failed to initialize\n"); + return FALSE; + } + return TRUE; +} + +static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LRESULT ret; + MSLLHOOKSTRUCT* params = (MSLLHOOKSTRUCT*) lParam; + + ret = CallNextHookEx(hMouseHookLL, nCode, wParam, lParam); + + if((params->flags & LLKHF_INJECTED) == 0) + return TRUE; + + return ret; +} + +LRESULT CALLBACK KbdLLHookProc(int nCode, WPARAM wParam, LPARAM lParam) +{ + LRESULT ret; + KBDLLHOOKSTRUCT* params = (KBDLLHOOKSTRUCT*) lParam; + + ret = CallNextHookEx(hMouseHookLL, nCode, wParam, lParam); + + if((params->flags & LLKHF_INJECTED) == 0) + return TRUE; + + return ret; +} + +BOOLEAN InitThreads() +{ + /* Create a LL hook that drops any physical keyboard and mouse action + and prevent the user from interfering with the test results */ + if(!IsDebuggerPresent()) + { + hMouseHookLL = SetWindowsHookExW(WH_MOUSE_LL, MouseLLHookProc, GetModuleHandleW( NULL ), 0); + ok(hMouseHookLL!=NULL,"failed to set hook\n"); + hKbdHookLL = SetWindowsHookExW(WH_KEYBOARD_LL, KbdLLHookProc, GetModuleHandleW( NULL ), 0); + ok(hKbdHookLL!=NULL,"failed to set hook\n"); + } + + /* create test clases */ + RegisterSimpleClass(TestProc, L"TestClass"); + + memset(&data[0], 0, sizeof(data[0])); + + data[0].tid = GetCurrentThreadId(); + + /* create test window */ + data[0].hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW, + 100, 100, 500, 500, NULL, NULL, 0, NULL); + if(!data[0].hWnd) + { + win_skip("CreateWindowW failed\n"); + return FALSE; + } + + /* create thread1(same desktop) */ + if(!CreateTestThread(1, NULL)) return FALSE; + + /* create thread2(same desktop) */ + if(!CreateTestThread(2, NULL)) return FALSE; + + /* create thread3(different desktop) */ + if(!CreateTestThread(3, L"ThreadTestDesktop")) return FALSE; + + /* create thread4(different desktop) */ + if(!CreateTestThread(4, L"ThreadTestDesktop")) return FALSE; + + return TRUE; +} + + + + +/* + * The actual tests + */ + +void Test_SimpleParameters() +{ + BOOL ret; + /* FIXME: acording to msdn xp doesn't set last error but vista+ does*/ + + /* test wrong thread */ + ret = AttachThreadInput( 0, 1, TRUE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* test same thread */ + ret = AttachThreadInput( data[1].tid, data[1].tid, TRUE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* try to attach to a thread on another desktop*/ + ret = AttachThreadInput( data[2].tid,data[3].tid, TRUE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* test other desktop to this */ + ret = AttachThreadInput( data[3].tid,data[2].tid, TRUE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* attach two threads that are both in ThreadTestDesktop */ + { + /* Attach thread 3 and 4 */ + ret = AttachThreadInput( data[3].tid,data[4].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + /* cleanup previous attachment */ + ret = AttachThreadInput( data[3].tid,data[4].tid, FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + { + /* Attach thread 1 and 2 */ + ret = AttachThreadInput( data[1].tid,data[2].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + /* attach already attached*/ + ret = AttachThreadInput( data[1].tid,data[2].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + /* Now try to detach 0 from 1 */ + ret = AttachThreadInput( data[0].tid,data[1].tid, FALSE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* also try to detach 3 from 2 */ + ret = AttachThreadInput( data[2].tid,data[1].tid, FALSE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* cleanup previous attachment */ + ret = AttachThreadInput( data[1].tid,data[2].tid, FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + /*too bad this causes a crash in win32k */ +#if 0 + /* test triple attach */ + { + ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + /* try to detach 2 and 0 */ + ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + ret = AttachThreadInput( data[2].tid, data[0].tid, FALSE); + ok(ret==0, "expected AttachThreadInput to fail\n"); + + /* try to to attach 0 to 2. it works! */ + ret = AttachThreadInput( data[0].tid, data[2].tid, TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + /* detach in inverse order */ + ret = AttachThreadInput( data[0].tid, data[1].tid, FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + ret = AttachThreadInput( data[1].tid, data[2].tid, FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } +#endif +} + +void Test_Focus() //Focus Active Capture Foreground Capture +{ + BOOL ret; + + /* Window 1 is in the foreground */ + SetForegroundWindow(data[1].hWnd); + SetActiveWindow(data[0].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + /* attach thread 0 to 1 */ + { + ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[1].hWnd); + + ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(0); + + SetForegroundWindow(data[1].hWnd); + SetActiveWindow(data[0].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + /* attach thread 1 to 0 */ + { + ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[1].hWnd); + + ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + /* Window 0 is in the foreground */ + SetForegroundWindow(data[0].hWnd); + SetActiveWindow(data[1].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[0].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + /* attach thread 0 to 1 */ + { + ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + FlushMessages(); + + EXPECT_FOREGROUND(data[0].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + SetForegroundWindow(data[0].hWnd); + SetActiveWindow(data[1].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[1].hWnd); + + ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(0); + + SetForegroundWindow(data[0].hWnd); + SetActiveWindow(data[1].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[0].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + /* attach thread 1 to 0 */ + { + ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + FlushMessages(); + + EXPECT_FOREGROUND(data[0].hWnd); + EXPECT_ACTIVE(data[0].hWnd); + + SetForegroundWindow(data[0].hWnd); + SetActiveWindow(data[1].hWnd); + FlushMessages(); + + EXPECT_FOREGROUND(data[1].hWnd); + EXPECT_ACTIVE(data[1].hWnd); + + ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } +} + +/* test some functions like PostMessage and SendMessage that shouldn't be affected */ +void Test_UnaffectedMessages() +{ + BOOL ret; + + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + /* test that messages posted before and after attachment are unaffected + and that we don't receive a meassage from a window we shouldn't */ + PostMessage(data[0].hWnd, WM_USER, 0,0); + PostMessage(data[1].hWnd, WM_USER, 1,0); + + { + MSG_ENTRY Thread0_chain[]={ + {0,WM_USER, POST, 0, 0}, + {0,WM_USER, POST, 2, 0}, + {0,0}}; + MSG_ENTRY Thread1_chain[]={ + {1,WM_USER, POST, 1, 0}, + {1,WM_USER, POST, 3, 0}, + {0,0}}; + + ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + PostMessage(data[0].hWnd, WM_USER, 2,0); + PostMessage(data[1].hWnd, WM_USER, 3,0); + + FlushMessages(); + Sleep(100); + + COMPARE_CACHE_(&data[0].cache, Thread0_chain); + COMPARE_CACHE_(&data[1].cache, Thread1_chain); + + ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + /* test messages send to the wrong thread */ + SendMessage(data[0].hWnd, WM_USER, 0,0); + SendMessage(data[1].hWnd, WM_USER, 1,0); + + { + MSG_ENTRY Thread0_chain[]={ + {0,WM_USER, SENT, 0, 0}, + {0,WM_USER, SENT, 2, 0}, + {0,0}}; + MSG_ENTRY Thread1_chain[]={ + {1,WM_USER, SENT, 1, 0}, + {1,WM_USER, SENT, 3, 0}, + {1,WM_MOUSEMOVE, SENT, 0, 0}, + {0,0}}; + + ret = AttachThreadInput( data[2].tid, data[1].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + SendMessage(data[0].hWnd, WM_USER, 2,0); + SendMessage(data[1].hWnd, WM_USER, 3,0); + + /* Try to send a fake input message */ + SendMessage(data[1].hWnd, WM_MOUSEMOVE, 0,0); + + COMPARE_CACHE_(&data[0].cache, Thread0_chain); + COMPARE_CACHE_(&data[1].cache, Thread1_chain); + + ret = AttachThreadInput( data[2].tid, data[1].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + /* todo: test keyboard layout that shouldn't be affected */ +} + +void Test_SendInput() +{ + MSG_ENTRY Thread1_chain[]={ + {1,WM_KEYDOWN, POST, VK_SHIFT, 0}, + {1,WM_KEYUP, POST, VK_SHIFT, 0}, + {0,0}}; + MSG_ENTRY Thread0_chain[]={ + {0,WM_KEYDOWN, POST, VK_SHIFT, 0}, + {0,WM_KEYUP, POST, VK_SHIFT, 0}, + {0,0}}; + + BOOL ret; + + /* First try sending input without attaching. It will go to the foreground */ + { + SetForegroundWindow(data[1].hWnd); + SetActiveWindow(data[0].hWnd); + + ok(GetForegroundWindow() == data[1].hWnd, "wrong foreground\n"); + ok(GetActiveWindow() == data[0].hWnd, "wrong active\n"); + + FlushMessages(); + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + keybd_event(VK_SHIFT, 0,0,0); + keybd_event(VK_SHIFT, 0,KEYEVENTF_KEYUP,0); + Sleep(100); + FlushMessages(); + + COMPARE_CACHE_(&data[0].cache, empty_chain); + COMPARE_CACHE_(&data[1].cache, Thread1_chain); + } + + /* Next attach and send input. It will go to the same thread as before */ + { + ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + FlushMessages(); + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + keybd_event(VK_SHIFT, 0,0,0); + keybd_event(VK_SHIFT, 0,KEYEVENTF_KEYUP,0); + Sleep(100); + FlushMessages(); + + COMPARE_CACHE_(&data[0].cache, empty_chain); + COMPARE_CACHE_(&data[1].cache, Thread1_chain); + } + + /* Now set foregroung and active again. Input will go to thread 0 */ + { + SetForegroundWindow(data[1].hWnd); + SetActiveWindow(data[0].hWnd); + + FlushMessages(); + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + keybd_event(VK_SHIFT, 0,0,0); + keybd_event(VK_SHIFT, 0,KEYEVENTF_KEYUP,0); + Sleep(100); + FlushMessages(); + + COMPARE_CACHE_(&data[0].cache, Thread0_chain); + COMPARE_CACHE_(&data[1].cache, empty_chain); + + ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } + + /* Attach in the opposite order and send input */ + { + ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + + FlushMessages(); + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + keybd_event(VK_SHIFT, 0,0,0); + keybd_event(VK_SHIFT, 0,KEYEVENTF_KEYUP,0); + Sleep(100); + FlushMessages(); + + COMPARE_CACHE_(&data[0].cache, Thread0_chain); + COMPARE_CACHE_(&data[1].cache, empty_chain); + } + + /* Now set foregroung and active again. Input will go to thread 0 */ + { + SetForegroundWindow(data[1].hWnd); + SetActiveWindow(data[0].hWnd); + + FlushMessages(); + EMPTY_CACHE_(&data[0].cache); + EMPTY_CACHE_(&data[1].cache); + + keybd_event(VK_SHIFT, 0,0,0); + keybd_event(VK_SHIFT, 0,KEYEVENTF_KEYUP,0); + Sleep(100); + FlushMessages(); + + COMPARE_CACHE_(&data[0].cache, Thread0_chain); + COMPARE_CACHE_(&data[1].cache, empty_chain); + + ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE); + ok(ret==1, "expected AttachThreadInput to succeed\n"); + } +} + +START_TEST(AttachThreadInput) +{ + if(!InitThreads()) + return; + + Test_SimpleParameters(); + Test_Focus(); + Test_UnaffectedMessages(); + Test_SendInput(); + + if(hMouseHookLL) + UnhookWindowsHookEx(hMouseHookLL); + if(hKbdHookLL) + UnhookWindowsHookEx(hKbdHookLL); + + /* Stop all threads and exit gratefully */ + PostThreadMessage(data[1].tid, WM_QUIT,0,0); + PostThreadMessage(data[2].tid, WM_QUIT,0,0); + PostThreadMessage(data[3].tid, WM_QUIT,0,0); + PostThreadMessage(data[4].tid, WM_QUIT,0,0); +} +
Propchange: trunk/rostests/apitests/user32/AttachThreadInput.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: trunk/rostests/apitests/user32/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/CMakeLists... ============================================================================== --- trunk/rostests/apitests/user32/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/CMakeLists.txt [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -1,5 +1,6 @@
list(APPEND SOURCE + AttachThreadInput.c helper.c DeferWindowPos.c desktop.c
Modified: trunk/rostests/apitests/user32/DeferWindowPos.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/DeferWindo... ============================================================================== --- trunk/rostests/apitests/user32/DeferWindowPos.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/DeferWindowPos.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -42,11 +42,11 @@ { WINDOWPOS* pwp = (WINDOWPOS*)lParam; ok(wParam==0,"expected wParam=0\n"); - record_message(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); + RECOND_MESSAGE(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); break; } default: - record_message(iwnd, message, SENT, 0,0); + RECOND_MESSAGE(iwnd, message, SENT, 0,0); } return DefWindowProc(hWnd, message, wParam, lParam); } @@ -59,7 +59,7 @@ { int iwnd = get_iwnd(msg.hwnd); if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - record_message(iwnd, msg.message, POST,0,0); + RECOND_MESSAGE(iwnd, msg.message, POST,0,0); DispatchMessageA( &msg ); } } @@ -105,7 +105,7 @@ SetWindowPos(hWnd4, 0, 250,250,200,200, SWP_NOOWNERZORDER|SWP_SHOWWINDOW|SWP_NOACTIVATE); SetActiveWindow(hWnd4); FlushMessages(); - empty_message_cache(); + EMPTY_CACHE(); }
static void Test_DWP_Error(HWND hWnd, HWND hWnd2) @@ -248,7 +248,7 @@ ok_windowpos(hWnd2, 70, 80, 250, 260, "Window 2");
FlushMessages(); - empty_message_cache(); + EMPTY_CACHE(); }
MSG_ENTRY move1_chain[]={ @@ -299,7 +299,7 @@ SetWindowPos(hWnd1, 0, 10,20,100,100,0); SetWindowPos(hWnd2, 0, 10,20,100,100,0); FlushMessages(); - empty_message_cache(); + EMPTY_CACHE();
/* move hWnd1 */ hdwp = BeginDeferWindowPos(1);
Modified: trunk/rostests/apitests/user32/SetActiveWindow.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/SetActiveW... ============================================================================== --- trunk/rostests/apitests/user32/SetActiveWindow.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/SetActiveWindow.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -48,11 +48,11 @@ { WINDOWPOS* pwp = (WINDOWPOS*)lParam; ok(wParam==0,"expected wParam=0\n"); - record_message(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); + RECOND_MESSAGE(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); break; } default: - record_message(iwnd, message, SENT, 0,0); + RECOND_MESSAGE(iwnd, message, SENT, 0,0); } return DefWindowProc(hWnd, message, wParam, lParam); } @@ -65,7 +65,7 @@ { int iwnd = get_iwnd(msg.hwnd); if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - record_message(iwnd, msg.message, POST,0,0); + RECOND_MESSAGE(iwnd, msg.message, POST,0,0); DispatchMessageA( &msg ); } } @@ -86,7 +86,7 @@ SetWindowPos(hWnd2, 0, 0,0,0,0, SWP_NOMOVE|SWP_NOREPOSITION|SWP_NOSIZE|SWP_SHOWWINDOW);
FlushMessages(); - empty_message_cache(); + EMPTY_CACHE(); }
static void destroy_test_window()
Modified: trunk/rostests/apitests/user32/SystemParametersInfo.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/SystemPara... ============================================================================== --- trunk/rostests/apitests/user32/SystemParametersInfo.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/SystemParametersInfo.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -38,11 +38,11 @@ { WINDOWPOS* pwp = (WINDOWPOS*)lParam; ok(wParam==0,"expected wParam=0\n"); - record_message(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); + RECOND_MESSAGE(iwnd, message, SENT, get_iwnd(pwp->hwndInsertAfter), pwp->flags); break; } default: - record_message(iwnd, message, SENT, 0,0); + RECOND_MESSAGE(iwnd, message, SENT, 0,0); } return DefWindowProc(hWnd, message, wParam, lParam); } @@ -55,7 +55,7 @@ { int iwnd = get_iwnd(msg.hwnd); if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - record_message(iwnd, msg.message, POST,0,0); + RECOND_MESSAGE(iwnd, msg.message, POST,0,0); DispatchMessageA( &msg ); } }
Modified: trunk/rostests/apitests/user32/TrackMouseEvent.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/TrackMouse... ============================================================================== --- trunk/rostests/apitests/user32/TrackMouseEvent.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/TrackMouseEvent.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -49,7 +49,7 @@ ok(0, "Got unexpected WM_SYSTIMER in the winproc. wParam=%d\n", wParam); break; default: - record_message(iwnd, message, SENT, 0,0); + RECOND_MESSAGE(iwnd, message, SENT, 0,0); } return DefWindowProc(hWnd, message, wParam, lParam); } @@ -57,7 +57,7 @@ static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam) { LRESULT ret; - record_message(0, WH_MOUSE_LL, HOOK, wParam, 0); + RECOND_MESSAGE(0, WH_MOUSE_LL, HOOK, wParam, 0); ret = CallNextHookEx(hMouseHookLL, nCode, wParam, lParam); if(ignore_mousell) return TRUE; @@ -68,7 +68,7 @@ { MOUSEHOOKSTRUCT *hs = (MOUSEHOOKSTRUCT*) lParam; LRESULT ret; - record_message(get_iwnd(hs->hwnd), WH_MOUSE, HOOK, wParam, hs->wHitTestCode); + RECOND_MESSAGE(get_iwnd(hs->hwnd), WH_MOUSE, HOOK, wParam, hs->wHitTestCode); ret = CallNextHookEx(hMouseHook, nCode, wParam, lParam); if(ignore_mouse) return TRUE; @@ -86,12 +86,12 @@ { if(msg.message == WM_SYSTIMER) { - record_message(iwnd, msg.message, POST,msg.wParam,0); + RECOND_MESSAGE(iwnd, msg.message, POST,msg.wParam,0); if(ignore_timer) continue; } else if(!(msg.message > WM_USER || !iwnd || IsDWmMsg(msg.message) || IseKeyMsg(msg.message))) - record_message(iwnd, msg.message, POST,0,0); + RECOND_MESSAGE(iwnd, msg.message, POST,0,0); } DispatchMessageA( &msg ); } @@ -265,7 +265,7 @@ MOVE_CURSOR(0,0); create_test_windows(); FlushMessages(); - empty_message_cache(); + EMPTY_CACHE();
/* the mouse moves over hwnd2 */ MOVE_CURSOR(220,220);
Modified: trunk/rostests/apitests/user32/helper.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/helper.c?r... ============================================================================== --- trunk/rostests/apitests/user32/helper.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/helper.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -11,10 +11,11 @@ #include "helper.h" #include <undocuser.h>
-MSG_ENTRY last_post_message; -MSG_ENTRY message_cache[100]; -static int message_cache_size = 0; - +MSG_CACHE default_cache = { +#ifdef _MSC_VER + 0 +#endif +}; MSG_ENTRY empty_chain[]= {{0,0}};
static char* get_msg_name(UINT msg) @@ -48,6 +49,8 @@ case WM_SETTINGCHANGE: return "WM_SETTINGCHANGE"; case WM_GETICON: return "WM_GETICON"; case WM_SETICON: return "WM_SETICON"; + case WM_KEYDOWN: return "WM_KEYDOWN"; + case WM_KEYUP: return "WM_KEYUP"; default: return NULL; } } @@ -64,11 +67,9 @@ } }
-void empty_message_cache() -{ - memset(&last_post_message, 0, sizeof(last_post_message)); - memset(message_cache, 0, sizeof(message_cache)); - message_cache_size = 0; +void empty_message_cache(MSG_CACHE* cache) +{ + memset(cache, 0, sizeof(MSG_CACHE)); }
void sprintf_msg_entry(char* buffer, MSG_ENTRY* msg) @@ -111,20 +112,20 @@ } }
-void trace_cache(const char* file, int line) +void trace_cache(MSG_CACHE* cache, const char* file, int line) { int i; char buff[100];
- for (i=0; i < message_cache_size; i++) - { - sprintf_msg_entry(buff, &message_cache[i]); + for (i=0; i < cache->count; i++) + { + sprintf_msg_entry(buff, &cache->message_cache[i]); trace_(file,line)("%d: %s\n", i, buff); } trace_(file,line)("\n"); }
-void compare_cache(const char* file, int line, MSG_ENTRY *msg_chain) +void compare_cache(MSG_CACHE* cache, const char* file, int line, MSG_ENTRY *msg_chain) { int i = 0; char buffGot[100], buffExp[100]; @@ -132,9 +133,9 @@
while(1) { - BOOL same = !memcmp(&message_cache[i],msg_chain, sizeof(MSG_ENTRY)); - - sprintf_msg_entry(buffGot, &message_cache[i]); + BOOL same = !memcmp(&cache->message_cache[i],msg_chain, sizeof(MSG_ENTRY)); + + sprintf_msg_entry(buffGot, &cache->message_cache[i]); sprintf_msg_entry(buffExp, msg_chain); ok_(file,line)(same,"%d: got %s, expected %s\n",i, buffGot, buffExp);
@@ -145,7 +146,7 @@ msg_chain++; else { - if(i>message_cache_size) + if(i > cache->count) break; } i++; @@ -154,46 +155,46 @@ if(got_error ) { trace_(file,line)("The complete list of messages got is:\n"); - trace_cache(file,line); - } - - empty_message_cache(); -} - -void record_message(int iwnd, UINT message, MSG_TYPE type, int param1,int param2) -{ - if(message_cache_size>=100) + trace_cache(cache, file,line); + } + + empty_message_cache(cache); +} + +void record_message(MSG_CACHE* cache, int iwnd, UINT message, MSG_TYPE type, int param1,int param2) +{ + if(cache->count >= 100) { return; }
/* do not report a post message a second time */ if(type == SENT && - last_post_message.iwnd == iwnd && - last_post_message.msg == message && - last_post_message.param1 == param1 && - last_post_message.param2 == param2) - { - memset(&last_post_message, 0, sizeof(last_post_message)); + cache->last_post_message.iwnd == iwnd && + cache->last_post_message.msg == message && + cache->last_post_message.param1 == param1 && + cache->last_post_message.param2 == param2) + { + memset(&cache->last_post_message, 0, sizeof(MSG_ENTRY)); return; }
- message_cache[message_cache_size].iwnd = iwnd; - message_cache[message_cache_size].msg = message; - message_cache[message_cache_size].type = type; - message_cache[message_cache_size].param1 = param1; - message_cache[message_cache_size].param2 = param2; - - if(message_cache[message_cache_size].type == POST) - { - last_post_message = message_cache[message_cache_size]; + cache->message_cache[cache->count].iwnd = iwnd; + cache->message_cache[cache->count].msg = message; + cache->message_cache[cache->count].type = type; + cache->message_cache[cache->count].param1 = param1; + cache->message_cache[cache->count].param2 = param2; + + if(cache->message_cache[cache->count].type == POST) + { + cache->last_post_message = cache->message_cache[cache->count]; } else { - memset(&last_post_message, 0, sizeof(last_post_message)); - } - - message_cache_size++; + memset(&cache->last_post_message, 0, sizeof(MSG_ENTRY)); + } + + cache->count++; }
ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName)
Modified: trunk/rostests/apitests/user32/helper.h URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/helper.h?r... ============================================================================== --- trunk/rostests/apitests/user32/helper.h [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/helper.h [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -16,13 +16,21 @@ int param2; } MSG_ENTRY;
+typedef struct _MSG_CACHE +{ + MSG_ENTRY last_post_message; + MSG_ENTRY message_cache[100]; + int count; +} MSG_CACHE;
extern MSG_ENTRY empty_chain[]; +extern MSG_CACHE default_cache;
-void record_message(int iwnd, UINT message, MSG_TYPE type, int param1,int param2); -void compare_cache(const char* file, int line, MSG_ENTRY *msg_chain); -void trace_cache(const char* file, int line); -void empty_message_cache(); +void record_message(MSG_CACHE* cache, int iwnd, UINT message, MSG_TYPE type, int param1,int param2); +void compare_cache(MSG_CACHE* cache, const char* file, int line, MSG_ENTRY *msg_chain); +void trace_cache(MSG_CACHE* cache, const char* file, int line); +void empty_message_cache(MSG_CACHE* cache); + ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName);
/* filter messages that are affected by dwm */ @@ -44,10 +52,14 @@ return (msg == WM_KEYUP || msg == WM_KEYDOWN); }
-#define COMPARE_CACHE(...) compare_cache(__FILE__, __LINE__, ##__VA_ARGS__) -#define TRACE_CACHE() trace_cache(__FILE__, __LINE__) +#define COMPARE_CACHE(msg_chain) compare_cache(&default_cache, __FILE__, __LINE__, msg_chain) +#define TRACE_CACHE() trace_cache(&default_cache, __FILE__, __LINE__) +#define EMPTY_CACHE() empty_message_cache(&default_cache); +#define RECOND_MESSAGE(...) record_message(&default_cache, ##__VA_ARGS__);
-#define EXPECT_ACTIVE(hwnd) ok(GetActiveWindow() == hwnd, "Expected %p to be the active window, not %p\n",hwnd,GetActiveWindow()) +#define COMPARE_CACHE_(cache, msg_chain) compare_cache(cache, __FILE__, __LINE__, msg_chain) +#define TRACE_CACHE_(cache) trace_cache(cache, __FILE__, __LINE__) +#define EMPTY_CACHE_(cache) empty_message_cache(cache);
#define EXPECT_QUEUE_STATUS(expected, notexpected) \ { \
Modified: trunk/rostests/apitests/user32/testlist.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/apitests/user32/testlist.c... ============================================================================== --- trunk/rostests/apitests/user32/testlist.c [iso-8859-1] (original) +++ trunk/rostests/apitests/user32/testlist.c [iso-8859-1] Mon Aug 13 18:04:04 2012 @@ -5,6 +5,7 @@ #define STANDALONE #include "wine/test.h"
+extern void func_AttachThreadInput(void); extern void func_DeferWindowPos(void); extern void func_desktop(void); extern void func_GetIconInfo(void); @@ -24,6 +25,7 @@
const struct test winetest_testlist[] = { + { "AttachThreadInput", func_AttachThreadInput }, { "desktop", func_desktop }, { "DeferWindowPos", func_DeferWindowPos }, { "GetIconInfo", func_GetIconInfo },