none
In Visual Studio C# WinForms.Net, how to know the color of a pixel in my program's window as seen in screen? RRS feed

  • Question

  • I want to invoke a fake mouse click on an empty place in my WinForm, how to know if the form is shown and isn't lagging because I don't want the click be on something else, I made a 3x3 square with 9 pixels of different colors and I want to check if the screen has these 9 colors in place so the fake click gets clicked immediately!

    private void FormMain_Paint(object sender, PaintEventArgs e)
    {
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 1, Color.Gray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1,1, Color.DarkGray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 1, Color.Brown);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 2, Color.RosyBrown);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1, 2, Color.DarkSlateGray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 2, Color.DarkGray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50, 3, Color.SlateGray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 1, 3, Color.LightSlateGray);
        ClassSetGetPixel.SetPixel(this, pictureBoxSettings.Right + 50 + 2, 3, Color.LightGray);
    }
    

    if (formMain.WindowState != FormWindowState.Minimized)
                    {
                        if ((GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 1))) == Color.Gray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1, 1))) == Color.DarkGray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 1))) == Color.Brown) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 2))) == Color.RosyBrown) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1,2))) == Color.DarkSlateGray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 2))) == Color.DarkGray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50, 3))) == Color.SlateGray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 1, 3))) == Color.LightSlateGray) &&
                         (GetPixel(formMain.PointToScreen(new Point(formMain.pictureBoxSettings.Right + 50 + 2, 3))) == Color.LightGray))
                        {
                            Program.DoMouseClick(formMain.Location.X + formMain.pictureBoxSettings.Right + 1, formMain.Location.Y + formMain.pictureBoxSettings.Top + 100);
                        }
                    }

    static public void SetPixel(Control control, int x, int y, Color color)
            {
                if (control != null)
                {
                    IntPtr hDC = GetDC(control.Handle);
                    int argb = color.ToArgb();
                    int colorRef =
                        (int)((argb & 0x00FF0000) >> 16) |
                        (int)(argb & 0x0000FF00) |
                        (int)((argb & 0x000000FF) << 16);
                    SetPixel(hDC, x, y, colorRef);
                    ReleaseDC(control.Handle, hDC);
                }
            }


            static Color GetPixel(Point p)
            {
                using (var bitmap = new Bitmap(1, 1))
                {
                    using (var graphics = Graphics.FromImage(bitmap))
                    {

                        graphics.CopyFromScreen(p, new Point(0, 0), new Size(1, 1));
                    }
                    return bitmap.GetPixel(0, 0);
                }
            }

    • Edited by Tam1988 Friday, March 27, 2020 4:02 PM
    Friday, March 27, 2020 3:29 PM

All replies

  • In order to check that some local point (e.g.: x=100, y=60) of formMain is visible, try this code:

    [DllImport( "user32" )]

    static extern IntPtr WindowFromPoint( Point p );

     

    . . .

    int x = 100;

    int y = 60;

     

    Point p = formMain.PointToScreen( new Point( x, y ) );

     

    IntPtr w = WindowFromPoint( p );

    Screen s = Screen.FromPoint( p );

     

    bool is_point_visible = s.Bounds.Contains( p ) && w == formMain.Handle;

     

    if( is_point_visible )

    {

           // . . .

    }

     

    • Edited by Viorel_MVP Friday, March 27, 2020 4:13 PM
    Friday, March 27, 2020 4:09 PM
  • Does your code detect when the form has been opened and shown (not minimized) and not not shown because of lag of it opening?

    Anyway my code worked when I made for 2 screens Windows desktop zoom in them to 100% instead of 150%, how to make my code take Windows screens zooming in consideration?


    • Edited by Tam1988 Friday, March 27, 2020 4:27 PM
    Friday, March 27, 2020 4:26 PM
  • Hi Tam1988,

    You can use the following code to get the magnification of the screen.

    Maybe you can use it to modify your code so that it can handle various situations.

           [DllImport("gdi32.dll")]
            static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
            public enum DeviceCap
            {
                VERTRES = 10,
                DESKTOPVERTRES = 117,
            }
    
            private float getScalingFactor()
            {
                Graphics g = Graphics.FromHwnd(IntPtr.Zero);
                IntPtr desktop = g.GetHdc();
                int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
                int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
                float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
                return ScreenScalingFactor; // 1.25 = 125%
            }

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, March 31, 2020 8:19 AM