1

So I cannot find anything to help me with this issue, it's driving me bonkers.

Using Windows Input Simulator (C# SendInput Wrapper - Simulate Keyboard and Mouse)

When users of my software happen to have a non standard 100% windows scaling InputSimulator.Mouse.MoveMouseTo(toX, toY); is thrown off, moving to an incorrect location.

How i'm currently calculating:

int toX = (int)((65535.0f * (newX / (float)screen.Bounds.Width)) + 0.5f);
int toY = (int)((65535.0f * (newY / (float)screen.Bounds.Height)) + 0.5f);

If a user has scaling set to 125% for example, how would i calculate the correct 100% scaling location?

Thanks in advance.

Spark
  • 1,007
  • 1
  • 8
  • 26
  • Creating dpiAware programs has been important for 18 years already. With the release of Win10 it is now crucial, its installer no longer picks 96 dpi (aka 100%) as the default. Closing with the proper fix. – Hans Passant Sep 24 '19 at 11:43

1 Answers1

0

The answer was pretty simple, just a frustrating problem to solve.

First detect if a user has scaling applied like so:

[DllImport("gdi32.dll")]
public static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

public enum DeviceCap { VERTRES = 10, DESKTOPVERTRES = 117 }
public float GetScalingFactor()
{
    Graphics g = Graphics.FromHwnd(IntPtr.Zero);
    IntPtr desktop = g.GetHdc();
    int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
    int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);

    float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;

    return ScreenScalingFactor; // 1.25 = 125%
}

Then store the scale and divide the initial coordinate by it.

ScreenScale = Utils.GetScalingFactor();
int toX = (int)((65535.0f * ((x / ScreenScale) / (float)wowScreen.Bounds.Width)) + 0.5f);
int toY = (int)((65535.0f * ((y / ScreenScale) / (float)wowScreen.Bounds.Height)) + 0.5f);
Spark
  • 1,007
  • 1
  • 8
  • 26