ReactOS 0.4.15-dev-5865-g640e228
AttachThreadInput.c File Reference
#include "precomp.h"
Include dependency graph for AttachThreadInput.c:

Go to the source code of this file.

Classes

struct  THREAD_DATA
 

Macros

#define EXPECT_FOREGROUND(expected)
 
#define EXPECT_ACTIVE(expected)
 

Functions

static int get_iwnd (HWND hWnd)
 
LRESULT CALLBACK TestProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
static void FlushMessages ()
 
static DWORD WINAPI thread_proc (void *param)
 
BOOL CreateTestThread (int i, WCHAR *Desktop)
 
static LRESULT CALLBACK MouseLLHookProc (int nCode, WPARAM wParam, LPARAM lParam)
 
LRESULT CALLBACK KbdLLHookProc (int nCode, WPARAM wParam, LPARAM lParam)
 
BOOLEAN InitThreads ()
 
static void cleanup_attachments ()
 
void Test_SimpleParameters ()
 
void Test_Focus ()
 
void Test_UnaffectedMessages ()
 
void Test_SendInput ()
 
 START_TEST (AttachThreadInput)
 

Variables

static THREAD_DATA data [6]
 
static HHOOK hMouseHookLL = NULL
 
static HHOOK hKbdHookLL = NULL
 

Macro Definition Documentation

◆ EXPECT_ACTIVE

#define EXPECT_ACTIVE (   expected)
Value:
"Expected hwnd%d to be active, got hwnd%d\n", \
static int get_iwnd(HWND hWnd)
#define ok(value,...)
Definition: atltest.h:57
BOOL expected
Definition: store.c:2063
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138

Definition at line 31 of file AttachThreadInput.c.

◆ EXPECT_FOREGROUND

#define EXPECT_FOREGROUND (   expected)
Value:
"Expected hwnd%d at the foreground, got hwnd%d\n", \
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392

Definition at line 27 of file AttachThreadInput.c.

Function Documentation

◆ cleanup_attachments()

static void cleanup_attachments ( )
static

Definition at line 208 of file AttachThreadInput.c.

209{
210 int i,j;
211 BOOL ret;
212
213 for(i = 0; i< 4; i++)
214 {
215 for(j = 0; j< 4; j++)
216 {
218 ok(ret==0, "expected AttachThreadInput to fail\n");
219 }
220 }
221}
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
static TfClientId tid
int ret
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)

Referenced by START_TEST().

◆ CreateTestThread()

BOOL CreateTestThread ( int  i,
WCHAR Desktop 
)

Definition at line 117 of file AttachThreadInput.c.

118{
119 DWORD ret;
120
121 data[i].StartEvent = CreateEventW(NULL, 0, 0, NULL);
122 data[i].Desktop = Desktop;
123 data[i].hThread = CreateThread(NULL, 0, thread_proc, &data[i], 0, &data[i].tid);
124 if(!data[i].hThread) goto fail;
127 if(ret == WAIT_TIMEOUT)
128 {
129fail:
130 win_skip("child thread failed to initialize\n");
131 return FALSE;
132 }
133 return TRUE;
134}
static DWORD WINAPI thread_proc(void *param)
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
unsigned long DWORD
Definition: ntddk_ex.h:95
HANDLE hThread
Definition: wizard.c:28
#define win_skip
Definition: test.h:160
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
HANDLE StartEvent
Definition: thmsvc.c:26

Referenced by InitThreads(), and Test_SimpleParameters().

◆ FlushMessages()

static void FlushMessages ( )
static

Definition at line 59 of file AttachThreadInput.c.

60{
61 MSG msg;
63
64 while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
65 {
66 int iwnd = get_iwnd(msg.hwnd);
67 if( iwnd >= 0 && msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER)
68 record_message(&data[0].cache, iwnd, msg.message, POST, msg.wParam,0);
70 }
71
72 /* Use SendMessage to sync with the other queues */
74 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
76 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
78 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
80 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
81}
#define msg(x)
Definition: auth_time.c:54
HWND hWnd
Definition: settings.c:17
#define WM_APP
Definition: eventvwr.h:73
GLuint res
Definition: glext.h:9613
void record_message(MSG_CACHE *cache, int iwnd, UINT message, MSG_TYPE type, int param1, int param2)
Definition: msgtrace.c:179
@ POST
Definition: msgtrace.h:7
Definition: cache.c:49
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
LONG_PTR LRESULT
Definition: windef.h:209
#define ERROR_TIMEOUT
Definition: winerror.h:941
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
#define SendMessageTimeout
Definition: winuser.h:5835
#define WM_TIMER
Definition: winuser.h:1732
#define PM_REMOVE
Definition: winuser.h:1186
#define PeekMessage
Definition: winuser.h:5820
#define SMTO_NORMAL
Definition: winuser.h:1215

