0

I am getting error "A generic error occurred in GDI+". I have code below, but it error after some time while loop. I research for all and can not fix it, please help me

public Color GetColorAt(int x, int y)
    {
        x = x - rect.Left - 7;
        y = y - rect.Top - 31;

        Color c = Color.Black;
        IntPtr hDC = PlatformInvokeUSER32.GetDC(proc.MainWindowHandle);

        try
        {
            if (hDC != IntPtr.Zero)
            {
                IntPtr hMemDC = PlatformInvokeGDI32.CreateCompatibleDC(hDC);
                if (hMemDC != IntPtr.Zero)
                {
                    IntPtr m_HBitmap = PlatformInvokeGDI32.CreateCompatibleBitmap(hDC, 1, 1);
                    if (m_HBitmap != IntPtr.Zero)
                    {
                        IntPtr hOld = (IntPtr)PlatformInvokeGDI32.SelectObject(hMemDC, m_HBitmap);
                        PlatformInvokeGDI32.BitBlt(hMemDC, 0, 0, 1, 1, hDC, x, y, PlatformInvokeGDI32.SRCCOPY);
                        PlatformInvokeGDI32.SelectObject(hMemDC, hOld);

                        Bitmap screen = Image.FromHbitmap(m_HBitmap);
                        c = screen.GetPixel(0, 0);
                        screen.Dispose();
                    }
                    PlatformInvokeGDI32.DeleteObject(m_HBitmap);
                    PlatformInvokeGDI32.DeleteDC(m_HBitmap);
                }
                PlatformInvokeGDI32.DeleteDC(hMemDC);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace);
        }

        PlatformInvokeUSER32.ReleaseDC(proc.MainWindowHandle, hDC);
        PlatformInvokeGDI32.DeleteDC(hDC);
        GC.Collect();
        return c;
}

Using call function while loop realtime

public Form1()
        {
            InitializeComponent();
            while (true)
            {
                Color c = GetColorAt(50, 50);
                Thread.Sleep(10);
            }
        }
Jack Huỳnh
  • 79
  • 2
  • 3
  • @AlexF Thanks you, but you mean `PlatformInvokeUSER32.ReleaseDC(proc.MainWindowHandle, hDC)` in code realy have before `DeleteDC` – Jack Huỳnh Dec 24 '20 at 08:00
  • 1
    + Use a `System.Windows.Forms.Timer` instead of the `while (true) { }` loop, call the method from the `Tick` event of the timer. – dr.null Dec 24 '20 at 11:50
  • @dr.null Thank you, i tried Tick timer is not `lock` when doing 10 millisecond, maybe func `GetColorAt` complete in 20 millisecond then Tick 2 times. I tried lock in Tick timer doing when func `GetColorAt` complete to next step, but it the same error. I do not free/clear/dispose/empty memory GDI object in the loop realtime! – Jack Huỳnh Dec 25 '20 at 03:45
  • Try [this](https://stackoverflow.com/a/753157/14171304). – dr.null Dec 25 '20 at 05:26
  • @dr.null i have tried, your code slowing 20-50ms, i need detect color `MainWindowHandle` of game screen, looping <= 10ms. I noticed that if the `GDI Object` increases > 9000 then an error occurs => view in tab `Task Manager` – Jack Huỳnh Dec 25 '20 at 06:14
  • I'm sorry but 10ms doesn't make since. Even owl's eyes won't detect that. The code returns a pixel color from a given **screen** point . You need to use the [Control.PointToScreen](https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.control.pointtoscreen?view=net-5.0) method to get the screen point so you can pass it to the referred method. – dr.null Dec 25 '20 at 13:46
  • 1
    Thanks @dr.null. I try using `Double Screen`, it very good working – Jack Huỳnh Dec 27 '20 at 05:07

0 Answers0