3f8e3b0d534f75ae299e53dd20af5db2caba3f43
2 * PROJECT: ReactOS api tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for AttachThreadInput
5 * PROGRAMMERS: Giannis Adamopoulos
13 #define DESKTOP_ALL_ACCESS 0x01ff
21 HANDLE QueueStatusEvent
;
22 DWORD LastQueueStatus
;
29 HHOOK hMouseHookLL
= NULL
;
30 HHOOK hKbdHookLL
= NULL
;
33 #define EXPECT_FOREGROUND(expected) ok(GetForegroundWindow() == expected, \
34 "Expected hwnd%d at the foreground, got hwnd%d\n", \
35 get_iwnd(expected), get_iwnd(GetForegroundWindow()));
37 #define EXPECT_ACTIVE(expected) ok(GetActiveWindow() == expected, \
38 "Expected hwnd%d to be active, got hwnd%d\n", \
39 get_iwnd(expected), get_iwnd(GetActiveWindow()));
45 static int get_iwnd(HWND hWnd
)
47 if(hWnd
== data
[0].hWnd
) return 0;
48 else if(hWnd
== data
[1].hWnd
) return 1;
49 else if(hWnd
== data
[2].hWnd
) return 2;
50 else if(hWnd
== data
[3].hWnd
) return 3;
51 else if(hWnd
== data
[4].hWnd
) return 4;
55 LRESULT CALLBACK
TestProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
57 int iwnd
= get_iwnd(hWnd
);
59 if(iwnd
>= 0 && message
> 0 && message
< WM_APP
&& message
!= WM_TIMER
)
60 record_message(&data
[iwnd
].cache
, iwnd
, message
, SENT
, wParam
,0);
62 return DefWindowProc(hWnd
, message
, wParam
, lParam
);
65 static void FlushMessages()
70 while (PeekMessage( &msg
, 0, 0, 0, PM_REMOVE
))
72 int iwnd
= get_iwnd(msg
.hwnd
);
73 if( iwnd
>= 0 && msg
.message
> 0 && msg
.message
< WM_APP
&& msg
.message
!= WM_TIMER
)
74 record_message(&data
[0].cache
, iwnd
, msg
.message
, POST
, msg
.wParam
,0);
75 DispatchMessageA( &msg
);
78 /* Use SendMessage to sync with the other queues */
79 res
= SendMessageTimeout(data
[1].hWnd
, WM_APP
, 0,0, SMTO_NORMAL
, 1000, NULL
);
80 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
81 res
= SendMessageTimeout(data
[2].hWnd
, WM_APP
, 0,0, SMTO_NORMAL
, 1000, NULL
);
82 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
83 res
= SendMessageTimeout(data
[3].hWnd
, WM_APP
, 0,0, SMTO_NORMAL
, 1000, NULL
);
84 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
85 res
= SendMessageTimeout(data
[4].hWnd
, WM_APP
, 0,0, SMTO_NORMAL
, 1000, NULL
);
86 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
89 static DWORD WINAPI
thread_proc(void *param
)
91 THREAD_DATA
* current_data
= (THREAD_DATA
*)param
;
96 if(current_data
->Desktop
)
98 hdesk
= CreateDesktopW(current_data
->Desktop
, NULL
, NULL
, 0, DESKTOP_ALL_ACCESS
, NULL
);
99 SetThreadDesktop(hdesk
);
102 /* create test window */
103 current_data
->hWnd
= CreateWindowW(L
"TestClass", L
"test", WS_OVERLAPPEDWINDOW
,
104 100, 100, 500, 500, NULL
, NULL
, 0, NULL
);
105 SetEvent( current_data
->StartEvent
);
107 iwnd
= get_iwnd(current_data
->hWnd
);
109 /* Use MsgWaitForMultipleObjects to let the thread process apcs */
110 while( GetMessage(&msg
, 0,0,0) )
112 if(msg
.message
> 0 && msg
.message
< WM_APP
&& msg
.message
!= WM_TIMER
)
113 record_message(&data
[iwnd
].cache
, iwnd
, msg
.message
, POST
, msg
.wParam
,0);
114 DispatchMessage(&msg
);
123 BOOL
CreateTestThread(int i
, WCHAR
* Desktop
)
127 data
[i
].StartEvent
= CreateEventW(NULL
, 0, 0, NULL
);
128 data
[i
].Desktop
= Desktop
;
129 data
[i
].hThread
= CreateThread(NULL
, 0, thread_proc
, &data
[i
], 0, &data
[i
].tid
);
130 if(!data
[i
].hThread
) goto fail
;
131 ret
= WaitForSingleObject(data
[i
].StartEvent
, 1000);
132 CloseHandle(data
[i
].StartEvent
);
133 if(ret
== WAIT_TIMEOUT
)
136 win_skip("child thread failed to initialize\n");
142 static LRESULT CALLBACK
MouseLLHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
145 MSLLHOOKSTRUCT
* params
= (MSLLHOOKSTRUCT
*) lParam
;
147 ret
= CallNextHookEx(hMouseHookLL
, nCode
, wParam
, lParam
);
149 if((params
->flags
& LLKHF_INJECTED
) == 0)
155 LRESULT CALLBACK
KbdLLHookProc(int nCode
, WPARAM wParam
, LPARAM lParam
)
158 KBDLLHOOKSTRUCT
* params
= (KBDLLHOOKSTRUCT
*) lParam
;
160 ret
= CallNextHookEx(hMouseHookLL
, nCode
, wParam
, lParam
);
162 if((params
->flags
& LLKHF_INJECTED
) == 0)
168 BOOLEAN
InitThreads()
170 /* Create a LL hook that drops any physical keyboard and mouse action
171 and prevent the user from interfering with the test results */
172 if(!IsDebuggerPresent())
174 hMouseHookLL
= SetWindowsHookExW(WH_MOUSE_LL
, MouseLLHookProc
, GetModuleHandleW( NULL
), 0);
175 ok(hMouseHookLL
!=NULL
,"failed to set hook\n");
176 hKbdHookLL
= SetWindowsHookExW(WH_KEYBOARD_LL
, KbdLLHookProc
, GetModuleHandleW( NULL
), 0);
177 ok(hKbdHookLL
!=NULL
,"failed to set hook\n");
180 /* create test clases */
181 RegisterSimpleClass(TestProc
, L
"TestClass");
183 memset(&data
[0], 0, sizeof(data
[0]));
185 data
[0].tid
= GetCurrentThreadId();
187 /* create test window */
188 data
[0].hWnd
= CreateWindowW(L
"TestClass", L
"test", WS_OVERLAPPEDWINDOW
,
189 100, 100, 500, 500, NULL
, NULL
, 0, NULL
);
192 win_skip("CreateWindowW failed\n");
196 /* create thread1(same desktop) */
197 if(!CreateTestThread(1, NULL
)) return FALSE
;
199 /* create thread2(same desktop) */
200 if(!CreateTestThread(2, NULL
)) return FALSE
;
202 /* ugly ros hack to bypass desktop crapiness */
203 if(!CreateTestThread(6, L
"ThreadTestDesktop")) return FALSE
;
205 /* create thread3(different desktop) */
206 if(!CreateTestThread(3, L
"ThreadTestDesktop")) return FALSE
;
208 /* create thread4(different desktop) */
209 if(!CreateTestThread(4, L
"ThreadTestDesktop")) return FALSE
;
214 static void cleanup_attachments()
219 for(i
= 0; i
< 4; i
++);
221 for(j
= 0; j
< 4; j
++);
223 ret
= AttachThreadInput(data
[i
].tid
,data
[j
].tid
, FALSE
);
224 ok(ret
==0, "expected AttachThreadInput to fail\n");
236 void Test_SimpleParameters()
239 /* FIXME: acording to msdn xp doesn't set last error but vista+ does*/
241 /* test wrong thread */
242 ret
= AttachThreadInput( 0, 1, TRUE
);
243 ok(ret
==0, "expected AttachThreadInput to fail\n");
245 /* test same thread */
246 ret
= AttachThreadInput( data
[1].tid
, data
[1].tid
, TRUE
);
247 ok(ret
==0, "expected AttachThreadInput to fail\n");
249 /* try to attach to a thread on another desktop*/
250 ret
= AttachThreadInput( data
[2].tid
,data
[3].tid
, TRUE
);
251 ok(ret
==0, "expected AttachThreadInput to fail\n");
253 AttachThreadInput( data
[2].tid
,data
[3].tid
, FALSE
);
255 /* test other desktop to this */
256 ret
= AttachThreadInput( data
[3].tid
,data
[2].tid
, TRUE
);
257 ok(ret
==0, "expected AttachThreadInput to fail\n");
259 AttachThreadInput( data
[3].tid
,data
[2].tid
, FALSE
);
261 /* attach two threads that are both in ThreadTestDesktop */
263 /* Attach thread 3 and 4 */
264 ret
= AttachThreadInput( data
[3].tid
,data
[4].tid
, TRUE
);
265 ok(ret
==1, "expected AttachThreadInput to succeed\n");
267 /* cleanup previous attachment */
268 ret
= AttachThreadInput( data
[3].tid
,data
[4].tid
, FALSE
);
269 ok(ret
==1, "expected AttachThreadInput to succeed\n");
273 /* Attach thread 1 and 2 */
274 ret
= AttachThreadInput( data
[1].tid
,data
[2].tid
, TRUE
);
275 ok(ret
==1, "expected AttachThreadInput to succeed\n");
277 /* attach already attached*/
278 ret
= AttachThreadInput( data
[1].tid
,data
[2].tid
, TRUE
);
279 ok(ret
==1, "expected AttachThreadInput to succeed\n");
281 /* attach in the opposite order */
282 ret
= AttachThreadInput( data
[2].tid
,data
[1].tid
, TRUE
);
283 ok(ret
==1, "expected AttachThreadInput to succeed\n");
285 /* Now try to detach 0 from 1 */
286 ret
= AttachThreadInput( data
[0].tid
,data
[1].tid
, FALSE
);
287 ok(ret
==0, "expected AttachThreadInput to fail\n");
289 /* also try to detach 3 from 2 */
290 ret
= AttachThreadInput( data
[3].tid
,data
[2].tid
, FALSE
);
291 ok(ret
==0, "expected AttachThreadInput to fail\n");
293 /* cleanup previous attachment */
294 ret
= AttachThreadInput( data
[1].tid
,data
[2].tid
, FALSE
);
295 ok(ret
==1, "expected AttachThreadInput to succeed\n");
297 ret
= AttachThreadInput( data
[2].tid
,data
[1].tid
, FALSE
);
298 ok(ret
==1, "expected AttachThreadInput to succeed\n");
300 ret
= AttachThreadInput( data
[1].tid
,data
[2].tid
, FALSE
);
301 ok(ret
==1, "expected AttachThreadInput to succeed\n");
304 /* test triple attach */
306 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
307 ok(ret
==1, "expected AttachThreadInput to succeed\n");
308 ret
= AttachThreadInput( data
[1].tid
, data
[2].tid
, TRUE
);
309 ok(ret
==1, "expected AttachThreadInput to succeed\n");
311 /* try to detach 2 and 0 */
312 ret
= AttachThreadInput( data
[0].tid
, data
[2].tid
, FALSE
);
313 ok(ret
==0, "expected AttachThreadInput to fail\n");
314 ret
= AttachThreadInput( data
[2].tid
, data
[0].tid
, FALSE
);
315 ok(ret
==0, "expected AttachThreadInput to fail\n");
317 /* try to to attach 0 to 2. it works! */
318 ret
= AttachThreadInput( data
[0].tid
, data
[2].tid
, TRUE
);
319 ok(ret
==1, "expected AttachThreadInput to succeed\n");
321 ret
= AttachThreadInput( data
[0].tid
, data
[2].tid
, FALSE
);
322 ok(ret
==1, "expected AttachThreadInput to succeed\n");
324 /* detach in inverse order */
325 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, FALSE
);
326 ok(ret
==1, "expected AttachThreadInput to succeed\n");
327 ret
= AttachThreadInput( data
[1].tid
, data
[2].tid
, FALSE
);
328 ok(ret
==1, "expected AttachThreadInput to succeed\n");
331 /* test detaching in thread cleanup */
333 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
334 ok(ret
==1, "expected AttachThreadInput to succeed\n");
335 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
336 ok(ret
==1, "expected AttachThreadInput to succeed\n");
337 ret
= AttachThreadInput( data
[1].tid
, data
[2].tid
, TRUE
);
338 ok(ret
==1, "expected AttachThreadInput to succeed\n");
339 ret
= AttachThreadInput( data
[1].tid
, data
[2].tid
, TRUE
);
340 ok(ret
==1, "expected AttachThreadInput to succeed\n");
342 TerminateThread(data
[1].hThread
, 0);
344 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, FALSE
);
345 ok(ret
==0, "expected AttachThreadInput to fail\n");
346 ret
= AttachThreadInput( data
[1].tid
, data
[2].tid
, FALSE
);
347 ok(ret
==0, "expected AttachThreadInput to fail\n");
349 /* Create Thread1 again */
350 CreateTestThread(1, NULL
);
355 void Test_Focus() //Focus Active Capture Foreground Capture
359 /* Window 1 is in the foreground */
360 SetForegroundWindow(data
[1].hWnd
);
361 SetActiveWindow(data
[0].hWnd
);
364 EXPECT_FOREGROUND(data
[1].hWnd
);
365 EXPECT_ACTIVE(data
[0].hWnd
);
367 /* attach thread 0 to 1 */
369 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
370 ok(ret
==1, "expected AttachThreadInput to succeed\n");
373 EXPECT_FOREGROUND(data
[1].hWnd
);
374 EXPECT_ACTIVE(data
[1].hWnd
);
376 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, FALSE
);
377 ok(ret
==1, "expected AttachThreadInput to succeed\n");
380 EXPECT_FOREGROUND(data
[1].hWnd
);
383 SetForegroundWindow(data
[1].hWnd
);
384 SetActiveWindow(data
[0].hWnd
);
387 EXPECT_FOREGROUND(data
[1].hWnd
);
388 EXPECT_ACTIVE(data
[0].hWnd
);
390 /* attach thread 1 to 0 */
392 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, TRUE
);
393 ok(ret
==1, "expected AttachThreadInput to succeed\n");
396 EXPECT_FOREGROUND(data
[1].hWnd
);
397 EXPECT_ACTIVE(data
[1].hWnd
);
399 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, FALSE
);
400 ok(ret
==1, "expected AttachThreadInput to succeed\n");
403 /* Window 0 is in the foreground */
404 SetForegroundWindow(data
[0].hWnd
);
405 SetActiveWindow(data
[1].hWnd
);
408 EXPECT_FOREGROUND(data
[0].hWnd
);
409 EXPECT_ACTIVE(data
[0].hWnd
);
411 /* attach thread 0 to 1 */
413 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
414 ok(ret
==1, "expected AttachThreadInput to succeed\n");
417 EXPECT_FOREGROUND(data
[0].hWnd
);
418 EXPECT_ACTIVE(data
[0].hWnd
);
420 SetForegroundWindow(data
[0].hWnd
);
421 SetActiveWindow(data
[1].hWnd
);
424 EXPECT_FOREGROUND(data
[1].hWnd
);
425 EXPECT_ACTIVE(data
[1].hWnd
);
427 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, FALSE
);
428 ok(ret
==1, "expected AttachThreadInput to succeed\n");
431 EXPECT_FOREGROUND(data
[1].hWnd
);
434 SetForegroundWindow(data
[0].hWnd
);
435 SetActiveWindow(data
[1].hWnd
);
438 EXPECT_FOREGROUND(data
[0].hWnd
);
439 EXPECT_ACTIVE(data
[0].hWnd
);
441 /* attach thread 1 to 0 */
443 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, TRUE
);
444 ok(ret
==1, "expected AttachThreadInput to succeed\n");
447 EXPECT_FOREGROUND(data
[0].hWnd
);
448 EXPECT_ACTIVE(data
[0].hWnd
);
450 SetForegroundWindow(data
[0].hWnd
);
451 SetActiveWindow(data
[1].hWnd
);
454 EXPECT_FOREGROUND(data
[1].hWnd
);
455 EXPECT_ACTIVE(data
[1].hWnd
);
457 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, FALSE
);
458 ok(ret
==1, "expected AttachThreadInput to succeed\n");
462 /* test some functions like PostMessage and SendMessage that shouldn't be affected */
463 void Test_UnaffectedMessages()
468 EMPTY_CACHE_(&data
[0].cache
);
469 EMPTY_CACHE_(&data
[1].cache
);
471 /* test that messages posted before and after attachment are unaffected
472 and that we don't receive a meassage from a window we shouldn't */
473 PostMessage(data
[0].hWnd
, WM_USER
, 0,0);
474 PostMessage(data
[1].hWnd
, WM_USER
, 1,0);
477 MSG_ENTRY Thread0_chain
[]={
478 {0,WM_USER
, POST
, 0, 0},
479 {0,WM_USER
, POST
, 2, 0},
481 MSG_ENTRY Thread1_chain
[]={
482 {1,WM_USER
, POST
, 1, 0},
483 {1,WM_USER
, POST
, 3, 0},
486 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, TRUE
);
487 ok(ret
==1, "expected AttachThreadInput to succeed\n");
489 PostMessage(data
[0].hWnd
, WM_USER
, 2,0);
490 PostMessage(data
[1].hWnd
, WM_USER
, 3,0);
495 COMPARE_CACHE_(&data
[0].cache
, Thread0_chain
);
496 COMPARE_CACHE_(&data
[1].cache
, Thread1_chain
);
498 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, FALSE
);
499 ok(ret
==1, "expected AttachThreadInput to succeed\n");
502 /* test messages send to the wrong thread */
503 res
= SendMessageTimeout(data
[0].hWnd
, WM_USER
, 0,0, SMTO_NORMAL
, 1000, NULL
);
504 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
505 res
= SendMessageTimeout(data
[1].hWnd
, WM_USER
, 1,0, SMTO_NORMAL
, 1000, NULL
);
506 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
509 MSG_ENTRY Thread0_chain
[]={
510 {0,WM_USER
, SENT
, 0, 0},
511 {0,WM_USER
, SENT
, 2, 0},
513 MSG_ENTRY Thread1_chain
[]={
514 {1,WM_USER
, SENT
, 1, 0},
515 {1,WM_USER
, SENT
, 3, 0},
516 {1,WM_MOUSEMOVE
, SENT
, 0, 0},
519 ret
= AttachThreadInput( data
[2].tid
, data
[1].tid
, TRUE
);
520 ok(ret
==1, "expected AttachThreadInput to succeed\n");
522 res
= SendMessageTimeout(data
[0].hWnd
, WM_USER
, 2,0, SMTO_NORMAL
, 1000, NULL
);
523 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
524 res
= SendMessageTimeout(data
[1].hWnd
, WM_USER
, 3,0, SMTO_NORMAL
, 1000, NULL
);
525 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
527 /* Try to send a fake input message */
528 res
= SendMessageTimeout(data
[1].hWnd
, WM_MOUSEMOVE
, 0,0, SMTO_NORMAL
, 1000, NULL
);
529 ok (res
!= ERROR_TIMEOUT
, "SendMessageTimeout timed out\n");
531 COMPARE_CACHE_(&data
[0].cache
, Thread0_chain
);
532 COMPARE_CACHE_(&data
[1].cache
, Thread1_chain
);
534 ret
= AttachThreadInput( data
[2].tid
, data
[1].tid
, FALSE
);
535 ok(ret
==1, "expected AttachThreadInput to succeed\n");
538 /* todo: test keyboard layout that shouldn't be affected */
541 void Test_SendInput()
543 MSG_ENTRY Thread1_chain
[]={
544 {1,WM_KEYDOWN
, POST
, VK_SHIFT
, 0},
545 {1,WM_KEYUP
, POST
, VK_SHIFT
, 0},
547 MSG_ENTRY Thread0_chain
[]={
548 {0,WM_KEYDOWN
, POST
, VK_SHIFT
, 0},
549 {0,WM_KEYUP
, POST
, VK_SHIFT
, 0},
554 /* First try sending input without attaching. It will go to the foreground */
556 SetForegroundWindow(data
[1].hWnd
);
557 SetActiveWindow(data
[0].hWnd
);
559 ok(GetForegroundWindow() == data
[1].hWnd
, "wrong foreground\n");
560 ok(GetActiveWindow() == data
[0].hWnd
, "wrong active\n");
563 EMPTY_CACHE_(&data
[0].cache
);
564 EMPTY_CACHE_(&data
[1].cache
);
566 keybd_event(VK_SHIFT
, 0,0,0);
567 keybd_event(VK_SHIFT
, 0,KEYEVENTF_KEYUP
,0);
571 COMPARE_CACHE_(&data
[0].cache
, empty_chain
);
572 COMPARE_CACHE_(&data
[1].cache
, Thread1_chain
);
575 /* Next attach and send input. It will go to the same thread as before */
577 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, TRUE
);
578 ok(ret
==1, "expected AttachThreadInput to succeed\n");
581 EMPTY_CACHE_(&data
[0].cache
);
582 EMPTY_CACHE_(&data
[1].cache
);
584 keybd_event(VK_SHIFT
, 0,0,0);
585 keybd_event(VK_SHIFT
, 0,KEYEVENTF_KEYUP
,0);
589 COMPARE_CACHE_(&data
[0].cache
, empty_chain
);
590 COMPARE_CACHE_(&data
[1].cache
, Thread1_chain
);
593 /* Now set foregroung and active again. Input will go to thread 0 */
595 SetForegroundWindow(data
[1].hWnd
);
596 SetActiveWindow(data
[0].hWnd
);
599 EMPTY_CACHE_(&data
[0].cache
);
600 EMPTY_CACHE_(&data
[1].cache
);
602 keybd_event(VK_SHIFT
, 0,0,0);
603 keybd_event(VK_SHIFT
, 0,KEYEVENTF_KEYUP
,0);
607 COMPARE_CACHE_(&data
[0].cache
, Thread0_chain
);
608 COMPARE_CACHE_(&data
[1].cache
, empty_chain
);
610 ret
= AttachThreadInput( data
[1].tid
, data
[0].tid
, FALSE
);
611 ok(ret
==1, "expected AttachThreadInput to succeed\n");
614 /* Attach in the opposite order and send input */
616 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, TRUE
);
617 ok(ret
==1, "expected AttachThreadInput to succeed\n");
620 EMPTY_CACHE_(&data
[0].cache
);
621 EMPTY_CACHE_(&data
[1].cache
);
623 keybd_event(VK_SHIFT
, 0,0,0);
624 keybd_event(VK_SHIFT
, 0,KEYEVENTF_KEYUP
,0);
628 COMPARE_CACHE_(&data
[0].cache
, Thread0_chain
);
629 COMPARE_CACHE_(&data
[1].cache
, empty_chain
);
632 /* Now set foregroung and active again. Input will go to thread 0 */
634 SetForegroundWindow(data
[1].hWnd
);
635 SetActiveWindow(data
[0].hWnd
);
638 EMPTY_CACHE_(&data
[0].cache
);
639 EMPTY_CACHE_(&data
[1].cache
);
641 keybd_event(VK_SHIFT
, 0,0,0);
642 keybd_event(VK_SHIFT
, 0,KEYEVENTF_KEYUP
,0);
646 COMPARE_CACHE_(&data
[0].cache
, Thread0_chain
);
647 COMPARE_CACHE_(&data
[1].cache
, empty_chain
);
649 ret
= AttachThreadInput( data
[0].tid
, data
[1].tid
, FALSE
);
650 ok(ret
==1, "expected AttachThreadInput to succeed\n");
654 START_TEST(AttachThreadInput
)
659 win_skip("skip Test_SimpleParameters that crash ros\n");
660 //Test_SimpleParameters();
661 //cleanup_attachments();
663 cleanup_attachments();
664 Test_UnaffectedMessages();
665 cleanup_attachments();
667 cleanup_attachments();
670 UnhookWindowsHookEx(hMouseHookLL
);
672 UnhookWindowsHookEx(hKbdHookLL
);
674 /* Stop all threads and exit gratefully */
675 PostThreadMessage(data
[1].tid
, WM_QUIT
,0,0);
676 PostThreadMessage(data
[2].tid
, WM_QUIT
,0,0);
677 PostThreadMessage(data
[3].tid
, WM_QUIT
,0,0);
678 PostThreadMessage(data
[4].tid
, WM_QUIT
,0,0);