ReactOS  0.4.13-dev-482-ge57f103
AttachThreadInput.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS api tests
3  * LICENSE: GPL - See COPYING in the top level directory
4  * PURPOSE: Test for AttachThreadInput
5  * PROGRAMMERS: Giannis Adamopoulos
6  */
7 
8 #include "precomp.h"
9 
10 typedef struct {
18 
20 } THREAD_DATA;
21 
25 HHOOK hKbdHookLL = NULL;
26 
27 
28 #define EXPECT_FOREGROUND(expected) ok(GetForegroundWindow() == expected, \
29  "Expected hwnd%d at the foreground, got hwnd%d\n", \
30  get_iwnd(expected), get_iwnd(GetForegroundWindow()));
31 
32 #define EXPECT_ACTIVE(expected) ok(GetActiveWindow() == expected, \
33  "Expected hwnd%d to be active, got hwnd%d\n", \
34  get_iwnd(expected), get_iwnd(GetActiveWindow()));
35 
36 /*
37  * Helper functions
38  */
39 
40 static int get_iwnd(HWND hWnd)
41 {
42  if(hWnd == data[0].hWnd) return 0;
43  else if(hWnd == data[1].hWnd) return 1;
44  else if(hWnd == data[2].hWnd) return 2;
45  else if(hWnd == data[3].hWnd) return 3;
46  else if(hWnd == data[4].hWnd) return 4;
47  else return -1;
48 }
49 
51 {
52  int iwnd = get_iwnd(hWnd);
53 
54  if(iwnd >= 0 && message > 0 && message < WM_APP && message != WM_TIMER)
55  record_message(&data[iwnd].cache, iwnd, message, SENT, wParam,0);
56 
58 }
59 
60 static void FlushMessages()
61 {
62  MSG msg;
63  LRESULT res;
64 
65  while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
66  {
67  int iwnd = get_iwnd(msg.hwnd);
68  if( iwnd >= 0 && msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER)
69  record_message(&data[0].cache, iwnd, msg.message, POST, msg.wParam,0);
71  }
72 
73  /* Use SendMessage to sync with the other queues */
75  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
77  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
79  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
81  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
82 }
83 
85 {
86  THREAD_DATA* current_data = (THREAD_DATA*)param;
87  MSG msg;
88  HDESK hdesk = NULL;
89  int iwnd;
90 
91  if(current_data->Desktop)
92  {
93  hdesk = CreateDesktopW(current_data->Desktop, NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
94  SetThreadDesktop(hdesk);
95  }
96 
97  /* create test window */
98  current_data->hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW,
99  100, 100, 500, 500, NULL, NULL, 0, NULL);
100  SetEvent( current_data->StartEvent );
101 
102  iwnd = get_iwnd(current_data->hWnd);
103 
104  /* Use MsgWaitForMultipleObjects to let the thread process apcs */
105  while( GetMessage(&msg, 0,0,0) )
106  {
107  if(msg.message > 0 && msg.message < WM_APP && msg.message != WM_TIMER )
108  record_message(&data[iwnd].cache, iwnd, msg.message, POST, msg.wParam,0);
110  }
111 
112  if(hdesk)
113  CloseDesktop(hdesk);
114 
115  return 0;
116 }
117 
119 {
120  DWORD ret;
121 
122  data[i].StartEvent = CreateEventW(NULL, 0, 0, NULL);
123  data[i].Desktop = Desktop;
124  data[i].hThread = CreateThread(NULL, 0, thread_proc, &data[i], 0, &data[i].tid);
125  if(!data[i].hThread) goto fail;
128  if(ret == WAIT_TIMEOUT)
129  {
130 fail:
131  win_skip("child thread failed to initialize\n");
132  return FALSE;
133  }
134  return TRUE;
135 }
136 
138 {
139  LRESULT ret;
141 
143 
144  if((params->flags & LLKHF_INJECTED) == 0)
145  return TRUE;
146 
147  return ret;
148 }
149 
151 {
152  LRESULT ret;
154 
156 
157  if((params->flags & LLKHF_INJECTED) == 0)
158  return TRUE;
159 
160  return ret;
161 }
162 
164 {
165  /* Create a LL hook that drops any physical keyboard and mouse action
166  and prevent the user from interfering with the test results */
167  if(!IsDebuggerPresent())
168  {
170  ok(hMouseHookLL!=NULL,"failed to set hook\n");
172  ok(hKbdHookLL!=NULL,"failed to set hook\n");
173  }
174 
175  /* create test clases */
176  RegisterSimpleClass(TestProc, L"TestClass");
177 
178  memset(&data[0], 0, sizeof(data[0]));
179 
180  data[0].tid = GetCurrentThreadId();
181 
182  /* create test window */
183  data[0].hWnd = CreateWindowW(L"TestClass", L"test", WS_OVERLAPPEDWINDOW,
184  100, 100, 500, 500, NULL, NULL, 0, NULL);
185  if(!data[0].hWnd)
186  {
187  win_skip("CreateWindowW failed\n");
188  return FALSE;
189  }
190 
191  /* create thread1(same desktop) */
192  if(!CreateTestThread(1, NULL)) return FALSE;
193 
194  /* create thread2(same desktop) */
195  if(!CreateTestThread(2, NULL)) return FALSE;
196 
197  /* ugly ros hack to bypass desktop crapiness */
198  if(!CreateTestThread(6, L"ThreadTestDesktop")) return FALSE;
199 
200  /* create thread3(different desktop) */
201  if(!CreateTestThread(3, L"ThreadTestDesktop")) return FALSE;
202 
203  /* create thread4(different desktop) */
204  if(!CreateTestThread(4, L"ThreadTestDesktop")) return FALSE;
205 
206  return TRUE;
207 }
208 
209 static void cleanup_attachments()
210 {
211  int i,j;
212  BOOL ret;
213 
214  for(i = 0; i< 4; i++)
215  {
216  for(j = 0; j< 4; j++)
217  {
219  ok(ret==0, "expected AttachThreadInput to fail\n");
220  }
221  }
222 }
223 
224 
225 
226 
227 /*
228  * The actual tests
229  */
230 
232 {
233  BOOL ret;
234  /* FIXME: acording to msdn xp doesn't set last error but vista+ does*/
235 
236  /* test wrong thread */
237  ret = AttachThreadInput( 0, 1, TRUE);
238  ok(ret==0, "expected AttachThreadInput to fail\n");
239 
240  /* test same thread */
241  ret = AttachThreadInput( data[1].tid, data[1].tid, TRUE);
242  ok(ret==0, "expected AttachThreadInput to fail\n");
243 
244  /* try to attach to a thread on another desktop*/
246  ok(ret==0, "expected AttachThreadInput to fail\n");
247  if(ret == 1 )
249 
250  /* test other desktop to this */
252  ok(ret==0, "expected AttachThreadInput to fail\n");
253  if(ret == 1 )
255 
256  /* attach two threads that are both in ThreadTestDesktop */
257  {
258  /* Attach thread 3 and 4 */
260  ok(ret==1, "expected AttachThreadInput to succeed\n");
261 
262  /* cleanup previous attachment */
264  ok(ret==1, "expected AttachThreadInput to succeed\n");
265  }
266 
267  {
268  /* Attach thread 1 and 2 */
270  ok(ret==1, "expected AttachThreadInput to succeed\n");
271 
272  /* attach already attached*/
274  ok(ret==1, "expected AttachThreadInput to succeed\n");
275 
276  /* attach in the opposite order */
278  ok(ret==1, "expected AttachThreadInput to succeed\n");
279 
280  /* Now try to detach 0 from 1 */
282  ok(ret==0, "expected AttachThreadInput to fail\n");
283 
284  /* also try to detach 3 from 2 */
286  ok(ret==0, "expected AttachThreadInput to fail\n");
287 
288  /* cleanup previous attachment */
290  ok(ret==1, "expected AttachThreadInput to succeed\n");
291 
293  ok(ret==1, "expected AttachThreadInput to succeed\n");
294 
296  ok(ret==1, "expected AttachThreadInput to succeed\n");
297  }
298 
299  /* test triple attach */
300  {
301  ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE);
302  ok(ret==1, "expected AttachThreadInput to succeed\n");
303  ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE);
304  ok(ret==1, "expected AttachThreadInput to succeed\n");
305 
306  /* try to detach 2 and 0 */
307  ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE);
308  ok(ret==0, "expected AttachThreadInput to fail\n");
309  ret = AttachThreadInput( data[2].tid, data[0].tid, FALSE);
310  ok(ret==0, "expected AttachThreadInput to fail\n");
311 
312  /* try to to attach 0 to 2. it works! */
313  ret = AttachThreadInput( data[0].tid, data[2].tid, TRUE);
314  ok(ret==1, "expected AttachThreadInput to succeed\n");
315 
316  ret = AttachThreadInput( data[0].tid, data[2].tid, FALSE);
317  ok(ret==1, "expected AttachThreadInput to succeed\n");
318 
319  /* detach in inverse order */
320  ret = AttachThreadInput( data[0].tid, data[1].tid, FALSE);
321  ok(ret==1, "expected AttachThreadInput to succeed\n");
322  ret = AttachThreadInput( data[1].tid, data[2].tid, FALSE);
323  ok(ret==1, "expected AttachThreadInput to succeed\n");
324  }
325 
326  /* test detaching in thread cleanup */
327  {
328  ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE);
329  ok(ret==1, "expected AttachThreadInput to succeed\n");
330  ret = AttachThreadInput( data[0].tid, data[1].tid, TRUE);
331  ok(ret==1, "expected AttachThreadInput to succeed\n");
332  ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE);
333  ok(ret==1, "expected AttachThreadInput to succeed\n");
334  ret = AttachThreadInput( data[1].tid, data[2].tid, TRUE);
335  ok(ret==1, "expected AttachThreadInput to succeed\n");
336 
338 
339  ret = AttachThreadInput( data[0].tid, data[1].tid, FALSE);
340  ok(ret==0, "expected AttachThreadInput to fail\n");
341  ret = AttachThreadInput( data[1].tid, data[2].tid, FALSE);
342  ok(ret==0, "expected AttachThreadInput to fail\n");
343 
344  /* Create Thread1 again */
346  }
347 
348 }
349 
350 void Test_Focus() //Focus Active Capture Foreground Capture
351 {
352  BOOL ret;
353 
354  trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd);
355  /* Window 1 is in the foreground */
358  FlushMessages();
359 
361  EXPECT_ACTIVE(data[0].hWnd);
362 
363  /* attach thread 0 to 1 */
364  {
365  ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE);
366  ok(ret==1, "expected AttachThreadInput to succeed\n");
367  FlushMessages();
368 
370  EXPECT_ACTIVE(data[1].hWnd);
371 
372  ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE);
373  ok(ret==1, "expected AttachThreadInput to succeed\n");
374  }
375 
377  EXPECT_ACTIVE(0);
378 
381  FlushMessages();
382 
384  EXPECT_ACTIVE(data[0].hWnd);
385 
386  /* attach thread 1 to 0 */
387  {
388  ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE);
389  ok(ret==1, "expected AttachThreadInput to succeed\n");
390  FlushMessages();
391 
393  EXPECT_ACTIVE(data[1].hWnd);
394 
395  ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE);
396  ok(ret==1, "expected AttachThreadInput to succeed\n");
397  }
398 
399  /* Window 0 is in the foreground */
402  FlushMessages();
403 
405  EXPECT_ACTIVE(data[0].hWnd);
406 
407  /* attach thread 0 to 1 */
408  {
409  ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE);
410  ok(ret==1, "expected AttachThreadInput to succeed\n");
411  FlushMessages();
412 
414  EXPECT_ACTIVE(data[0].hWnd);
415 
418  FlushMessages();
419 
421  EXPECT_ACTIVE(data[1].hWnd);
422 
423  ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE);
424  ok(ret==1, "expected AttachThreadInput to succeed\n");
425  }
426 
428  EXPECT_ACTIVE(0);
429 
432  FlushMessages();
433 
435  EXPECT_ACTIVE(data[0].hWnd);
436 
437  /* attach thread 1 to 0 */
438  {
439  ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE);
440  ok(ret==1, "expected AttachThreadInput to succeed\n");
441  FlushMessages();
442 
444  EXPECT_ACTIVE(data[0].hWnd);
445 
448  FlushMessages();
449 
451  EXPECT_ACTIVE(data[1].hWnd);
452 
453  ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE);
454  ok(ret==1, "expected AttachThreadInput to succeed\n");
455  }
456 }
457 
458 /* test some functions like PostMessage and SendMessage that shouldn't be affected */
460 {
461  BOOL ret;
462  LRESULT res;
463 
464  EMPTY_CACHE_(&data[0].cache);
465  EMPTY_CACHE_(&data[1].cache);
466 
467  /* test that messages posted before and after attachment are unaffected
468  and that we don't receive a meassage from a window we shouldn't */
469  PostMessage(data[0].hWnd, WM_USER, 0,0);
470  PostMessage(data[1].hWnd, WM_USER, 1,0);
471 
472  {
473  MSG_ENTRY Thread0_chain[]={
474  {0,WM_USER, POST, 0, 0},
475  {0,WM_USER, POST, 2, 0},
476  {0,0}};
477  MSG_ENTRY Thread1_chain[]={
478  {1,WM_USER, POST, 1, 0},
479  {1,WM_USER, POST, 3, 0},
480  {0,0}};
481 
482  ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE);
483  ok(ret==1, "expected AttachThreadInput to succeed\n");
484 
485  PostMessage(data[0].hWnd, WM_USER, 2,0);
486  PostMessage(data[1].hWnd, WM_USER, 3,0);
487 
488  FlushMessages();
489  Sleep(100);
490 
491  COMPARE_CACHE_(&data[0].cache, Thread0_chain);
492  COMPARE_CACHE_(&data[1].cache, Thread1_chain);
493 
494  ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE);
495  ok(ret==1, "expected AttachThreadInput to succeed\n");
496  }
497 
498  /* test messages send to the wrong thread */
499  res = SendMessageTimeout(data[0].hWnd, WM_USER, 0,0, SMTO_NORMAL, 1000, NULL);
500  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
501  res = SendMessageTimeout(data[1].hWnd, WM_USER, 1,0, SMTO_NORMAL, 1000, NULL);
502  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
503 
504  {
505  MSG_ENTRY Thread0_chain[]={
506  {0,WM_USER, SENT, 0, 0},
507  {0,WM_USER, SENT, 2, 0},
508  {0,0}};
509  MSG_ENTRY Thread1_chain[]={
510  {1,WM_USER, SENT, 1, 0},
511  {1,WM_USER, SENT, 3, 0},
512  {1,WM_MOUSEMOVE, SENT, 0, 0},
513  {0,0}};
514 
515  ret = AttachThreadInput( data[2].tid, data[1].tid , TRUE);
516  ok(ret==1, "expected AttachThreadInput to succeed\n");
517 
518  res = SendMessageTimeout(data[0].hWnd, WM_USER, 2,0, SMTO_NORMAL, 1000, NULL);
519  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
520  res = SendMessageTimeout(data[1].hWnd, WM_USER, 3,0, SMTO_NORMAL, 1000, NULL);
521  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
522 
523  /* Try to send a fake input message */
525  ok (res != ERROR_TIMEOUT, "SendMessageTimeout timed out\n");
526 
527  COMPARE_CACHE_(&data[0].cache, Thread0_chain);
528  COMPARE_CACHE_(&data[1].cache, Thread1_chain);
529 
530  ret = AttachThreadInput( data[2].tid, data[1].tid , FALSE);
531  ok(ret==1, "expected AttachThreadInput to succeed\n");
532  }
533 
534  /* todo: test keyboard layout that shouldn't be affected */
535 }
536 
538 {
539  MSG_ENTRY Thread1_chain[]={
540  {1,WM_KEYDOWN, POST, VK_SHIFT, 0},
541  {1,WM_KEYUP, POST, VK_SHIFT, 0},
542  {0,0}};
543  MSG_ENTRY Thread0_chain[]={
544  {0,WM_KEYDOWN, POST, VK_SHIFT, 0},
545  {0,WM_KEYUP, POST, VK_SHIFT, 0},
546  {0,0}};
547 
548  BOOL ret;
549 
550  //trace("Thread hWnd0 0x%p hWnd1 0x%p\n",data[0].hWnd, data[1].hWnd);
551 
552  /* First try sending input without attaching. It will go to the foreground */
553  {
556 
557  ok(GetForegroundWindow() == data[1].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
558  ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
559 
560  FlushMessages();
561  EMPTY_CACHE_(&data[0].cache);
562  EMPTY_CACHE_(&data[1].cache);
563 
564  keybd_event(VK_SHIFT, 0,0,0);
566  Sleep(100);
567  FlushMessages();
568 
570  COMPARE_CACHE_(&data[1].cache, Thread1_chain);
571  }
572 
573  /* Next attach and send input. It will go to the same thread as before */
574  { // from to
575  ret = AttachThreadInput( data[1].tid, data[0].tid , TRUE);
576  ok(ret==1, "expected AttachThreadInput to succeed\n");
577 
578  FlushMessages();
579  EMPTY_CACHE_(&data[0].cache);
580  EMPTY_CACHE_(&data[1].cache);
581 
582  keybd_event(VK_SHIFT, 0,0,0);
584  Sleep(100);
585  FlushMessages();
586 
588  COMPARE_CACHE_(&data[1].cache, Thread1_chain);
589  }
590 
591  /* Now set foreground and active again. Input will go to thread 0 */
592  {
595  FlushMessages();
596 
597  ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
598  ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
599 
600  EMPTY_CACHE_(&data[0].cache);
601  EMPTY_CACHE_(&data[1].cache);
602 
603  keybd_event(VK_SHIFT, 0,0,0);
605  Sleep(100);
606  FlushMessages();
607 
608  COMPARE_CACHE_(&data[0].cache, Thread0_chain);
610 
611  ret = AttachThreadInput( data[1].tid, data[0].tid , FALSE);
612  ok(ret==1, "expected AttachThreadInput to succeed\n");
613  }
614 
615  /* Attach in the opposite order and send input */
616  {
617  ret = AttachThreadInput( data[0].tid, data[1].tid , TRUE);
618  ok(ret==1, "expected AttachThreadInput to succeed\n");
619 
620  FlushMessages();
621  EMPTY_CACHE_(&data[0].cache);
622  EMPTY_CACHE_(&data[1].cache);
623 
624  keybd_event(VK_SHIFT, 0,0,0);
626  Sleep(100);
627  FlushMessages();
628 
629  COMPARE_CACHE_(&data[0].cache, Thread0_chain);
631  }
632 
633  /* Now set foreground and active again. Input will go to thread 0 */
634  {
637  FlushMessages();
638 
639  ok(GetForegroundWindow() == data[0].hWnd, "wrong foreground got 0x%p\n",GetForegroundWindow());
640  ok(GetActiveWindow() == data[0].hWnd, "wrong active got 0x%p\n",GetActiveWindow());
641 
642  EMPTY_CACHE_(&data[0].cache);
643  EMPTY_CACHE_(&data[1].cache);
644 
645  keybd_event(VK_SHIFT, 0,0,0);
647  Sleep(100);
648  FlushMessages();
649 
650  COMPARE_CACHE_(&data[0].cache, Thread0_chain);
652 
653  ret = AttachThreadInput( data[0].tid, data[1].tid , FALSE);
654  ok(ret==1, "expected AttachThreadInput to succeed\n");
655  }
656 }
657 
659 {
660  if(!InitThreads())
661  return;
662 
665  Test_Focus();
669  Test_SendInput();
671 
672  if(hMouseHookLL)
674  if(hKbdHookLL)
676 
677  /* Stop all threads and exit gratefully */
682 }
683 
BOOL WINAPI IsDebuggerPresent(VOID)
Definition: debugger.c:615
Definition: cache.c:46
#define trace(...)
Definition: kmt_test.h:217
#define DispatchMessage
Definition: winuser.h:5631
LRESULT WINAPI DispatchMessageA(_In_ const MSG *)
Definition: tftpd.h:59
#define PeekMessage
Definition: winuser.h:5696
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
BOOL WINAPI TerminateThread(IN HANDLE hThread, IN DWORD dwExitCode)
Definition: thread.c:548
BOOL WINAPI AttachThreadInput(_In_ DWORD, _In_ DWORD, _In_ BOOL)
#define KEYEVENTF_KEYUP
Definition: winuser.h:1092
Definition: msgtrace.h:14
#define EXPECT_FOREGROUND(expected)
#define EXPECT_ACTIVE(expected)
#define ERROR_TIMEOUT
Definition: winerror.h:941
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1827
static DWORD WINAPI thread_proc(void *param)
#define CALLBACK
Definition: compat.h:27
HWND hWnd
Definition: settings.c:17
#define WM_QUIT
Definition: winuser.h:1605
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
LRESULT CALLBACK KbdLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
UINT_PTR WPARAM
Definition: windef.h:207
#define CreateWindowW(a, b, c, d, e, f, g, h, i, j, k)
Definition: winuser.h:4185
WPARAM wParam
Definition: combotst.c:138
void Test_Focus()
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
#define SMTO_NORMAL
Definition: winuser.h:1211
BOOL WINAPI SetThreadDesktop(_In_ HDESK)
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define WH_MOUSE_LL
Definition: winuser.h:44
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
HWND WINAPI SetActiveWindow(_In_ HWND)
GLenum const GLfloat * params
Definition: glext.h:5645
#define EMPTY_CACHE_(cache)
Definition: msgtrace.h:64
unsigned int BOOL
Definition: ntddk_ex.h:94
START_TEST(AttachThreadInput)
#define ok(value,...)
#define VK_SHIFT
Definition: winuser.h:2156
unsigned char BOOLEAN
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:111
smooth NULL
Definition: ftsmooth.c:416
DWORD tidMouseMove
#define WM_KEYDOWN
Definition: winuser.h:1691
LONG_PTR LPARAM
Definition: windef.h:208
static void FlushMessages()
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
DWORD WINAPI GetCurrentThreadId(VOID)
Definition: thread.c:420
#define DefWindowProc
Definition: ros2win.h:31
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
#define PostMessage
Definition: winuser.h:5698
static __inline ATOM RegisterSimpleClass(WNDPROC lpfnWndProc, LPCWSTR lpszClassName)
BOOL CreateTestThread(int i, WCHAR *Desktop)
void record_message(MSG_CACHE *cache, int iwnd, UINT message, MSG_TYPE type, int param1, int param2)
Definition: msgtrace.c:179
void Test_SimpleParameters()
HHOOK hKbdHookLL
#define WH_KEYBOARD_LL
Definition: winuser.h:43
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SendMessageTimeout
Definition: winuser.h:5711
VOID WINAPI keybd_event(_In_ BYTE, _In_ BYTE, _In_ DWORD, _In_ ULONG_PTR)
#define WM_TIMER
Definition: winuser.h:1718
#define PostThreadMessage
Definition: winuser.h:5699
GLfloat param
Definition: glext.h:5796
#define WINAPI
Definition: msvc.h:8
#define WM_KEYUP
Definition: winuser.h:1692
unsigned long DWORD
Definition: ntddk_ex.h:95
static LRESULT CALLBACK MouseLLHookProc(int nCode, WPARAM wParam, LPARAM lParam)
HANDLE QueueStatusEvent
#define COMPARE_CACHE_(cache, msg_chain)
Definition: msgtrace.h:62
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
BOOLEAN InitThreads()
#define WAIT_TIMEOUT
Definition: dderror.h:14
LRESULT CALLBACK TestProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
#define LLKHF_INJECTED
Definition: winuser.h:2600
int ret
Definition: msgtrace.h:7
static const WCHAR L[]
Definition: oid.c:1250
void Test_SendInput()
#define WM_APP
Definition: eventvwr.h:70
void Test_UnaffectedMessages()
#define WM_USER
Definition: winuser.h:1856
BOOL WINAPI UnhookWindowsHookEx(_In_ HHOOK)
#define DESKTOP_ALL_ACCESS
Definition: precomp.h:20
LRESULT WINAPI CallNextHookEx(_In_opt_ HHOOK, _In_ int, _In_ WPARAM, _In_ LPARAM)
static int get_iwnd(HWND hWnd)
HANDLE StartEvent
Definition: thmsvc.c:26
unsigned int UINT
Definition: ndis.h:50
#define WM_MOUSEMOVE
Definition: winuser.h:1751
HWND WINAPI GetForegroundWindow(void)
Definition: ntwrapper.h:392
#define GetMessage
Definition: winuser.h:5656
HANDLE hThread
Definition: wizard.c:27
Definition: msgtrace.h:6
static void cleanup_attachments()
#define msg(x)
Definition: auth_time.c:54
HHOOK WINAPI SetWindowsHookExW(_In_ int, _In_ HOOKPROC, _In_opt_ HINSTANCE, _In_ DWORD)
GLuint res
Definition: glext.h:9613
BOOL WINAPI CloseDesktop(_In_ HDESK)
#define WS_OVERLAPPEDWINDOW
Definition: pedump.c:637
HMODULE WINAPI GetModuleHandleW(LPCWSTR lpModuleName)
Definition: loader.c:845
HHOOK hMouseHookLL
BOOL WINAPI SetForegroundWindow(_In_ HWND)
#define PM_REMOVE
Definition: winuser.h:1182
HDESK WINAPI CreateDesktopW(LPCWSTR lpszDesktop, LPCWSTR lpszDevice, LPDEVMODEW pDevmode, DWORD dwFlags, ACCESS_MASK dwDesiredAccess, LPSECURITY_ATTRIBUTES lpsa)
Definition: desktop.c:473
LONG_PTR LRESULT
Definition: windef.h:209
MSG_CACHE cache
#define memset(x, y, z)
Definition: compat.h:39
MSG_ENTRY empty_chain[]
Definition: msgtrace.c:20
#define win_skip
Definition: test.h:141
static TfClientId tid
LPARAM lParam
Definition: combotst.c:139
HWND WINAPI GetActiveWindow(void)
Definition: winpos.c:138