The Idea
I was wondering if it's possible to change the pitch of your mouse over the entire screen. To give an example: If you draw a perfect circle with your physical mouse on your table, your screen would draw an oval (with: width > height).
This could be useful if you e.g. used to have a customizable mouse that supported individual m_pitch settings but recently broke down and you can't afford a new one. You could use this program to virtualize those individual settings.
So I went to work and concocted this small program:
#include <windows.h>
#include <iostream>
#include <math.h>
using namespace std;
HHOOK hMouseHook;
bool prev_initialized = false;
bool real_input = true;
MOUSEHOOKSTRUCT prevMouseStruct;
double ratio = 0.5; //cursor should pitch 0.5x as fast as it normally would
double rest = 0;
LRESULT CALLBACK mouseProc (int nCode, WPARAM wParam, LPARAM lParam)
{
MOUSEHOOKSTRUCT * pMouseStruct = (MOUSEHOOKSTRUCT *)lParam;
if (pMouseStruct != NULL){
if(wParam == WM_MOUSEMOVE)
{
printf("Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x,pMouseStruct->pt.y);
if(prev_initialized && real_input){
int y_diff = prevMouseStruct.pt.y - pMouseStruct->pt.y;
if(y_diff != 0){
double ratiod_diff = ((double)y_diff) * ratio;
int rounded_diff = (int)round(ratiod_diff);
int newY = prevMouseStruct.pt.y - rounded_diff;
rest += ratiod_diff - rounded_diff;
if(rest > 1){
--rest;
++newY;
}else if(rest < -1){
++rest;
--newY;
}
real_input = false;
pMouseStruct->pt.y = newY;
SetCursorPos(pMouseStruct->pt.x, pMouseStruct->pt.y);
printf("New- Mouse position X = %d Mouse Position Y = %d\n", pMouseStruct->pt.x,newY);
}
}else if(!real_input){
real_input = true;
} else{
prevMouseStruct = *pMouseStruct;
prev_initialized = true;
}
}
}
return CallNextHookEx(hMouseHook, nCode, wParam, lParam);
}
int main()
{
HINSTANCE hInstance = GetModuleHandle(NULL);
hMouseHook = SetWindowsHookEx(WH_MOUSE_LL, mouseProc, hInstance, NULL);
MSG message;
while (GetMessage(&message,NULL,0,0)) {
TranslateMessage( &message );
DispatchMessage( &message );
}
UnhookWindowsHookEx(hMouseHook);
return 0;
}
How?
This program registers all mousemovement-events on the screen and remembers 2 coordinates:
- The previous mouse location; e.g.: POINT(100, 100)
- The current mouse location; e.g.: POINT(120,150) -> the mouse moved 20px to the right and 50px down
Then, I calculate where I want the cursor to be with the ratio (and some other fancy precision stuff). E.g.: the cursor moves 50px down and the ratio is 0.5 -> the mouse only goes 25px down.
Lastly, I call SetMousePos() with the new y-value to move the cursor to my desired location. (Note: I also try to make sure that this function does not call mouseProc() again by using the boolean real_input as a flag).
The problem
I am running into the following problem: the cursor is not staying at its new y-position. After calling the setMousePos()-function, the mouse shifts to its new position for a split second and then instantly reverts back to its former position. This leaves a makeshift 'afterimage' of the mouse. In this GIF, I move the cursor from the top to the bottom. You can see that it leaves it's after-image that grows larger in distance when you move further away from your starting-position (the starting-position is the position of your mouse when the console opens).
Any feedback would be MUCH appreciated!