#define _WIN32_WINNT 0x0501 #include #include static HINSTANCE g_hInstance; LRESULT CALLBACK hook_proc( int code, WPARAM wparam, LPARAM lparam ) { MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam; POINT pt; GetCursorPos(&pt); if (code == HC_ACTION) { printf("code=%d w=%p [(%ld %ld) %lx %lx %p] cur(%ld %ld) dl(%ld %ld)\n", code, wparam, hook->pt.x, hook->pt.y, hook->mouseData, hook->flags, hook->dwExtraInfo, pt.x, pt.y, hook->pt.x - pt.x, hook->pt.y - pt.y); } return CallNextHookEx( 0, code, wparam, lparam ); } #define SEND(x,y) \ i.mi.time = GetCurrentTime(); \ i.mi.dx = x; i.mi.dy = y; \ SendInput(1, &i, sizeof(INPUT)); inline void send_abs(int x, int y, LPINPUT i, LPPOINT pt) { int accel[3], xMult = 1, yMult = 1; int width = GetSystemMetrics(SM_CXSCREEN); int height = GetSystemMetrics(SM_CYSCREEN); SystemParametersInfoW(SPI_GETMOUSE, 0, accel, 0); if (abs(x) > accel[0] && accel[2] != 0) { if ((abs(x) > accel[1]) && (accel[2] == 2)) xMult = 4; else xMult = 2; } if (abs(y) > accel[0] && accel[2] != 0) { if ((abs(y) > accel[1]) && (accel[2] == 2)) yMult = 4; else yMult = 2; } i->mi.dx = ((pt->x + (long)(x) * xMult) << 16) / width; i->mi.dy = ((pt->y + (long)(y) * yMult) << 16) / height; i->mi.time = GetCurrentTime(); SendInput(1, i, sizeof(INPUT)); } void send_input(void) { INPUT i; POINT pt, ptorg; GetCursorPos(&ptorg); pt = ptorg; printf("Cur pos: %ld %ld\n", ptorg.x, ptorg.y); i.type = INPUT_MOUSE; i.mi.dwFlags = MOUSEEVENTF_MOVE; i.mi.dwExtraInfo = 0; i.mi.mouseData = 0; SEND(-4, 0) SEND(+4, 0) SEND(0, -4) SEND(0, +4) SetCursorPos(100, 100); GetCursorPos(&pt); fprintf(stderr, "Moved cursor to 100-100 cur(%ld %ld)\n", pt.x, pt.y); i.mi.dwFlags = MOUSEEVENTF_MOVE; SEND(-4, 0) i.mi.dwFlags |= MOUSEEVENTF_ABSOLUTE; send_abs(-10, 0, &i, &pt); send_abs(+10, 0, &i, &pt); /* Restopre position */ SetCursorPos(ptorg.x, ptorg.y); } void test1(void) { HHOOK hook; hook = SetWindowsHookExA(WH_MOUSE_LL, hook_proc, g_hInstance, 0); send_input(); UnhookWindowsHookEx(hook); } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; HWND hwnd; g_hInstance = hInstance; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = NULL; wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = "MainWindow"; wcex.hIconSm = NULL; RegisterClassEx(&wcex); hwnd = CreateWindow("MainWindow", "Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 200, 200, NULL, NULL, NULL, NULL); ShowWindow(hwnd, SW_SHOW); test1(); DestroyWindow(hwnd); return 0; }