Andrew Eikum : user32/tests: Add tests for SendInput with unicode.
Alexandre Julliard
julliard at winehq.org
Wed Aug 19 11:31:43 CDT 2009
Module: wine
Branch: master
Commit: 37754eb400d32a979c9c1d5f850847277f772d75
URL: http://source.winehq.org/git/wine.git/?a=commit;h=37754eb400d32a979c9c1d5f850847277f772d75
Author: Andrew Eikum <aeikum at codeweavers.com>
Date: Tue Aug 18 11:29:17 2009 -0500
user32/tests: Add tests for SendInput with unicode.
---
dlls/user32/tests/input.c | 230 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 230 insertions(+), 0 deletions(-)
diff --git a/dlls/user32/tests/input.c b/dlls/user32/tests/input.c
index 6ef7817..dfaf87e 100644
--- a/dlls/user32/tests/input.c
+++ b/dlls/user32/tests/input.c
@@ -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");
More information about the wine-cvs
mailing list