2つの座標間でC#でマウスカーソル移動をシミュレートする
質問
私は2つの座標の間でプログラムでマウスを移動しようとしています。しかし、私はすべての高速または遅い加工マシンで速度を確実に維持したいと思っています。私が見た このリンクはこちらです. 。しかし、2つの座標間の移動をシミュレートする際に、カーソルの最適で滑らかで目に見える速度を私に理解することはありません。私の最初のアイデアのようなさまざまなマシンの遅延やステップの最適値のようなパラメーターを決定するトリックを知っている人は、特定のイテラトンのループのために使用して、マシンのパフォーマンスを決定し、その時間に基づいてパラメーターを評価します - ループは...アイデアを取りましたか?それとも私はこれについて完全に間違っていますか?ありがとう
解決
動きを時間の関数にする必要があります。での答えから始めます C#マウスを現実的に移動します, 、およびStopwatchクラスを使用して経過時間を測定します。
public void LinearSmoothMove(Point newPosition, TimeSpan duration)
{
Point start = GetCursorPosition();
// Find the vector between start and newPosition
double deltaX = newPosition.X - start.X;
double deltaY = newPosition.Y - start.Y;
// start a timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
double timeFraction = 0.0;
do
{
timeFraction = (double)stopwatch.Elapsed.Ticks / duration.Ticks;
if (timeFraction > 1.0)
timeFraction = 1.0;
PointF curPoint = new PointF(start.X + timeFraction * deltaX,
start.Y + timeFraction * deltaY);
SetCursorPosition(Point.Round(curPoint));
Thread.Sleep(20);
} while (timeFraction < 1.0);
}
他のヒント
物理学をお勧めします。速度は時間で距離を分割します。すべてのマシンでコンサントマウスの速度が必要な場合は、正確な時間を取得する必要があります。
例を挙げましょう:
マウスをポイント0/0から400/600に移動すると、3秒後にエンドポイントに常に到達する必要があります。
したがって、開始時間を節約し、早いループを構築する必要があります。ループでは、経過時間と合計時間からxおよびy座標を計算します。
X = 400 / 3s * ElapsedTime
Y = 600 / 3s * ElapsedTime
これはマシン独立になります。良い結果を得るには、次のように高い正確な時間を使用する必要があります ストップウォッチ.
私はこれを試しましたが、それでも最適ではありません。マシンの処理能力によってまだ変化します。@justin、睡眠時間と睡眠時間に異なる値を使用します。テストした後、より良い解決策を思いついた場合はお知らせください。ありがとうございます。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace ConsoleApplication11
{
class Program
{
[DllImport("user32.dll")]
static extern bool SetCursorPos(int X, int Y);
public static void LinearSmoothMove(Point newPosition, TimeSpan duration)
{
Point start = Cursor.Position;
int sleep = 10;
//PointF iterPoint = start;
// Find the vector between start and newPosition
double deltaX = newPosition.X - start.X;
double deltaY = newPosition.Y - start.Y;
// start a timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
double timeFraction = 0.0;
do
{
timeFraction = (double)stopwatch.Elapsed.Ticks / duration.Ticks;
if (timeFraction > 1.0)
timeFraction = 1.0;
PointF curPoint = new PointF((float)(start.X + timeFraction * deltaX), (float)(start.Y + timeFraction * deltaY));
SetCursorPos(Point.Round(curPoint).X, Point.Round(curPoint).Y);
Thread.Sleep(sleep);
} while (timeFraction < 1.0);
}
static void Main(string[] args)
{
TimeSpan delayt = new TimeSpan(0, 0, 3);
LinearSmoothMove(new Point(20, 40), delayt);
Console.Read();
}
}
}