#include #include struct Record { unsigned int Event, Key; long long int Time, Delta; }; Record Records[1000]; unsigned int Count = 1; long long int Time; bool Keys[255]; LARGE_INTEGER GetFrequency() { LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); return frequency; } long long int GetTime() { static LARGE_INTEGER frequency = GetFrequency(); LARGE_INTEGER counter; QueryPerformanceCounter(&counter); return (1000000 * counter.QuadPart / frequency.QuadPart); } LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { /* case WM_KEYDOWN: if ((lParam & (1 << 30)) == 0) { Records[Count].Event = 1; Records[Count].Key = wParam; Records[Count].Time = GetTime(); Records[Count].Delta = Records[Count].Time - Time; Time = Records[Count].Time; Count++; } break; case WM_KEYUP: Records[Count].Event = 0; Records[Count].Key = wParam; Records[Count].Time = GetTime(); Records[Count].Delta = Records[Count].Time - Time; Time = Records[Count].Time; Count++; break; */ case WM_INPUT: { unsigned int size; GetRawInputData((HRAWINPUT) lParam, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); unsigned char *data = new unsigned char[size]; GetRawInputData((HRAWINPUT) lParam, RID_INPUT, data, &size, sizeof(RAWINPUTHEADER)); RAWINPUT *raw = (RAWINPUT*) data; if (raw->header.dwType == RIM_TYPEKEYBOARD) { if (raw->data.keyboard.Flags & RI_KEY_BREAK) { if (Keys[raw->data.keyboard.MakeCode]) { Keys[raw->data.keyboard.MakeCode] = false; Records[Count].Event = 0; Records[Count].Key = raw->data.keyboard.MakeCode; Records[Count].Time = GetTime(); Records[Count].Delta = Records[Count].Time - Time; Time = Records[Count].Time; Count++; } } else { if (!Keys[raw->data.keyboard.MakeCode]) { Keys[raw->data.keyboard.MakeCode] = true; Records[Count].Event = 1; Records[Count].Key = raw->data.keyboard.MakeCode; Records[Count].Time = GetTime(); Records[Count].Delta = Records[Count].Time - Time; Time = Records[Count].Time; Count++; } } } break; } case WM_CLOSE: PostQuitMessage(EXIT_SUCCESS); return 0; } return DefWindowProc(hwnd, uMsg, wParam, lParam); } int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); TCHAR className[] = TEXT("Window"); WNDCLASS windowClass = {0}; windowClass.lpfnWndProc = WindowProc; windowClass.hInstance = hInstance; windowClass.lpszClassName = className; RegisterClass(&windowClass); HWND handle = CreateWindow(className, TEXT("Input"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480, 0, 0, hInstance, 0); RAWINPUTDEVICE rid[1] = {0}; rid[0].usUsagePage = 0x01; rid[0].usUsage = 0x06; rid[0].dwFlags = RIDEV_NOLEGACY; RegisterRawInputDevices(rid, 1, sizeof(rid[0])); ShowWindow(handle, nCmdShow); MSG message; while (GetMessage(&message, 0, 0, 0)) DispatchMessage(&message); DestroyWindow(handle); UnregisterClass(className, hInstance); for (unsigned int i = 1; i < Count; i++) printf("%s %d %lld %lld %s\n", Records[i].Event ? "press " : "release", Records[i].Key, Records[i].Time, Records[i].Delta, ((Records[i].Delta > 16000) && (Records[i].Event == Records[i - 1].Event)) ? "!" : ""); getchar(); FreeConsole(); return message.wParam; }