在光标下获取颜色时 CPU 使用率高

发布于 2025-01-04 07:50:36 字数 2398 浏览 0 评论 0原文

我正在开发一个应用程序,将鼠标移动到某个区域,如果某些区域不是黑色,则单击鼠标。

但是,在使用此方法获取光标下方的颜色时,我的 CPU 使用率非常高。从 startY 到 endY 完成 5 次运行后 - 应用程序滞后了大约 5-10 秒。到达该区域的尽头。注释掉这部分后,应用程序运行良好,并且每次运行都不会增加太完整。

这是我的 while 循环:

private void moveMouse(int startX, int endX, int startY, int endY)
    {
        int newPosX = startX;
        int newPosY = startY;
        while (running)
        {
            Application.DoEvents();
            //this.Cursor = new Cursor(Cursor.Current.Handle);
            Cursor.Position = new Point(newPosX, newPosY);
            Thread.Sleep(3);
            if (colorCursor.Get(newPosX, newPosY))
            {
                MyMouse.sendClick();
                countClicks++;
                lblStatus.Text = "Klik: " + countClicks;
            }

            newPosX += 10;
            if (newPosX > endX)
            {
                newPosY += 25;
                newPosX = startX;
            }
            if (newPosY > endY)
            {
                newPosY = startY;
                Thread.Sleep(1000);
            }
        }
    }

光标下方的颜色:

public class ColorUnderCursor
{
    [DllImport("gdi32")]
    public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);

    //[DllImport("user32.dll", CharSet = CharSet.Auto)]
    //public static extern bool GetCursorPos(out POINT pt);

    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowDC(IntPtr hWnd);

    public bool Get(int x, int y)
    {
        IntPtr dc = GetWindowDC(IntPtr.Zero);

        long color = GetPixel(dc, x, y);
        Color underMouse = Color.FromArgb((int)color);
        if(underMouse != Color.FromArgb(0, 0, 0, 0))
            return true;

        return false;
    }
}

如何最大限度地减少 CPU 的大量使用。

解决方案: 是我的方法“Get”导致了问题。我通过下面的方法解决了这个问题,并在后台工作人员中运行整个过程。

public bool GetPixel(Point position)
    {
        using (var bitmap = new Bitmap(1, 1))
        {
            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.CopyFromScreen(position, new Point(0, 0), new Size(1, 1));
            }
            if (bitmap.GetPixel(0, 0) != Color.FromArgb(255, 0, 0, 0) && bitmap.GetPixel(0, 0) != Color.FromArgb(255, 255, 255, 255))
                return true;

            return false;
        }
    }

I'm working on an app, moving the mouse in a certain area and clicking the mouse if something is not the color black.

However, I am getting a really high CPU usage while using this method too get the color below the cursor. After 5 completed runs from startY to endY - the application is lagging that much it takes around 5-10 sec. to get too the end of the area. With this part commented out, the application runs fine and each run doesn't increase in the too complete.

Here is my while loop:

private void moveMouse(int startX, int endX, int startY, int endY)
    {
        int newPosX = startX;
        int newPosY = startY;
        while (running)
        {
            Application.DoEvents();
            //this.Cursor = new Cursor(Cursor.Current.Handle);
            Cursor.Position = new Point(newPosX, newPosY);
            Thread.Sleep(3);
            if (colorCursor.Get(newPosX, newPosY))
            {
                MyMouse.sendClick();
                countClicks++;
                lblStatus.Text = "Klik: " + countClicks;
            }

            newPosX += 10;
            if (newPosX > endX)
            {
                newPosY += 25;
                newPosX = startX;
            }
            if (newPosY > endY)
            {
                newPosY = startY;
                Thread.Sleep(1000);
            }
        }
    }

Color below cursor:

public class ColorUnderCursor
{
    [DllImport("gdi32")]
    public static extern uint GetPixel(IntPtr hDC, int XPos, int YPos);

    //[DllImport("user32.dll", CharSet = CharSet.Auto)]
    //public static extern bool GetCursorPos(out POINT pt);

    [DllImport("User32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr GetWindowDC(IntPtr hWnd);

    public bool Get(int x, int y)
    {
        IntPtr dc = GetWindowDC(IntPtr.Zero);

        long color = GetPixel(dc, x, y);
        Color underMouse = Color.FromArgb((int)color);
        if(underMouse != Color.FromArgb(0, 0, 0, 0))
            return true;

        return false;
    }
}

How I can minimize this heavy usage of the CPU.

Solution:
It was my method "Get" which was causing the problem. I solved it by this method below, and running the whole thing inside a backgroundworker.

public bool GetPixel(Point position)
    {
        using (var bitmap = new Bitmap(1, 1))
        {
            using (var graphics = Graphics.FromImage(bitmap))
            {
                graphics.CopyFromScreen(position, new Point(0, 0), new Size(1, 1));
            }
            if (bitmap.GetPixel(0, 0) != Color.FromArgb(255, 0, 0, 0) && bitmap.GetPixel(0, 0) != Color.FromArgb(255, 255, 255, 255))
                return true;

            return false;
        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

述情 2025-01-11 07:50:36

尝试将逻辑移至 Invoke 调用中,如下所示

private void moveMouse(int startX, int endX, int startY, int endY)
{

  this.BeginInvoke(new Action(() => { InvokeMouseMove(startX, endX, startY, endY)
   }));
}

private void InvokeMouseMove(int startX, int endX, int startY, int endY)
    {
        int newPosX = startX;
        int newPosY = startY;
        while (running)
        {
            Application.DoEvents();
            //this.Cursor = new Cursor(Cursor.Current.Handle);
            Cursor.Position = new Point(newPosX, newPosY);

            if (colorCursor.Get(newPosX, newPosY))
            {
                MyMouse.sendClick();
                countClicks++;
                lblStatus.Text = "Klik: " + countClicks;
            }

            newPosX += 10;
            if (newPosX > endX)
            {
                newPosY += 25;
                newPosX = startX;
            }
            if (newPosY > endY)
            {
                newPosY = startY;
            }
        }
    }

Try to move logic into Invoke call like this

private void moveMouse(int startX, int endX, int startY, int endY)
{

  this.BeginInvoke(new Action(() => { InvokeMouseMove(startX, endX, startY, endY)
   }));
}

private void InvokeMouseMove(int startX, int endX, int startY, int endY)
    {
        int newPosX = startX;
        int newPosY = startY;
        while (running)
        {
            Application.DoEvents();
            //this.Cursor = new Cursor(Cursor.Current.Handle);
            Cursor.Position = new Point(newPosX, newPosY);

            if (colorCursor.Get(newPosX, newPosY))
            {
                MyMouse.sendClick();
                countClicks++;
                lblStatus.Text = "Klik: " + countClicks;
            }

            newPosX += 10;
            if (newPosX > endX)
            {
                newPosY += 25;
                newPosX = startX;
            }
            if (newPosY > endY)
            {
                newPosY = startY;
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文