2016-04-05 14 views
1

私は、-1から+1までの範囲の倍精度の形でPOTからアナログ入力を受け取り、これをマウスカーソルデルタとして使用します。すべてが機能しますが、反復/速度が遅すぎるため、入力の値を掛けてカーソルを移動させ、私が望むほど流動的でないようにしなければなりません。デルタでマウスを動かすと、カーソルの動きが「びびり」になる

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

それは相対的カーソル移動を可能にするが、私はSetCursorPosかしらとXを追跡するため、画面にYに対しては、より効率的であるSendInputを使用しています。

これを行うには良い方法がありますか?

+0

ピクセル移動の小数部分を正しく保持するように設定されているようです。私が推測できる唯一のことは、あなたが望む結果を得るためにPOTが必要な忠実度を欠いていることです。おそらく、POT出力の「曲線」をテストして、どれほど滑らかであるかを調べることは興味深いでしょう。 – LodeRunner28

+0

私はそれを固定値にしてみてみましたが、まだジッタがあります。 Iveは、実行頻度の差を計算するためにストップウォッチを設定し、それを真のデルタVに変えることを考慮しました。しかし、私は既に、1回の反復で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に切り捨てるのではなく、パフォーマンスが少し向上したようだ。

SendInputの代わりにGetCursorPosSetCursorPosを使用します。より良いパフォーマンスを発揮すると思うが、毎回GetCursorPosを呼び出すのではなく、私自身のxとy座標を維持していればさらに良いだろうが、私はアプリのマウス使用量を維持したい。

これにはまだチューニングが必要です。私が言ったように、私はまだ多くのサイクルをEventWaitHandleに費やしています。そして、それをもっとうまく走らせる方法はわかりません。

関連する問題