简体   繁体   English

按delta移动鼠标会导致光标移动“抖动”

[英]Moving mouse by delta causes cursor movement to be “jittery”

I am writing a piece of software that takes an analog input from a POT in the form of a double with a range from -1 to +1 and am in turn trying to use this as mouse cursor delta. 我正在编写一个软件,它以双精度形式从POT接收模拟输入,范围从-1到+1,然后又尝试将其用作鼠标光标增量。 Everything works, but the iteration/speed is too slow and forces me to multiply the value of the input causing the cursor to movement to not be as fluid as I would like. 一切正常,但迭代/速度太慢,迫使我乘以输入值,使光标移动到不像我想的那样流畅。

class myApp
{
    double remX = 0;
    double remY = 0;
    double rateX = 0;
    double rateY = 0;

    private void mouseDeltaThread()
    {
        while (!Global.IsShuttingDown)
        {
            System.Threading.Thread.Sleep(1);
            if (rateX != 0 || rateY !=0)
                setMouseDelta(rateX,rateY);
        }

    }

    private void setMouseDelta(double dX, double dY)
    {
        remX += (dX);
        remY += (dY);

        int moveX = (int)Math.Truncate(remX);
        int moveY = (int)Math.Truncate(remY);

        remX -= moveX;
        remY -= moveY;

        Shared.MoveCursorBy(moveX, moveY);
    }

}

internal static class Shared
{
    internal const uint INPUT_MOUSE = 0, INPUT_KEYBOARD = 1, INPUT_HARDWARE = 2;
    private static INPUT[] sendInputs = new INPUT[2]; // will allow for keyboard + mouse/tablet input within one SendInput call, or two mouse events
    private static object lockob = new object();
    public static void MoveCursorBy(int x, int y)
    {
        lock (lockob)
        {
            if (x != 0 || y != 0)
            {
                sendInputs[0].type = INPUT_MOUSE;
                sendInputs[0].data.mi.dwExtraInfo = IntPtr.Zero;
                sendInputs[0].data.mi.dwFlags = MouseEventFlags.MOUSEEVENTF_MOVE;
                sendInputs[0].data.mi.mouseData = 0;
                sendInputs[0].data.mi.time = 0;
                sendInputs[0].data.mi.dx = x;
                sendInputs[0].data.mi.dy = y;
                uint result = SendInput(1, sendInputs, Marshal.SizeOf(sendInputs[0]));
            }
        }
    }
}

I am using SendInput since it allows for relative cursor movement, but I wonder if SetCursorPos and keeping track of the x,y relative to screen is more efficient. 我正在使用SendInput因为它允许相对光标移动,但我想知道SetCursorPos和跟踪相对于屏幕的x,y是否更有效。

Is there a better way of doing this? 有没有更好的方法呢?

Better, but still spending too many cycles on my waitHandle. 更好,但仍然在我的waitHandle上花费太多周期。 I know infinite loops are typically bad, but I simply cannot see any other way to get decent performance out of this as timers seem to iterate slower. 我知道无限循环通常是坏的,但我根本无法看到任何其他方式来获得良好的性能,因为计时器似乎迭代速度较慢。

class MyApp
{
    double remX = 0;
    double remY = 0;
    double rateX = 0;
    double rateY = 0;

    private void mouseDeltaThread()
    {
        EventWaitHandle MyEventWaitHandle = new EventWaitHandle(false,EventResetMode.AutoReset);
        while (!Global.IsShuttingDown)
        {
            MyEventWaitHandle.WaitOne(1);
            if (rateX != 0 || rateY !=0)
                setMouseDelta(rateX,rateY);
        }

    }

    private void setMouseDelta(double dX, double dY)
    {
        remX += (dX);
        remY += (dY);

        int moveX = (int)remX;
        int moveY = (int)remY;

        remX -= moveX;
        remY -= moveY;

        Shared.MoveCursorBy(moveX, moveY);
    }

}

internal static class Shared
{
    public static void MoveCursorBy(int x, int y)
    {
        POINT p = new POINT();
        GetCursorPos(out p);
        p.x += x;
        p.y += y;
        SetCursorPos(p.x, p.y);
    }
}

Changes from top to bottom. 从上到下的变化。

Using EventWaitHandle . 使用EventWaitHandle Definitely like this and will be using it more often, however no noticeable performance differences from Sleep(1). 绝对是这样的,并且会更频繁地使用它,但是与Sleep(1)没有明显的性能差异。

Casting double remX and remY to int rather than truncating it. double remX和remY转换为int而不是截断它。 Seems to have slight performance boost. 似乎有轻微的性能提升。

Using GetCursorPos and SetCursorPos in place of SendInput . 使用GetCursorPosSetCursorPos代替SendInput Seems to perform better, would be better still if I maintained my own running x and y coords instead of calling GetCursorPos every iteration, but I wanted to maintain out of app mouse usage as well. 似乎表现更好,如果我保持自己运行的x和y coords而不是每次迭代都调用GetCursorPos ,那会更好,但我也想保持app鼠标的使用。

This still needs some tuning thoug. 这还需要一些调整。 As I said, I am still spending too many cycles on the EventWaitHandle and I do not know how to make that run any better. 正如我所说,我仍然在EventWaitHandle上花费了太多周期,我不知道如何让这个运行得更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM