2016-04-05 2 views
1

Я пишу часть программного обеспечения, которое принимает аналоговый вход от POT в виде двойника с диапазоном от -1 до +1 и в свою очередь пытается использовать это как дельта мыши. Все работает, но итерация/скорость слишком медленная и заставляет меня умножать значение ввода, заставляя курсор двигаться, чтобы он не был таким жидким, как хотелось бы.Перемещение мыши по дельте вызывает движение курсора «jittery»

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])); 
      } 
     } 
    } 
} 

Я использую SendInput, поскольку она позволяет относительное перемещение курсора, но мне интересно, если SetCursorPos и отслеживанию х, у относительно экрана является более эффективным.

Есть ли лучший способ сделать это?

+0

Кажется, что вы правильно настроили его, чтобы сохранить дробную часть движения пикселя. Единственное, что я могу предположить, это то, что POT не обладает необходимой преданностью, чтобы дать вам нужные результаты. Может быть, было бы интересно проверить «кривую» выхода POT, чтобы увидеть, насколько она гладкая. – LodeRunner28

+0

Я пробовал кормить его фиксированной стоимостью и все еще получаю дрожь. Я решил настроить его на наличие секундомера, чтобы рассчитать разницу в частоте выполнения и объяснить, чтобы он превратил его в истинную дельта V. Но поскольку я уже вынужден перемещать целых 5 пикселей за одну итерацию, чтобы получить приличную скорость , Я заинтересован в добавлении большего количества кода в цикл. На мой взгляд, мой вопрос является академическим на данный момент и задается вопросом, является ли метод SendInput самым эффективным способом для этого. – Wobbles

ответ

0

Лучше, но все еще тратить слишком много циклов на мой waitHandle. Я знаю, что бесконечные циклы, как правило, плохие, но я просто не вижу другого способа получить достойную производительность из-за этого, поскольку таймеры кажутся более медленными.

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); 
    } 
} 

Изменения сверху донизу.

Использование EventWaitHandle. Определенно, как это и будет использовать его чаще, однако никаких заметных различий в производительности от Sleep (1).

Литье double remX и remY до int, а не обрезание. Кажется, есть небольшое повышение производительности.

Использование GetCursorPos и SetCursorPos вместо SendInput. Кажется, что лучше работать, было бы лучше, если бы я поддерживал свои собственные хостинги x и y вместо того, чтобы вызывать GetCursorPos на каждую итерацию, но я тоже хотел поддерживать использование приложений для мыши.

Это все еще нуждается в некоторой настройке. Как я уже сказал, я все еще трачу слишком много циклов на EventWaitHandle, и я не знаю, как сделать этот запуск лучше.

 Смежные вопросы

  • Нет связанных вопросов^_^