I tried to make a test case now. It's tested on wine-1.5.27 since I don't have enough battery to compile new wine.
$ winegcc test.c -o test
Issue1, the 0x40 bit: $ ./test.exe 00 00 00 00 00 00 00 00 *press LEFT arrow* 81 00 00 00 *release LEFT arrow* 01 00 00 00 *ALTTAB* 41 00 00 00
Issue2, LEFT ARROW remains pressed if released in another window. $ ./test.exe 00 00 00 00 *press LEFT ARROW* 81 00 00 00 *ALTTAB* c1 00 00 00 *RELEASE LEFT ARROW (outside Wine application)* c1 00 00 00 *ALTTAB BACK* c1 00 00 00 *press LEFT ARROW again (inside Wine application)* 41 00 00 00
test.c (also at http://pastie.org/7642788 if my mail client breaks it): // based on http://www.winprog.org/tutorial/simple_window.html #include <windows.h> #include <stdio.h>
static const char g_szClassName[] = "myWindowClass";
static void print_keyboard_state() { BYTE keystate[256]; GetKeyboardState(keystate); printf("%02x %02x %02x %02x\n", keystate[VK_LEFT], keystate[VK_UP], keystate[VK_RIGHT], keystate[VK_DOWN]); }
// Step 4: the Window Procedure static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { case WM_TIMER: print_keyboard_state(); break; case WM_CLOSE: DestroyWindow(hwnd); break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hwnd, msg, wParam, lParam); } return 0; }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wc; HWND hwnd; MSG Msg;
//Step 1: Registering the Window Class wc.cbSize = sizeof(WNDCLASSEX); wc.style = 0; wc.lpfnWndProc = WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wc.lpszMenuName = NULL; wc.lpszClassName = g_szClassName; wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) return 1;
// Step 2: Creating the Window hwnd = CreateWindowEx( WS_EX_CLIENTEDGE, g_szClassName, "The title of my window", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
if(hwnd == NULL) return 1;
ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd);
UINT id; SetTimer(hwnd, 0, 1000, NULL);
// Step 3: The Message Loop while(GetMessage(&Msg, NULL, 0, 0) > 0) { TranslateMessage(&Msg); DispatchMessage(&Msg); } return Msg.wParam; }