Using Different ROP Codes

SRCCOPY is definitely the most popular dwROP parameter to BitBlt, and you may be hard-pressed to find uses for the other 255 ROP codes. So I'll give you a couple of examples in which other ROP codes show their stuff.

In the first example, you have a monochrome bitmap that you want to transfer to the screen. However, you want to display the bitmap so that the black (0) bits don't affect anything currently on the client area. Moreover, you want all the white (1) bits to color the client area with a brush, perhaps a colored brush created from CreateSolidBrush. How do you do it? I'll assume that you're working in the MM_TEXT mapping mode and that you want to write the bitmap starting at the point (xStart, yStart) in your client area. You already have a handle to the monochrome bitmap (hBitmap) and a handle to the colored brush (hBrush). You know the width and height of the bitmap and have them stored in a BITMAP structure named bm. Here's the code:

hdcMem = CreateCompatibleDC (hdc) ;

SelectObject (hdcMem, hBitmap) ;

hBrush = SelectObject (hdc, hBrush) ;

BitBlt (hdc, xStart, yStart, bm.bmWidth, bm.bmHeight,

hdcMem, 0, 0, 0xE20746L) ;

SelectObject (hdc, hBrush) ;

DeleteDC (hdcMem) ;

BitBlt performs a logical combination of a destination device context (hdc), a source device context (hdcMem), and the brush currently selected in the destination device context. So you create a memory device context, select the bitmap into it, select the colored brush into your client-area display context, and call BitBlt. Then you select the original brush into your display device context and delete the memory device context.

The only puzzling part of this code is the ROP code 0xE20746. This ROP code causes Windows to perform the logical operation:

((Destination ^ Pattern) & Source) ^ Destination

Still not obvious? Try this approach: Copy this part of the table on page 620:

Pattern: 1 1 1 1 0 0 0 0
Source: 1 1 0 0 1 1 0 0
Destination: 1 0 1 0 1 0 1 0
Result: ? ? ? ? ? ? ? ?

For every black bit in the bitmap (which will be selected into the source memory device context), you want the destination device context to be unchanged. This means that everywhere the Source is a 0, you want the Result to be the same bit as the Destination:

Pattern: 1 1 1 1 0 0 0 0
Source: 1 1 0 0 1 1 0 0
Destination: 1 0 1 0 1 0 1 0
Result: ? ? 1 0 ? ? 1 0

We're halfway there. For every white bit in the bitmap, you want the destination device context to be colored with the pattern. The brush you select in the destination device context is this pattern. So everywhere the Source is 1, you want the Result to be the Pattern:

Pattern: 1 1 1 1 0 0 0 0
Source: 1 1 0 0 1 1 0 0
Destination: 1 0 1 0 1 0 1 0
Result: 1 1 1 0 0 0 1 0

This means that the high word of the ROP code is 0xE2. You can look that up in the ROP table in Chapter 11 of the Programmer's Reference and find that the full ROP code is 0xE20746.

Perhaps at this point you discover that you mixed up the white and black bits when you created the bitmap in SDKPAINT. That's easy to fix. It's merely a different logical operation:

Pattern: 1 1 1 1 0 0 0 0
Source: 1 1 0 0 1 1 0 0
Destination: 1 0 1 0 1 0 1 0
Result: 1 0 1 1 1 0 0 0

Now the high word of the ROP code is 0xB8, and the entire ROP code is 0xB8074A, which performs the logical operation:

((Destination ^ Pattern) & Source) ^ Pattern

Here's the second example: Back in Chapter 8, I discussed the two bitmaps that make up icons and cursors. The use of two bitmaps allows these figures to be ”transparent“ in spots or to invert the display surface underneath. For a monochrome icon or cursor, the two bitmaps are coded as follows:

Bitmap 1: 0 0 1 1
Bitmap 2: 0 1 0 1
Result: Black White Screen Inverse Screen

Windows selects Bitmap 1 into a memory device context and uses BitBlt with a ROP code called SRCAND to transfer the bitmap to the display. This ROP code performs the logical operation:

Destination & Source

In Bitmap 1, the destination is left unchanged for 1 bits and set to 0 for 0 bits. Windows then selects Bitmap 2 into the device context and uses BitBlt with SRCINVERT. The logical operation is:

Destination ^ Source

In Bitmap 2, this leaves the destination unchanged for all 0 bits and inverts the destination for all 1 bits.

Look at the first and second columns of the table: Bitmap 1 with SRCAND blacks out the bits, and Bitmap 2 with SRCINVERT turns selected bits to white by inverting the black bits. These operations set the black and white bits that make up the icon or cursor. Now look at the third and fourth columns of the table: Bitmap 1 with SRCAND leaves the display unchanged, and Bitmap 2 with SRCINVERT inverts the colors of selected bits. These operations let the icon or cursor be transparent or invert the underlying colors.

Another example of the creative use of ROP codes accompanies the description of the GrayString function in Chapter 14.