#include #include #include #include #include static void pump_messages(void) { MSG msg; while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessageA(&msg); } } int main(int argc, char *argv[]) { ATOM cls; HWND hWnd; WNDCLASSW wcex; HINSTANCE hInstance = GetModuleHandleA(NULL); IDirectInput8W *di8 = nullptr; LPDIRECTINPUTDEVICE8W keyboard = nullptr; DWORD start, loop = 0; memset(&wcex, 0, sizeof(wcex)); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = NULL; wcex.hInstance = hInstance; wcex.hIcon = LoadIconA(0, (LPCSTR)IDI_APPLICATION); wcex.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wcex.lpszClassName = L"HotplugTestClass"; cls = RegisterClassW(&wcex); assert(cls); hWnd = CreateWindowW(L"static", L"Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 100, 100, NULL, NULL, hInstance, NULL); assert(hWnd); ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); assert(SUCCEEDED(DirectInput8Create(GetModuleHandleW(nullptr), DIRECTINPUT_VERSION, IID_IDirectInput8W, (void**)&di8, nullptr))); assert(SUCCEEDED(di8->CreateDevice(GUID_SysKeyboard, &keyboard, nullptr))); assert(SUCCEEDED(keyboard->SetDataFormat(&c_dfDIKeyboard))); assert(SUCCEEDED(keyboard->SetCooperativeLevel(hWnd, DISCL_FOREGROUND|DISCL_NONEXCLUSIVE|DISCL_NOWINKEY))); DIPROPDWORD buffer_size; buffer_size.diph.dwSize = sizeof(buffer_size); buffer_size.diph.dwHeaderSize = sizeof(buffer_size.diph); buffer_size.diph.dwObj = 0; buffer_size.diph.dwHow = DIPH_DEVICE; buffer_size.dwData = 16; assert(SUCCEEDED(keyboard->SetProperty(DIPROP_BUFFERSIZE, &buffer_size.diph))); start = GetTickCount(); while (GetTickCount() - start < 20000) { DWORD inner_start = GetTickCount(); DWORD missed_start = 0; DWORD missed_after_first = 0; BOOL got_one = FALSE; DIDEVICEOBJECTDATA data[10]; loop++; assert(SUCCEEDED(keyboard->Acquire())); do { DWORD cnt = ARRAYSIZE(data); keybd_event(0, DIK_D, KEYEVENTF_SCANCODE, 0); pump_messages(); assert(SUCCEEDED(keyboard->GetDeviceData(sizeof(data[0]), data, &cnt, 0))); if (cnt == 0) { if (got_one) missed_after_first++; else missed_start++; } else { keybd_event(0, DIK_D, KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP, 0); got_one = TRUE; } } while (GetTickCount() - inner_start < 500); if (missed_start || missed_after_first) printf("%02d: missed after aquire %04d, after first sucesfull event: %04d\n", loop, missed_start, missed_after_first); assert(SUCCEEDED(keyboard->Unacquire())); } printf("completed %d acquire loops\n", loop); return 0; }