#include <Windows.h>
#include <stdio.h>
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:
{
long long int currentTime = GetTime();
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 = currentTime;
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 = currentTime;
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;
}