Referenced by Test_Focus(), Test_SendInput(), and Test_UnaffectedMessages().

◆ get_iwnd()

static int get_iwnd ( HWND  hWnd)
static

Definition at line 39 of file AttachThreadInput.c.

40{
41 if(hWnd == data[0].hWnd) return 0;
42 else if(hWnd == data[1].hWnd) return 1;
43 else if(hWnd == data[2].hWnd) return 2;
44 else if(hWnd == data[3].hWnd) return 3;
45 else if(hWnd == data[4].hWnd) return 4;
46 else return -1;
47}

Referenced by FlushMessages(), TestProc(), and thread_proc().

◆ InitThreads()

BOOLEAN InitThreads ( )

Definition at line 162 of file AttachThreadInput.c.

163{
164 /* Create a LL hook that drops any physical keyboard and mouse action
165 and prevent the user from interfering with the test results */
166 if(!IsDebuggerPresent())
167 {
169 ok(hMouseHookLL!=NULL,"failed to set hook\n");
171 ok(hKbdHookLL!=NULL,"failed to set hook\n");
172 }
173
174 /* create test clases */
175 RegisterSimpleClass(TestProc, L"TestClass");
176
177 memset(&data[0], 0, sizeof(data[0]));
178
179 data[0].tid = GetCurrentThreadId();
180
181 /* create test window */
182 data[0].hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW,
183 100, 100, 500, 500, NULL, NULL, 0, NULL);
184 if(!data[0].hWnd)
185 {
186 win_skip("CreateWindowW failed\n");
187 return FALSE;
188 }
189
190 /* create thread1(same desktop) */
191 if(!CreateTestThread(1, NULL)) return FALSE;
192
193 /* create thread2(same desktop) */
194 if(!CreateTestThread(2, NULL)) return FALSE;
195
196 /* ugly ros hack to bypass desktop crapiness */
197 if(!CreateTestThread(6, L"ThreadTestDesktop")) return FALSE;
198
199 /* create thread3(different desktop) */
200 if(!CreateTestThread(3, L"ThreadTestDesktop")) return FALSE;
201
202 /* create thread4(different desktop) */
203 if(!CreateTestThread(4, L"ThreadTestDesktop")) return FALSE;
204
205 return TRUE;
206}
LRESULT CALLBACK KbdLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
static HHOOK hMouseHookLL
BOOL CreateTestThread(int i, WCHAR *Desktop)
static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
static HHOOK hKbdHookLL
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:838
#define L(x)
Definition: ntvdm.h:50
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
#define TestProc(n)
Definition: queuetest.c:15
#define memset(x, y, z)
Definition: compat.h:39
static __inline ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName)
DWORD WINAPI GetCurrentThreadId(void)
Definition: thread.c:459
BOOL WINAPI IsDebuggerPresent(void)
Definition: debugger.c:580
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
#define WH_MOUSE_LL
Definition: winuser.h:44
#define WH_KEYBOARD_LL
Definition: winuser.h:43
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4306

Referenced by START_TEST().

◆ KbdLLHookProc()

LRESULT CALLBACK KbdLLHookProc ( int  nCode,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 149 of file AttachThreadInput.c.

150{
151 LRESULT ret;
153
155
156 if((params->flags & LLKHF_INJECTED) == 0)
157 return TRUE;
158
159 return ret;
160}
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
GLenum const GLfloat * params
Definition: glext.h:5645
#define LLKHF_INJECTED
Definition: winuser.h:2636
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)

Referenced by InitThreads().

◆ MouseLLHookProc()

static LRESULT CALLBACK MouseLLHookProc ( int  nCode,
WPARAM  wParam,
LPARAM  lParam 
)
static

Definition at line 136 of file AttachThreadInput.c.

137{
138 LRESULT ret;
140
142
143 if((params->flags & LLKHF_INJECTED) == 0)
144 return TRUE;
145
146 return ret;
147}

Referenced by InitThreads().

◆ START_TEST()

START_TEST ( AttachThreadInput  )

Definition at line 657 of file AttachThreadInput.c.

