Skip to content
Permalink
master
Go to file
 
 
Cannot retrieve contributors at this time
207 lines (174 sloc) 4.52 KB
#ifndef UNICODE
#define UNICODE
#endif
#include <Windows.h>
#include <Windowsx.h>
#include <stdio.h>
#include <limits.h>
#ifndef HID_USAGE_PAGE_GENERIC
#define HID_USAGE_PAGE_GENERIC ((USHORT) 0x01)
#endif
#ifndef HID_USAGE_GENERIC_MOUSE
#define HID_USAGE_GENERIC_MOUSE ((USHORT) 0x02)
#endif
typedef struct {
int count;
int total;
int minimum;
int maximum;
} Stats;
BOOL motionDetected;
int lastX;
int lastY;
Stats hStats, vStats;
Stats hRawStats, vRawStats;
char buffer1[128];
char buffer2[128];
void reset(Stats *stats)
{
stats->count = 0;
stats->total = 0;
stats->minimum = INT_MAX;
stats->maximum = 0;
}
void resetStats()
{
reset(&hStats);
reset(&vStats);
reset(&hRawStats);
reset(&vRawStats);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
const wchar_t CLASS_NAME[] = L"Window Class";
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = CLASS_NAME;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindowEx(
0, CLASS_NAME, L"Mouse Logger",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL);
RAWINPUTDEVICE devices[1];
devices[0].usUsagePage = HID_USAGE_PAGE_GENERIC;
devices[0].usUsage = HID_USAGE_GENERIC_MOUSE;
devices[0].dwFlags = RIDEV_INPUTSINK;
devices[0].hwndTarget = hWnd;
RegisterRawInputDevices(devices, 1, sizeof(devices[0]));
RECT rc;
GetWindowRect(hWnd, &rc) ;
SetWindowPos(hWnd, 0,
(GetSystemMetrics(SM_CXSCREEN) - rc.right) / 2,
(GetSystemMetrics(SM_CYSCREEN) - rc.bottom) / 2,
0, 0, SWP_NOZORDER | SWP_NOSIZE);
resetStats();
ShowWindow(hWnd, nCmdShow);
MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void doUpdate(Stats *stats, int value)
{
stats->count++;
stats->total += value;
if (value < stats->minimum) {
stats->minimum = value;
}
if (value > stats->maximum) {
stats->maximum = value;
}
}
void update(Stats *stats, int value)
{
if (value != 0) {
doUpdate(stats, abs(value));
}
}
void format(char *buffer, Stats *stats) {
sprintf(buffer, "% 2d <% 5.2f <% 3d",
stats->count == 0 ? 0 : stats->minimum,
stats->count == 0 ? 0.0 : ((double)stats->total / stats->count),
stats->maximum);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg) {
case WM_LBUTTONDOWN:
resetStats();
printf("Reset.\n");
break;
case WM_MOUSEMOVE: {
int x = GET_X_LPARAM(lParam);
int y = GET_Y_LPARAM(lParam);
if (!motionDetected) {
motionDetected = TRUE;
TRACKMOUSEEVENT tme = { sizeof(tme) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = hWnd;
TrackMouseEvent(&tme);
} else {
int dx = x - lastX;
int dy = y - lastY;
update(&hStats, dx);
update(&vStats, dy);
format(buffer1, &hStats);
format(buffer2, &vStats);
printf("OS\t%+d, %+d\t%s\t%s\n", dx, dy, buffer1, buffer2);
}
lastX = x;
lastY = y;
break;
}
case WM_MOUSELEAVE:
motionDetected = FALSE;
break;
case WM_MOUSEWHEEL: {
int delta = GET_WHEEL_DELTA_WPARAM(wParam);
printf(" OS WHEEL %+d (%+.2f)\n", delta, (double)delta / WHEEL_DELTA);
break;
}
case WM_INPUT: {
if (!motionDetected) break;
UINT dwSize = 40;
static BYTE lpb[40];
GetRawInputData((HRAWINPUT)lParam, RID_INPUT,
lpb, &dwSize, sizeof(RAWINPUTHEADER));
RAWINPUT* input = (RAWINPUT*)lpb;
if (input->header.dwType == RIM_TYPEMOUSE) {
int dx = input->data.mouse.lLastX;
int dy = input->data.mouse.lLastY;
if (dx != 0 || dy != 0) {
update(&hRawStats, dx);
update(&vRawStats, dy);
format(buffer1, &hRawStats);
format(buffer2, &vRawStats);
printf("RAW\t%+d, %+d\t%s\t%s\n", dx, dy, buffer1, buffer2);
}
if (input->data.mouse.usButtonFlags & RI_MOUSE_WHEEL) {
short delta = input->data.mouse.usButtonData;
printf("RAW WHEEL %d (%.2f)\n", delta, (double)delta / WHEEL_DELTA);
}
}
break;
}
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
FillRect(hdc, &ps.rcPaint, (HBRUSH) (COLOR_WINDOW + 1));
EndPaint(hWnd, &ps);
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
You can’t perform that action at this time.