63.2.1 Using a Bitmap to Capture an Image

You can use a bitmap to capture an image. And, depending on your application, you can store the captured image in memory, display the captured image at a different location in your application's window, or display the captured image in another window.

Some applications need to capture images and store them temporarily. For example, when a user scales or “zooms” a picture created in a drawing application, the application will temporarily save the normal view of the image and display the “zoomed” view. Later, when the user selects the “normal” view, the application will replace the “zoomed” image with a copy of the normal view that it temporarily saved.

If your application will temporarily store an image, you will need to create a DC that is compatible with the current Window DC. You create a compatible DC by calling the CreateCompatibleDC function. Once you've created a compatible DC, you'll need to create a bitmap with the appropriate dimensions and select it into this device context. You create the bitmap by calling the CreateCompatibleBitmap function, and you select the bitmap into the compatible DC by calling the SelectObject function.

Once the compatible device-context is created and the appropriate bitmap has been selected into it, you can capture the image. Windows provides a special function called BitBlt to capture images. The BitBlt function performs a bit-block-transfer—it copies data from a source bitmap into a destination bitmap. Since it copies data from bitmaps, you'd probably expect that two arguments to this function would be bitmap handles; however, this is not true. Instead, the BitBlt function receives handles that identify two device contexts and copies bitmap data from a bitmap selected into the source DC into a bitmap selected into the target DC. In this case, the target DC is the compatible DC—when the BitBlt function completes the transfer, the image has actually been stored in memory. When you need to re-display the image, you can do so by simply calling the BitBlt function a second time and specifying the compatible device-context as the source DC and a window (or printer) device context as the target DC.

The following code is taken from an application that captures an image of the entire desktop. It creates a compatible device-context and a bitmap with the appropriate dimensions, it selects the bitmap into the compatible DC, and then it copies the image using the BitBlt function:

/*

* Create a normal- and a memory-DC for the entire screen. The

* normal DC provides a "snapshot" of the screen contents. The

* memory DC keeps a copy of this "snapshot" in the associated

* bitmap. (Note: a memory-DC is sometimes referred to as

* a "compatible" DC.)

*/

hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL);

hdcCompatible = CreateCompatibleDC(hdcScreen);

/* Create a compatible bitmap for hdcScreenComapt. */

hbmScreen = CreateCompatibleBitmap(hdcScreen,

GetDeviceCaps(hdcScreen, HORZRES),

GetDeviceCaps(hdcScreen, VERTRES));

if (hbmScreen == 0)

errhandler("hbmScreen", hwnd);

/* Select the bitmaps into the compatible DC. */

if (!SelectObject(hdcCompatible, hbmScreen))

errhandler("Compatible Bitmap Selection", hwnd);

/* Hide the app's window. */

ShowWindow(hwnd, SW_HIDE);

/* */

/* Copy color data for the entire display into a */

/* bitmap which is selected into a compatible DC. */

/* */

if (!BitBlt(hdcCompatible,

0,0,

bmp.bmWidth, bmp.bmHeight,

hdcScreen,

0,0,

SRCCOPY))

errhandler("Screen to Compat Blt Failed", hwnd);

/* Redraw the apps window. */

ShowWindow(hwnd, SW_SHOW);