1 /*
2  * PROJECT:         ReactOS api tests
3  * LICENSE:         GPL - See COPYING in the top level directory
4  * PURPOSE:         Test for GetKeyState
5  * PROGRAMMERS:     Giannis Adamopoulos
6  */
7 
8 #include "precomp.h"
9 
10 static HHOOK hKbdHook, hKbdLLHook;
11 
KeyboardProc(int code,WPARAM wParam,LPARAM lParam)12 LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam,  LPARAM lParam)
13 {
14     BOOL pressed = !(lParam & (1<<31));
15 	BOOL altPressed = lParam & (1<<29);
16 
17     if(pressed)
18 	{
19 	    ok(altPressed,"\n");
20 	    ok((GetKeyState(VK_MENU) & 0x8000), "Alt should not be pressed\n");\
21 		ok((GetKeyState(VK_LMENU) & 0x8000), "Left alt should not be pressed\n");\
22 	}
23 	else
24 	{
25 	    ok(!altPressed,"\n");
26 	    ok(!(GetKeyState(VK_MENU) & 0x8000), "Alt should be pressed\n");
27 	    ok(!(GetKeyState(VK_LMENU) & 0x8000), "Left alt should be pressed\n");
28 	}
29 
30     return CallNextHookEx(hKbdHook, code, wParam, lParam);
31 }
32 
LowLevelKeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)33 LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
34 {
35     PKBDLLHOOKSTRUCT pLLHook = (PKBDLLHOOKSTRUCT)lParam;
36 
37     if(wParam == WM_SYSKEYDOWN)
38 	{
39 	    ok(pLLHook->flags & LLKHF_ALTDOWN,"Didn't get LLKHF_ALTDOWN flag\n");
40 		ok((GetAsyncKeyState (VK_MENU) & 0x8000), "Alt should not be pressed in global kbd status\n");
41 	    ok(!(GetKeyState(VK_MENU) & 0x8000), "Alt should not be pressed in queue state\n");
42 		ok(!(GetAsyncKeyState (VK_LMENU) & 0x8000), "Left alt should not be pressed in global kbd status\n");
43 	    ok(!(GetKeyState(VK_LMENU) & 0x8000), "Left alt should not be pressed in queue state\n");
44 	}
45 	else if(wParam == WM_SYSKEYUP)
46 	{
47 	    ok(!(pLLHook->flags & LLKHF_ALTDOWN),"got LLKHF_ALTDOWN flag\n");
48 		ok(!(GetAsyncKeyState (VK_MENU) & 0x8000), "Alt should not be pressed in global kbd status\n");
49 	    ok((GetKeyState(VK_MENU) & 0x8000), "Alt should be pressed in queue state\n");
50 		ok(!(GetAsyncKeyState (VK_LMENU) & 0x8000), "Left alt should not be pressed in global kbd status\n");
51 	    ok((GetKeyState(VK_LMENU) & 0x8000), "Left alt should be pressed in queue state\n");
52 	}
53 
54 	return CallNextHookEx(hKbdLLHook, nCode, wParam, lParam);
55 }
56 
WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)57 static LRESULT CALLBACK WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
58 {
59     if(msg == WM_SYSKEYDOWN)
60 	{
61 	    ok(wParam == VK_MENU, "Got wrong wParam in WM_SYSKEYDOWN (%d instead of %d)\n", wParam, VK_MENU );
62 	}
63     return DefWindowProcA( hWnd, msg, wParam, lParam );
64 }
65 
CreateTestWindow()66 static HWND CreateTestWindow()
67 {
68     MSG msg;
69     WNDCLASSA  wclass;
70     HANDLE hInstance = GetModuleHandleA( NULL );
71     HWND hWndTest;
72 
73     wclass.lpszClassName = "InputSysKeyTestClass";
74     wclass.style         = CS_HREDRAW | CS_VREDRAW;
75     wclass.lpfnWndProc   = WndProc;
76     wclass.hInstance     = hInstance;
77     wclass.hIcon         = LoadIconA( 0, IDI_APPLICATION );
78     wclass.hCursor       = LoadCursorA( NULL, IDC_ARROW );
79     wclass.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
80     wclass.lpszMenuName = 0;
81     wclass.cbClsExtra    = 0;
82     wclass.cbWndExtra    = 0;
83     RegisterClassA( &wclass );
84     /* create the test window that will receive the keystrokes */
85     hWndTest = CreateWindowA( wclass.lpszClassName, "InputSysKeyTest",
86                               WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
87                               NULL, NULL, hInstance, NULL);
88     assert( hWndTest );
89     ShowWindow( hWndTest, SW_SHOW);
90     SetWindowPos( hWndTest, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE );
91     SetForegroundWindow( hWndTest );
92     UpdateWindow( hWndTest);
93 
94     /* flush pending messages */
95     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
96 
97 	return hWndTest;
98 }
99 
Test_GetKeyState()100 void Test_GetKeyState()
101 {
102 	HWND hwnd;
103     MSG msg;
104 
105 	hwnd = CreateTestWindow();
106 
107 	hKbdHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, GetModuleHandleA( NULL ), 0);
108 	hKbdLLHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandleA( NULL ), 0);
109 
110 	ok(hKbdHook != NULL, "\n");
111 	ok(hKbdLLHook != NULL, "\n");
112 
113 	keybd_event(VK_LMENU, 0, 0,0);
114 
115 	while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
116 
117 	keybd_event(VK_LMENU, 0, KEYEVENTF_KEYUP,0);
118 
119 	//fixme this hangs the test
120     //while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE|PM_NOYIELD )) DispatchMessageA( &msg );
121 
122 	DestroyWindow(hwnd);
123 
124     while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
125 
126 	UnhookWindowsHookEx (hKbdHook);
127 	UnhookWindowsHookEx (hKbdLLHook);
128 }
129 
START_TEST(GetKeyState)130 START_TEST(GetKeyState)
131 {
132     Test_GetKeyState();
133 }
134