The MapVirtualKey in GetDeviceState is not "the way to do it". It does not map VK_?? to DIK_??. I don't know why it does work most of the time. "ptr[i] = 0x80; ptr[i + 0x80] = 0x80;" gave double key events in a game I have.
The correct way to convert the keys is by this table (attachment). I made this table by pressing all the keys on my keyboard, and record the keycodes.
The code I wrote for this function is:
static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState( LPDIRECTINPUTDEVICE2A iface, DWORD len, LPVOID ptr ) { DWORD i; memset( ptr, 0, len ); if (len != 256) { WARN("whoops, got len %ld?\n", len); return DI_OK; }
for (i = 0; i < (sizeof(vk_to_dik) / sizeof(vk_to_dik[0])); i++) if (GetAsyncKeyState( vk_to_dik[i][0] ) & 0x8000) ((LPBYTE)ptr)[ vk_to_dik[i][1] ] = 0x80;
return DI_OK; }
Is there an array_size() macro in wine? where should I put this table? Any other comments about my first usefull (at least for me) wine code?
unsigned char vk_to_dik[][2] = { {VK_BACK, DIK_BACK}, {VK_TAB, DIK_TAB}, {VK_CLEAR, DIK_NUMPAD5}, /* Num Lock off */ {VK_RETURN, DIK_NUMPADENTER}, {VK_SHIFT, DIK_LSHIFT}, {VK_CONTROL, DIK_LCONTROL}, {VK_MENU, DIK_LMENU}, {VK_CAPITAL, DIK_CAPITAL}, {VK_ESCAPE, DIK_ESCAPE}, {VK_SPACE, DIK_SPACE}, {VK_PRIOR, DIK_PRIOR}, {VK_NEXT, DIK_NEXT}, {VK_END, DIK_END}, {VK_HOME, DIK_HOME}, {VK_LEFT, DIK_LEFT}, {VK_UP, DIK_UP}, {VK_RIGHT, DIK_RIGHT}, {VK_DOWN, DIK_DOWN}, {VK_INSERT, DIK_INSERT}, {VK_DELETE, DIK_DELETE}, {VK_0, DIK_0}, {VK_1, DIK_1}, {VK_2, DIK_2}, {VK_3, DIK_3}, {VK_4, DIK_4}, {VK_5, DIK_5}, {VK_6, DIK_6}, {VK_7, DIK_7}, {VK_8, DIK_8}, {VK_9, DIK_9}, {VK_A, DIK_A}, {VK_B, DIK_B}, {VK_C, DIK_C}, {VK_D, DIK_D}, {VK_E, DIK_E}, {VK_F, DIK_F}, {VK_G, DIK_G}, {VK_H, DIK_H}, {VK_I, DIK_I}, {VK_J, DIK_J}, {VK_K, DIK_K}, {VK_L, DIK_L}, {VK_M, DIK_M}, {VK_N, DIK_N}, {VK_O, DIK_O}, {VK_P, DIK_P}, {VK_Q, DIK_Q}, {VK_R, DIK_R}, {VK_S, DIK_S}, {VK_T, DIK_T}, {VK_U, DIK_U}, {VK_V, DIK_V}, {VK_W, DIK_W}, {VK_X, DIK_X}, {VK_Y, DIK_Y}, {VK_Z, DIK_Z}, {VK_LWIN, DIK_LWIN}, {VK_RWIN, DIK_RWIN}, {VK_APPS, DIK_APPS}, {VK_NUMPAD0, DIK_NUMPAD0}, {VK_NUMPAD1, DIK_NUMPAD1}, {VK_NUMPAD2, DIK_NUMPAD2}, {VK_NUMPAD3, DIK_NUMPAD3}, {VK_NUMPAD4, DIK_NUMPAD4}, {VK_NUMPAD5, DIK_NUMPAD5}, /* Num Lock on */ {VK_NUMPAD6, DIK_NUMPAD6}, {VK_NUMPAD7, DIK_NUMPAD7}, {VK_NUMPAD8, DIK_NUMPAD8}, {VK_NUMPAD9, DIK_NUMPAD9}, {VK_MULTIPLY, DIK_MULTIPLY}, {VK_ADD, DIK_ADD}, {VK_SUBTRACT, DIK_SUBTRACT}, {VK_DECIMAL, DIK_DECIMAL}, {VK_DIVIDE, DIK_DIVIDE}, {VK_F1, DIK_F1}, {VK_F2, DIK_F2}, {VK_F3, DIK_F3}, {VK_F4, DIK_F4}, {VK_F5, DIK_F5}, {VK_F6, DIK_F6}, {VK_F7, DIK_F7}, {VK_F8, DIK_F8}, {VK_F9, DIK_F9}, {VK_F10, DIK_F10}, {VK_F11, DIK_F11}, {VK_F12, DIK_F12}, {VK_NUMLOCK, DIK_NUMLOCK}, {VK_SCROLL, DIK_SCROLL}, {VK_OEM_1, DIK_SEMICOLON}, {VK_OEM_PLUS, DIK_EQUALS}, {VK_OEM_COMMA, DIK_COMMA}, {VK_OEM_MINUS, DIK_MINUS}, {VK_OEM_PERIOD, DIK_PERIOD}, {VK_OEM_2, DIK_SLASH}, {VK_OEM_3, DIK_GRAVE}, {VK_OEM_4, DIK_LBRACKET}, {VK_OEM_5, DIK_BACKSLASH}, {VK_OEM_6, DIK_RBRACKET}, {VK_OEM_7, DIK_APOSTROPHE} };