2016-04-05 12 views
1

Ich schreibe ein Stück Software, die einen analogen Eingang von einem POT in Form eines Doppel mit einem Bereich von -1 bis +1 nimmt und bin wiederum versucht um dies als Mauszeiger Delta zu verwenden. Alles funktioniert, aber die Iteration/Geschwindigkeit ist zu langsam und zwingt mich, den Wert der Eingabe zu multiplizieren, der bewirkt, dass der Cursor sich nicht so flüssig verhält, wie ich es möchte.Bewegte Maus durch Delta verursacht Cursor-Bewegung zu "nervös"

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

ich SendInput verwende, da es für eine relative Cursorbewegung erlaubt, aber ich frage mich, ob SetCursorPos und die Verfolgung der x, y relativ zum Bildschirm effizienter.

Gibt es einen besseren Weg, dies zu tun?

+0

Es scheint, als ob Sie es richtig eingerichtet haben, um den Bruchteil der Pixelbewegung beizubehalten. Das einzige, was ich annehmen kann, ist, dass dem POT die nötige Treue fehlt, um Ihnen die gewünschten Ergebnisse zu liefern. Vielleicht wäre es interessant, die "Kurve" der POT-Ausgabe zu testen, um zu sehen, wie glatt sie ist. – LodeRunner28

+0

Ich habe versucht, es einen festen Wert zu füttern und immer noch Jitter zu bekommen. Ich überlegte mir, ob ich eine Stoppuhr bauen sollte, um Unterschiede in der Ausführungshäufigkeit zu berechnen und sie in ein echtes Delta V zu verwandeln. Aber ich bin schon gezwungen, in einer einzigen Iteration 5 Pixel zu bewegen, um eine ordentliche Geschwindigkeit zu erreichen Ich habe Bedenken, mehr Code in die Schleife einzufügen. Ich denke, meine Frage ist an dieser Stelle akademisch und ich frage mich, ob 'SendInput' der leistungsfähigste Weg ist, dies zu tun. – Wobbles

Antwort

0

Besser, aber immer noch zu viele Zyklen auf meinem waitHandle. Ich weiß, dass Endlosschleifen normalerweise schlecht sind, aber ich kann einfach keinen anderen Weg sehen, um anständige Leistung daraus zu ziehen, da Timer langsamer zu iterieren scheinen.

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

Änderungen von oben nach unten.

Mit EventWaitHandle. Definitiv gefällt das und wird es öfter verwenden, allerdings keine merklichen Leistungsunterschiede zu Sleep (1).

Casting double remX und remY zu int anstatt es zu kürzen. Scheint einen leichten Leistungsschub zu haben.

Verwendung von GetCursorPos und SetCursorPos anstelle von SendInput. Scheint besser zu sein, wäre besser, wenn ich meine eigenen x- und y-Koordinaten beibehalten würde anstatt GetCursorPos bei jeder Iteration aufzurufen, aber ich wollte auch die Verwendung der Maus außerhalb der App beibehalten.

Dies erfordert noch einige Einstellungen. Wie gesagt, ich verbringe immer noch zu viele Zyklen auf der EventWaitHandle und ich weiß nicht, wie man diesen Lauf besser machen kann.