C#真实地移动鼠标

C#真实地移动鼠标,c#,mouse,C#,Mouse,我正在演示一个软件,希望构建一个鼠标“移动器”功能,这样我就可以基本上自动化这个过程。我想创建真实的鼠标移动,但在思考过程中我有点思维障碍。我可以用c#轻松地移动鼠标,但我希望它比光标出现在某个x,y坐标,然后按下按钮更逼真 我得到鼠标的当前位置,然后得到终点。计算两个点之间的一个弧,然后我需要沿着该弧计算点,这样我可以在其中添加一个计时器事件,这样我可以从一个点移动到下一个点,然后重复这个过程,直到到达目标 有人想详细说明吗 谢谢,R.我认为,通常的方法是用你自己的手实际移动真正的鼠标:让软件

我正在演示一个软件,希望构建一个鼠标“移动器”功能,这样我就可以基本上自动化这个过程。我想创建真实的鼠标移动,但在思考过程中我有点思维障碍。我可以用c#轻松地移动鼠标,但我希望它比光标出现在某个x,y坐标,然后按下按钮更逼真

我得到鼠标的当前位置,然后得到终点。计算两个点之间的一个弧,然后我需要沿着该弧计算点,这样我可以在其中添加一个计时器事件,这样我可以从一个点移动到下一个点,然后重复这个过程,直到到达目标

有人想详细说明吗


谢谢,R.

我认为,通常的方法是用你自己的手实际移动真正的鼠标:让软件捕捉那些(真实的)运动,并回放它们。

我尝试了圆弧计算方法,结果证明非常复杂,最后看起来不现实。正如JP在评论中所说,直线看起来更人性化

这是我用来计算鼠标线性移动的函数。应该是不言自明的。GetCursorPosition()和SetCursorPosition(Point)是win32函数GetCursorPos和SetCursorPos的包装器

就数学而言——从技术上讲,这被称为线段

