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/AttachThr…
==============================================================================
--- 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/CMakeList…
==============================================================================
--- 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/DeferWind…
==============================================================================
--- 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/SetActive…
==============================================================================
--- 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/SystemPar…
==============================================================================
--- 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/TrackMous…
==============================================================================
--- 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?…
==============================================================================
--- 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?…
==============================================================================
--- 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.…
==============================================================================
--- 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 },