user32/tests: Add tests for SendInput with unicode.

This commit is contained in:
Andrew Eikum 2009-08-18 11:29:17 -05:00 committed by Alexandre Julliard
parent f9e7c3f4ba
commit 37754eb400
1 changed files with 230 additions and 0 deletions

View File

@ -60,6 +60,20 @@
static HWND hWndTest;
static LONG timetag = 0x10000000;
static struct {
LONG last_key_down;
LONG last_key_up;
LONG last_syskey_down;
LONG last_syskey_up;
LONG last_char;
LONG last_syschar;
LONG last_hook_down;
LONG last_hook_up;
LONG last_hook_syskey_down;
LONG last_hook_syskey_up;
BOOL expect_alt;
} key_status;
static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
static int (WINAPI *pGetMouseMovePointsEx) (UINT, LPMOUSEMOVEPOINT, LPMOUSEMOVEPOINT, int, DWORD);
@ -923,6 +937,221 @@ static void test_Input_blackbox(void)
UnhookWindowsHookEx(hook);
}
static void reset_key_status(void)
{
key_status.last_key_down = -1;
key_status.last_key_up = -1;
key_status.last_syskey_down = -1;
key_status.last_syskey_up = -1;
key_status.last_char = -1;
key_status.last_syschar = -1;
key_status.last_hook_down = -1;
key_status.last_hook_up = -1;
key_status.last_hook_syskey_down = -1;
key_status.last_hook_syskey_up = -1;
key_status.expect_alt = FALSE;
}
static void test_unicode_keys(HWND hwnd, HHOOK hook)
{
TEST_INPUT inputs[2];
MSG msg;
/* init input data that never changes */
inputs[1].type = inputs[0].type = INPUT_KEYBOARD;
inputs[1].u.ki.dwExtraInfo = inputs[0].u.ki.dwExtraInfo = 0;
inputs[1].u.ki.time = inputs[0].u.ki.time = 0;
/* pressing & releasing a single unicode character */
inputs[0].u.ki.wVk = 0;
inputs[0].u.ki.wScan = 0x3c0;
inputs[0].u.ki.dwFlags = KEYEVENTF_UNICODE;
reset_key_status();
SendInput(1, (INPUT*)inputs, sizeof(INPUT));
while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
TranslateMessage(&msg);
}
DispatchMessageW(&msg);
}
ok(key_status.last_key_down == VK_PACKET,
"Last keydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_down);
ok(key_status.last_char == 0x3c0,
"Last char msg wparam should have been 0x3c0 (was: 0x%x)\n", key_status.last_char);
if(hook)
ok(key_status.last_hook_down == 0x3c0,
"Last hookdown msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_down);
inputs[1].u.ki.wVk = 0;
inputs[1].u.ki.wScan = 0x3c0;
inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
reset_key_status();
SendInput(1, (INPUT*)(inputs+1), sizeof(INPUT));
while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
if(msg.message == WM_KEYDOWN && msg.wParam == VK_PACKET){
TranslateMessage(&msg);
}
DispatchMessageW(&msg);
}
ok(key_status.last_key_up == VK_PACKET,
"Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
if(hook)
ok(key_status.last_hook_up == 0x3c0,
"Last hookup msg should have been 0x3c0, was: 0x%x\n", key_status.last_hook_up);
/* holding alt, pressing & releasing a unicode character, releasing alt */
inputs[0].u.ki.wVk = VK_LMENU;
inputs[0].u.ki.wScan = 0;
inputs[0].u.ki.dwFlags = 0;
inputs[1].u.ki.wVk = 0;
inputs[1].u.ki.wScan = 0x3041;
inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE;
reset_key_status();
key_status.expect_alt = TRUE;
SendInput(2, (INPUT*)inputs, sizeof(INPUT));
while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
TranslateMessage(&msg);
}
DispatchMessageW(&msg);
}
ok(key_status.last_syskey_down == VK_PACKET,
"Last syskeydown msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_syskey_down);
ok(key_status.last_syschar == 0x3041,
"Last syschar msg should have been 0x3041 (was: 0x%x)\n", key_status.last_syschar);
if(hook)
ok(key_status.last_hook_syskey_down == 0x3041,
"Last hooksysdown msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_syskey_down);
inputs[1].u.ki.wVk = 0;
inputs[1].u.ki.wScan = 0x3041;
inputs[1].u.ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
inputs[0].u.ki.wVk = VK_LMENU;
inputs[0].u.ki.wScan = 0;
inputs[0].u.ki.dwFlags = KEYEVENTF_KEYUP;
reset_key_status();
key_status.expect_alt = TRUE;
SendInput(2, (INPUT*)inputs, sizeof(INPUT));
while(PeekMessageW(&msg, hwnd, 0, 0, PM_REMOVE)){
if(msg.message == WM_SYSKEYDOWN && msg.wParam == VK_PACKET){
TranslateMessage(&msg);
}
DispatchMessageW(&msg);
}
ok(key_status.last_key_up == VK_PACKET,
"Last keyup msg should have been VK_PACKET[0x%04x] (was: 0x%x)\n", VK_PACKET, key_status.last_key_up);
if(hook)
ok(key_status.last_hook_up == 0x3041,
"Last hook up msg should have been 0x3041, was: 0x%x\n", key_status.last_hook_up);
}
static LRESULT CALLBACK unicode_wnd_proc( HWND hWnd, UINT msg, WPARAM wParam,
LPARAM lParam )
{
switch(msg){
case WM_KEYDOWN:
key_status.last_key_down = wParam;
break;
case WM_SYSKEYDOWN:
key_status.last_syskey_down = wParam;
break;
case WM_KEYUP:
key_status.last_key_up = wParam;
break;
case WM_SYSKEYUP:
key_status.last_syskey_up = wParam;
break;
case WM_CHAR:
key_status.last_char = wParam;
break;
case WM_SYSCHAR:
key_status.last_syschar = wParam;
break;
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
static LRESULT CALLBACK llkbd_unicode_hook(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode == HC_ACTION){
LPKBDLLHOOKSTRUCT info = (LPKBDLLHOOKSTRUCT)lParam;
ok(info->vkCode == VK_PACKET || (key_status.expect_alt && info->vkCode == VK_LMENU), "vkCode should have been VK_PACKET[%04x], was: %04x\n", VK_PACKET, info->vkCode);
key_status.expect_alt = FALSE;
switch(wParam){
case WM_KEYDOWN:
key_status.last_hook_down = info->scanCode;
break;
case WM_KEYUP:
key_status.last_hook_up = info->scanCode;
break;
case WM_SYSKEYDOWN:
key_status.last_hook_syskey_down = info->scanCode;
break;
case WM_SYSKEYUP:
key_status.last_hook_syskey_up = info->scanCode;
break;
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
static void test_Input_unicode(void)
{
WCHAR classNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
'K','e','y','T','e','s','t','C','l','a','s','s',0};
WCHAR windowNameW[] = {'I','n','p','u','t','U','n','i','c','o','d','e',
'K','e','y','T','e','s','t',0};
MSG msg;
WNDCLASSW wclass;
HANDLE hInstance = GetModuleHandleW(NULL);
HHOOK hook;
wclass.lpszClassName = classNameW;
wclass.style = CS_HREDRAW | CS_VREDRAW;
wclass.lpfnWndProc = unicode_wnd_proc;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(0, IDI_APPLICATION);
wclass.hCursor = LoadCursor( NULL, IDC_ARROW);
wclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wclass.lpszMenuName = 0;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
RegisterClassW(&wclass);
/* create the test window that will receive the keystrokes */
hWndTest = CreateWindowW(wclass.lpszClassName, windowNameW,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100,
NULL, NULL, hInstance, NULL);
assert(hWndTest);
assert(IsWindowUnicode(hWndTest));
hook = SetWindowsHookExW(WH_KEYBOARD_LL, llkbd_unicode_hook, GetModuleHandleW(NULL), 0);
if(!hook)
win_skip("unable to set WH_KEYBOARD_LL hook\n");
ShowWindow(hWndTest, SW_SHOW);
SetWindowPos(hWndTest, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE);
SetForegroundWindow(hWndTest);
UpdateWindow(hWndTest);
/* flush pending messages */
while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageW(&msg);
SetFocus(hWndTest);
test_unicode_keys(hWndTest, hook);
if(hook)
UnhookWindowsHookEx(hook);
DestroyWindow(hWndTest);
}
static void test_keynames(void)
{
int i, len;
@ -1320,6 +1549,7 @@ START_TEST(input)
{
test_Input_blackbox();
test_Input_whitebox();
test_Input_unicode();
}
else win_skip("SendInput is not available\n");