public void LinearSmoothMove(Point newPosition, int steps) {
    Point start = GetCursorPosition();
    PointF iterPoint = start;

    // Find the slope of the line segment defined by start and newPosition
    PointF slope = new PointF(newPosition.X - start.X, newPosition.Y - start.Y);

    // Divide by the number of steps
    slope.X = slope.X / steps;
    slope.Y = slope.Y / steps;

    // Move the mouse to each iterative point.
    for (int i = 0; i < steps; i++)
    {
        iterPoint = new PointF(iterPoint.X + slope.X, iterPoint.Y + slope.Y);
        SetCursorPosition(Point.Round(iterPoint));
        Thread.Sleep(MouseEventDelayMS);
    }

    // Move the mouse to the final destination.
    SetCursorPosition(newPosition);
}
public void LinearSmoothMove(点新位置,整数步){
点开始=GetCursorPosition();
PointF iterPoint=开始;
//查找由start和newPosition定义的线段的坡度
点F斜率=新点F(newPosition.X-start.X,newPosition.Y-start.Y);
//除以步数
斜率X=斜率X/步数;
斜率Y=斜率Y/台阶;
//将鼠标移动到每个迭代点。
对于(int i=0;i
程序WindMouse(xs、ys、xe、ye、重力、风、minWait、maxWait、maxStep、targetArea:extended);
变量
veloX,veloY,windX,windY,veloMag,dist,randomDist,lastDist,步长:扩展;
lastX,lastY:整数;
sqrt2、sqrt3、sqrt5:扩展;
开始
sqrt2:=sqrt(2);
sqrt3:=sqrt(3);
sqrt5:=sqrt(5);
而hypot(xs-xe,ys-ye)>1do
开始
dist:=低血压(xs-xe,ys-ye);
风:=矿井(风,距离);
如果dist>=targetArea,则
开始
windX:=windX/sqrt3+(随机(轮(风)*2+1)-风)/sqrt5;
风:=风/sqrt3+(随机(圆形(风)*2+1)-风)/sqrt5;
结束其他
开始
windX:=windX/sqrt2;
风:=风/sqrt2;
如果(最大步长<3),则
开始
最大步长:=随机(3)+3.0;
结束其他
开始
maxStep:=maxStep/sqrt5;
结束;
结束;
veloX:=veloX+windX;
速度:=速度+风;
veloX:=veloX+重力*(xe-xs)/dist;
速度:=速度+重力*(ye-ys)/距离;
如果hypot(veloX,veloY)>maxStep,则
开始
randomDist:=maxStep/2.0+随机(四舍五入(maxStep)/2);
veloMag:=sqrt(veloX*veloX+veloY*veloY);
veloX:=(veloX/veloMag)*随机分布;
veloY:=(veloY/veloMag)*随机分布;
结束;
lastX:=圆形(xs);
lastY:=圆形(ys);
xs:=xs+veloX;
ys:=ys+veloY;
如果是(最后一轮(xs))或(最后一轮(ys)),则
移动鼠标(圆形(xs),圆形(ys));
步骤:=hypot(xs-lastX,ys-lastY);
等待(轮((maxWait-minWait)*(step/maxStep)+minWait));
lastdist:=dist;
结束;
如果是(圆形(xe)圆形(xs))或(圆形(ye)圆形(ys)),则
移动鼠标(圆形(xe),圆形(ye));
结束;
{*******************************************************************************
程序mmuse(x,y,rx,ry:整数);
作者:Benland100
描述:移动鼠标。
*******************************************************************************}
//随机性只是添加到x,y。我可能想改变这一点。
程序mmuse(x,y,rx,ry:整数);
变量
cx,cy:整数;
随机速度:扩展;
开始
随机速度:=(随机(鼠标速度)/2.0+鼠标速度)/10.0;
如果randSpeed=0.0,则
随机速度:=0.1;
getMousePos(cx,cy);
X:=X+随机(rx);
Y:=Y+随机(ry);
风鼠(cx、cy、x、y、9.0、3.0、10.0/randSpeed、15.0/randSpeed、10.0*randSpeed、10.0*randSpeed);
结束;

这里有一些用SCAR写的方法。将它们转换为C#应该不会太难,它们非常现实。

我将前面提到的
WindMouse
函数转换为C#,实际上非常现实。请注意,这只是一个粗略的示例,没有为
GetCursorPos
SetCursorPos
使用包装器。我会用包装纸的

static class SampleMouseMove {

    static Random random = new Random();
    static int mouseSpeed = 15;

    static void Main(string[] args) {
        MoveMouse(0, 0, 0, 0);
    }

    static void MoveMouse(int x, int y, int rx, int ry) {
        Point c = new Point();
        GetCursorPos(out c);

        x += random.Next(rx);
        y += random.Next(ry);

        double randomSpeed = Math.Max((random.Next(mouseSpeed) / 2.0 + mouseSpeed) / 10.0, 0.1);

        WindMouse(c.X, c.Y, x, y, 9.0, 3.0, 10.0 / randomSpeed,
            15.0 / randomSpeed, 10.0 * randomSpeed, 10.0 * randomSpeed); 
    }

    static void WindMouse(double xs, double ys, double xe, double ye,
        double gravity, double wind, double minWait, double maxWait,
        double maxStep, double targetArea) {

        double dist, windX = 0, windY = 0, veloX = 0, veloY = 0, randomDist, veloMag, step;
        int oldX, oldY, newX = (int)Math.Round(xs), newY = (int)Math.Round(ys);

        double waitDiff = maxWait - minWait;
        double sqrt2 = Math.Sqrt(2.0);
        double sqrt3 = Math.Sqrt(3.0);
        double sqrt5 = Math.Sqrt(5.0);

        dist = Hypot(xe - xs, ye - ys);

        while (dist > 1.0) {

            wind = Math.Min(wind, dist);

            if (dist >= targetArea) {
                int w = random.Next((int)Math.Round(wind) * 2 + 1);
                windX = windX / sqrt3 + (w - wind) / sqrt5;
                windY = windY / sqrt3 + (w - wind) / sqrt5;
            }
            else {
                windX = windX / sqrt2;
                windY = windY / sqrt2;
                if (maxStep < 3)
                    maxStep = random.Next(3) + 3.0;
                else
                    maxStep = maxStep / sqrt5;
            }

            veloX += windX;
            veloY += windY;
            veloX = veloX + gravity * (xe - xs) / dist;
            veloY = veloY + gravity * (ye - ys) / dist;

            if (Hypot(veloX, veloY) > maxStep) {
                randomDist = maxStep / 2.0 + random.Next((int)Math.Round(maxStep) / 2);
                veloMag = Hypot(veloX, veloY);
                veloX = (veloX / veloMag) * randomDist;
                veloY = (veloY / veloMag) * randomDist;
            }

            oldX = (int)Math.Round(xs);
            oldY = (int)Math.Round(ys);
            xs += veloX;
            ys += veloY;
            dist = Hypot(xe - xs, ye - ys);
            newX = (int)Math.Round(xs);
            newY = (int)Math.Round(ys);

            if (oldX != newX || oldY != newY)
                SetCursorPos(newX, newY);

            step = Hypot(xs - oldX, ys - oldY);
            int wait = (int)Math.Round(waitDiff * (step / maxStep) + minWait);
            Thread.Sleep(wait);
        }

        int endX = (int)Math.Round(xe);
        int endY = (int)Math.Round(ye);
        if (endX != newX || endY != newY)
            SetCursorPos(endX, endY);
    }

    static double Hypot(double dx, double dy) {
        return Math.Sqrt(dx * dx + dy * dy);
    }

    [DllImport("user32.dll")]
    static extern bool SetCursorPos(int X, int Y);

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out Point p);
}
静态类SampleMouseMove{
静态随机=新随机();
静态int mouseSpeed=15;
静态void Main(字符串[]参数){
移动鼠标(0,0,0,0);
}
静态无效移动鼠标(int x,int y,int rx,int ry){
点c=新点();
GetCursorPos(输出c);
x+=随机。下一个(rx);
y+=随机。下一个(ry);
双随机速度=数学最大值((随机下一步(鼠标速度)/2.0+鼠标速度)/10.0,0.1);
WindMouse(c.X,c.Y,X,Y,9.0,3.0,10.0/s速度,
15.0/随机速度,10.0*随机速度,10.0*随机速度);
}
静态void WindMouse(双X、双Y、双xe、双ye、,
双重力,双风,双minWait,双maxWait,
双最大步进,双目标(A){
双距离,windX=0,windY=0,veloX=0,veloY=0,randomDist,veloMag,步长;
intoldx,oldY,newX=(int)Math.Round(xs),newY=(int)Math.Round(ys);
double waitDiff=maxWait-minWait;
双sqrt
static class SampleMouseMove {

    static Random random = new Random();
    static int mouseSpeed = 15;

    static void Main(string[] args) {
        MoveMouse(0, 0, 0, 0);
    }

    static void MoveMouse(int x, int y, int rx, int ry) {
        Point c = new Point();
        GetCursorPos(out c);

        x += random.Next(rx);
        y += random.Next(ry);

        double randomSpeed = Math.Max((random.Next(mouseSpeed) / 2.0 + mouseSpeed) / 10.0, 0.1);

        WindMouse(c.X, c.Y, x, y, 9.0, 3.0, 10.0 / randomSpeed,
            15.0 / randomSpeed, 10.0 * randomSpeed, 10.0 * randomSpeed); 
    }

    static void WindMouse(double xs, double ys, double xe, double ye,
        double gravity, double wind, double minWait, double maxWait,
        double maxStep, double targetArea) {

        double dist, windX = 0, windY = 0, veloX = 0, veloY = 0, randomDist, veloMag, step;
        int oldX, oldY, newX = (int)Math.Round(xs), newY = (int)Math.Round(ys);

        double waitDiff = maxWait - minWait;
        double sqrt2 = Math.Sqrt(2.0);
        double sqrt3 = Math.Sqrt(3.0);
        double sqrt5 = Math.Sqrt(5.0);

        dist = Hypot(xe - xs, ye - ys);

        while (dist > 1.0) {

            wind = Math.Min(wind, dist);

            if (dist >= targetArea) {
                int w = random.Next((int)Math.Round(wind) * 2 + 1);
                windX = windX / sqrt3 + (w - wind) / sqrt5;
                windY = windY / sqrt3 + (w - wind) / sqrt5;
            }
            else {
                windX = windX / sqrt2;
                windY = windY / sqrt2;
                if (maxStep < 3)
                    maxStep = random.Next(3) + 3.0;
                else
                    maxStep = maxStep / sqrt5;
            }

            veloX += windX;
            veloY += windY;
            veloX = veloX + gravity * (xe - xs) / dist;
            veloY = veloY + gravity * (ye - ys) / dist;

            if (Hypot(veloX, veloY) > maxStep) {
                randomDist = maxStep / 2.0 + random.Next((int)Math.Round(maxStep) / 2);
                veloMag = Hypot(veloX, veloY);
                veloX = (veloX / veloMag) * randomDist;
                veloY = (veloY / veloMag) * randomDist;
            }

            oldX = (int)Math.Round(xs);
            oldY = (int)Math.Round(ys);
            xs += veloX;
            ys += veloY;
            dist = Hypot(xe - xs, ye - ys);
            newX = (int)Math.Round(xs);
            newY = (int)Math.Round(ys);

            if (oldX != newX || oldY != newY)
                SetCursorPos(newX, newY);

            step = Hypot(xs - oldX, ys - oldY);
            int wait = (int)Math.Round(waitDiff * (step / maxStep) + minWait);
            Thread.Sleep(wait);
        }

        int endX = (int)Math.Round(xe);
        int endY = (int)Math.Round(ye);
        if (endX != newX || endY != newY)
            SetCursorPos(endX, endY);
    }

    static double Hypot(double dx, double dy) {
        return Math.Sqrt(dx * dx + dy * dy);
    }

    [DllImport("user32.dll")]
    static extern bool SetCursorPos(int X, int Y);

    [DllImport("user32.dll")]
    public static extern bool GetCursorPos(out Point p);
}
public static class Mouse
{
    private const float MOUSE_SMOOTH = 200f;

    public static void MoveTo(int targetX, int targetY)
    {
        var targetPosition = new Point(targetX, targetY);
        var curPos = Cursor.Position;

        var diffX = targetPosition.X - curPos.X;
        var diffY = targetPosition.Y - curPos.Y;

        for (int i = 0; i <= MOUSE_SMOOTH; i++)
        {
            float x = curPos.X + (diffX / MOUSE_SMOOTH * i);
            float y = curPos.Y + (diffY / MOUSE_SMOOTH * i);
            Cursor.Position = new Point((int)x, (int)y);
            Thread.Sleep(1);
        }

        if (Cursor.Position != targetPosition)
        {
            MoveTo(targetPosition.X, targetPosition.Y);
        }
    }
}