658{
659 if(!InitThreads())
660 return;
661
664 Test_Focus();
670
671 if(hMouseHookLL)
673 if(hKbdHookLL)
675
676 /* Stop all threads and exit gratefully */
681}
void Test_UnaffectedMessages()
void Test_SendInput()
static void cleanup_attachments()
void Test_SimpleParameters()
void Test_Focus()
BOOLEAN InitThreads()
#define WM_QUIT
Definition: winuser.h:1613
#define PostThreadMessage
Definition: winuser.h:5823
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)

◆ Test_Focus()

void Test_Focus ( )

Definition at line 349 of file AttachThreadInput.c.

350{
351 BOOL ret;
352
353 trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd);
354 /* Window 1 is in the foreground */
358
361
362 /* attach thread 0 to 1 */
363 {
365 ok(ret==1, "expected AttachThreadInput to succeed\n");
367
370
372 ok(ret==1, "expected AttachThreadInput to succeed\n");
373 }
374
376 EXPECT_ACTIVE(0);
377
381
384
385 /* attach thread 1 to 0 */
386 {
388 ok(ret==1, "expected AttachThreadInput to succeed\n");
390
393
395 ok(ret==1, "expected AttachThreadInput to succeed\n");
396 }
397
398 /* Window 0 is in the foreground */
402
405
406 /* attach thread 0 to 1 */
407 {
409 ok(ret==1, "expected AttachThreadInput to succeed\n");
411
414
418
421
423 ok(ret==1, "expected AttachThreadInput to succeed\n");
424 }
425
427 EXPECT_ACTIVE(0);
428
432
435
436 /* attach thread 1 to 0 */
437 {
439 ok(ret==1, "expected AttachThreadInput to succeed\n");
441
444
448
451
453 ok(ret==1, "expected AttachThreadInput to succeed\n");
454 }
455}
static void FlushMessages()
#define EXPECT_FOREGROUND(expected)
#define EXPECT_ACTIVE(expected)
#define trace
Definition: atltest.h:70
BOOL WINAPI SetForegroundWindow(_In_ HWND)
HWND WINAPI SetActiveWindow(_In_ HWND)

Referenced by START_TEST().

◆ Test_SendInput()

void Test_SendInput ( )

Definition at line 536 of file AttachThreadInput.c.

537{
538 MSG_ENTRY Thread1_chain[]={
539 {1,WM_KEYDOWN, POST, VK_SHIFT, 0},
540 {1,WM_KEYUP, POST, VK_SHIFT, 0},
541 {0,0}};
542 MSG_ENTRY Thread0_chain[]={
543 {0,WM_KEYDOWN, POST, VK_SHIFT, 0},
544 {0,WM_KEYUP, POST, VK_SHIFT, 0},
545 {0,0}};
546
547 BOOL ret;
548
549 //trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd);
550
551 /* First try sending input without attaching. It will go to the foreground */
552 {
555
556 ok(GetForegroundWindow() == data[1].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
557 ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
558
562
563 keybd_event(VK_SHIFT, 0,0,0);
565 Sleep(100);
567
569 COMPARE_CACHE_(&data[1].cache, Thread1_chain);
570 }
571
572 /* Next attach and send input. It will go to the same thread as before */
573 { // from to
575 ok(ret==1, "expected AttachThreadInput to succeed\n");
576
580
581 keybd_event(VK_SHIFT, 0,0,0);
583 Sleep(100);
585
587 COMPARE_CACHE_(&data[1].cache, Thread1_chain);
588 }
589
590 /* Now set foreground and active again. Input will go to thread 0 */
591 {
595
596 ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
597 ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
598
601
602 keybd_event(VK_SHIFT, 0,0,0);
604 Sleep(100);
606
607 COMPARE_CACHE_(&data[0].cache, Thread0_chain);
609
611 ok(ret==1, "expected AttachThreadInput to succeed\n");
612 }
613
614 /* Attach in the opposite order and send input */
615 {
617 ok(ret==1, "expected AttachThreadInput to succeed\n");
618
622
623 keybd_event(VK_SHIFT, 0,0,0);
625 Sleep(100);
627
628 COMPARE_CACHE_(&data[0].cache, Thread0_chain);
630 }
631
632 /* Now set foreground and active again. Input will go to thread 0 */
633 {
637
638 ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
639 ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
640
643
644 keybd_event(VK_SHIFT, 0,0,0);
646 Sleep(100);
648
649 COMPARE_CACHE_(&data[0].cache, Thread0_chain);
651
653 ok(ret==1, "expected AttachThreadInput to succeed\n");
654 }
655}
MSG_ENTRY empty_chain[]
Definition: msgtrace.c:20
#define COMPARE_CACHE_(cache, msg_chain)
Definition: msgtrace.h:62
#define EMPTY_CACHE_(cache)
Definition: msgtrace.h:64
Definition: msgtrace.h:15
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
#define WM_KEYUP
Definition: winuser.h:1706
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
#define VK_SHIFT
Definition: winuser.h:2192
#define WM_KEYDOWN
Definition: winuser.h:1705
#define KEYEVENTF_KEYUP
Definition: winuser.h:1096

Referenced by START_TEST().

◆ Test_SimpleParameters()

void Test_SimpleParameters ( )

Definition at line 230 of file AttachThreadInput.c.

231{
232 BOOL ret;
233 /* FIXME: acording to msdn xp doesn't set last error but vista+ does*/
234
235 /* test wrong thread */
236 ret = AttachThreadInput( 0, 1, TRUE);
237 ok(ret==0, "expected AttachThreadInput to fail\n");
238
239 /* test same thread */
241 ok(ret==0, "expected AttachThreadInput to fail\n");
242
243 /* try to attach to a thread on another desktop*/
245 ok(ret==0, "expected AttachThreadInput to fail\n");
246 if(ret == 1 )
248
249 /* test other desktop to this */
251 ok(ret==0, "expected AttachThreadInput to fail\n");
252 if(ret == 1 )
254
255 /* attach two threads that are both in ThreadTestDesktop */
256 {
257 /* Attach thread 3 and 4 */
259 ok(ret==1, "expected AttachThreadInput to succeed\n");
260
261 /* cleanup previous attachment */
263 ok(ret==1, "expected AttachThreadInput to succeed\n");
264 }
265
266 {
267 /* Attach thread 1 and 2 */
269 ok(ret==1, "expected AttachThreadInput to succeed\n");
270
271 /* attach already attached*/
273 ok(ret==1, "expected AttachThreadInput to succeed\n");
274
275 /* attach in the opposite order */
277 ok(ret==1, "expected AttachThreadInput to succeed\n");
278
279 /* Now try to detach 0 from 1 */
281 ok(ret==0, "expected AttachThreadInput to fail\n");
282
283 /* also try to detach 3 from 2 */
285 ok(ret==0, "expected AttachThreadInput to fail\n");
286
287 /* cleanup previous attachment */
289 ok(ret==1, "expected AttachThreadInput to succeed\n");
290
292 ok(ret==1, "expected AttachThreadInput to succeed\n");
293
295 ok(ret==1, "expected AttachThreadInput to succeed\n");
296 }
297
298 /* test triple attach */
299 {
301 ok(ret==1, "expected AttachThreadInput to succeed\n");
303 ok(ret==1, "expected AttachThreadInput to succeed\n");
304
305 /* try to detach 2 and 0 */
307 ok(ret==0, "expected AttachThreadInput to fail\n");
309 ok(ret==0, "expected AttachThreadInput to fail\n");
310
311 /* try to to attach 0 to 2. it works! */
313 ok(ret==1, "expected AttachThreadInput to succeed\n");
314
316 ok(ret==1, "expected AttachThreadInput to succeed\n");
317
318 /* detach in inverse order */
320 ok(ret==1, "expected AttachThreadInput to succeed\n");
322 ok(ret==1, "expected AttachThreadInput to succeed\n");
323 }
324
325 /* test detaching in thread cleanup */
326 {
328 ok(ret==1, "expected AttachThreadInput to succeed\n");
330 ok(ret==1, "expected AttachThreadInput to succeed\n");
332 ok(ret==1, "expected AttachThreadInput to succeed\n");
334 ok(ret==1, "expected AttachThreadInput to succeed\n");
335
337
339 ok(ret==0, "expected AttachThreadInput to fail\n");
341 ok(ret==0, "expected AttachThreadInput to fail\n");
342
343 /* Create Thread1 again */
345 }
346
347}
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:587

Referenced by START_TEST().

◆ Test_UnaffectedMessages()

void Test_UnaffectedMessages ( )

Definition at line 458 of file AttachThreadInput.c.

459{
460 BOOL ret;
461 LRESULT res;
462
465
466 /* test that messages posted before and after attachment are unaffected
467 and that we don't receive a meassage from a window we shouldn't */
468 PostMessage(data[0].hWnd, WM_USER, 0,0);
469 PostMessage(data[1].hWnd, WM_USER, 1,0);
470
471 {
472 MSG_ENTRY Thread0_chain[]={
473 {0,WM_USER, POST, 0, 0},
474 {0,WM_USER, POST, 2, 0},
475 {0,0}};
476 MSG_ENTRY Thread1_chain[]={
477 {1,WM_USER, POST, 1, 0},
478 {1,WM_USER, POST, 3, 0},
479 {0,0}};
480
482 ok(ret==1, "expected AttachThreadInput to succeed\n");
483
484 PostMessage(data[0].hWnd, WM_USER, 2,0);
485 PostMessage(data[1].hWnd, WM_USER, 3,0);
486
488 Sleep(100);
489
490 COMPARE_CACHE_(&data[0].cache, Thread0_chain);
491 COMPARE_CACHE_(&data[1].cache, Thread1_chain);
492
494 ok(ret==1, "expected AttachThreadInput to succeed\n");
495 }
496
497 /* test messages send to the wrong thread */
499 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
501 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
502
503 {
504 MSG_ENTRY Thread0_chain[]={
505 {0,WM_USER, SENT, 0, 0},
506 {0,WM_USER, SENT, 2, 0},
507 {0,0}};
508 MSG_ENTRY Thread1_chain[]={
509 {1,WM_USER, SENT, 1, 0},
510 {1,WM_USER, SENT, 3, 0},
511 {1,WM_MOUSEMOVE, SENT, 0, 0},
512 {0,0}};
513
515 ok(ret==1, "expected AttachThreadInput to succeed\n");
516
518 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
520 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
521
522 /* Try to send a fake input message */
524 ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
525
526 COMPARE_CACHE_(&data[0].cache, Thread0_chain);
527 COMPARE_CACHE_(&data[1].cache, Thread1_chain);
528
530 ok(ret==1, "expected AttachThreadInput to succeed\n");
531 }
532
533 /* todo: test keyboard layout that shouldn't be affected */
534}
@ SENT
Definition: msgtrace.h:6
#define WM_MOUSEMOVE
Definition: winuser.h:1765
#define PostMessage
Definition: winuser.h:5822
#define WM_USER
Definition: winuser.h:1885

Referenced by START_TEST().

◆ TestProc()

LRESULT CALLBACK TestProc ( HWND  hWnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 49 of file AttachThreadInput.c.

50{
51 int iwnd = get_iwnd(hWnd);
52
53 if(iwnd >= 0 && message > 0 && message < WM_APP && message != WM_TIMER)
54 record_message(&data[iwnd].cache, iwnd, message, SENT, wParam,0);
55
57}
#define DefWindowProc
Definition: ros2win.h:31
Definition: tftpd.h:60

◆ thread_proc()

static DWORD WINAPI thread_proc ( void param)
static

Definition at line 83 of file AttachThreadInput.c.

84{
85 THREAD_DATA* current_data = (THREAD_DATA*)param;
86 MSG msg;
87 HDESK hdesk = NULL;
88 int iwnd;
89
90 if(current_data->Desktop)
91 {
92 hdesk = CreateDesktopW(current_data->Desktop, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
93 SetThreadDesktop(hdesk);
94 }
95
96 /* create test window */
97 current_data->hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW,
98 100, 100, 500, 500, NULL, NULL, 0, NULL);
99 SetEvent( current_data->StartEvent );
100
101 iwnd = get_iwnd(current_data->hWnd);
102
103 /* Use MsgWaitForMultipleObjects to let the thread process apcs */
104 while( GetMessage(&msg, 0,0,0) )
105 {
106 if(msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER )
107 record_message(&data[iwnd].cache, iwnd, msg.message, POST, msg.wParam,0);
109 }
110
111 if(hdesk)
112 CloseDesktop(hdesk);
113
114 return 0;
115}
GLfloat param
Definition: glext.h:5796
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop, LPCWSTR lpszDevice, LPDEVMODEW pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:473
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
#define GetMessage
Definition: winuser.h:5780
#define DispatchMessage
Definition: winuser.h:5755
BOOL WINAPI CloseDesktop(_In_ HDESK)

Referenced by CreateTestThread().

Variable Documentation

◆ data

THREAD_DATA data[6]
static

Definition at line 22 of file AttachThreadInput.c.

◆ hKbdHookLL

HHOOK hKbdHookLL = NULL
static

Definition at line 24 of file AttachThreadInput.c.

Referenced by InitThreads(), and START_TEST().

◆ hMouseHookLL

HHOOK hMouseHookLL = NULL
static

Definition at line 23 of file AttachThreadInput.c.

Referenced by InitThreads(), KbdLLHookProc(), MouseLLHookProc(), and START_TEST().