2

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!

Im2be
  • 53
  • 2
  • 4

0 Answers0