Programming Microsoft Windows with C#

Reading Pixels from the Screen

As I discuss in my book Programming Windows with C#, the Windows Forms graphics system does not provide a way to read pixels from the screen. If reading the screen is something you need to do, you'll have to make use of Win32 functions.

The CaptureScreen.cs [rename file after download] file shows how to copy the contents of the screen into a .NET bitmap. (Like all Windows Forms programs, compiling the program requires references to the System, System.Drawing, and System.Windows.Forms DLLs.) To use the program, simply click the client area. The program creates a bitmap the size of the screen, copies the screen contents into the bitmap, and then displays the bitmap stretched to the size of its client area. You can use techniques shown in Chapter 11, 16, and 24 of Programming Windows with C# to save the bitmap to a file, or copy it to the clipboard.

The only external Win32 function required in CaptureScreen is the famous BitBlt (bit-block transfer) function. BitBlt requires two devices context handles — a source and a destination. Both device context handles can be obtained from methods provided by the .NET Graphics class.

The OnClick method of CaptureScreen begins by calling the static Graphics.FromHwnd method with an argument of zero. (I was prompted to try calling Graphics.FromHwnd with a zero argument by the documentation of the Win32 GetDC function: "If this value is NULL, GetDC retrieves the DC for the entire screen." It worked!) The OnClick method then creates a bitmap with the same size and resolution of the screen.

Once the bitmap is created, the OnClick method creates a Graphics object for the bitmap by calling the static Graphics.FromImage method. The GetHdc method of the Graphics class provides device context handles based on both Graphics objects. At this point, BitBlt can be called. The rest is just cleanup.

I tried to use a similar technique with the Win32 GetPixel function, but GetPixel mysteriously wouldn't work with that hdcScreen object that worked with BitBlt. A different approach is required that obtains a device context handle from the Win32 function CreateDC, and later deletes it with DeleteDC.

The WhatColor.cs [rename file after download] file is a Windows Forms version of the WhatClr program from Chapter 8 of my book Programming Windows (5th edition, Microsoft Press, 1999). The program sets a timer to display the RGB value of the pixel underneath the mouse position. It's very useful for Web page designers (and others) who want to match colors to objects displayed on the screen. The C# WhatColor program is somewhat enhanced to display both the hexadecimal and decimal renditions of the pixel color.

At each timer tick, the program obtains the current mouse coordinates using the static method Control.MousePosition. It obtains a device context handle for the whole screen using CreateDC, gets the pixel color from GetPixel and then deletes the device context handle by calling DeleteDC.

The COLORREF value that GetPixel returns contains the red, green, and blue bytes back packed into a 32-bit integer. The TimerOnTick method converts this value into a Win32 Color object using the static FromArgb method.

The OnPaint method using String.Format to create a two-line string containing the hexadecimal and decimal text renditions of the color, and then uses DrawString with a StringFormat object to center the text in the window.

© Charles Petzold, 2002
cp@charlespetzold.com
This page last updated March, 2002