You can use bitmaps in a brush by creating a pattern brush. Once the pattern brush is created, you can select the brush into a device context and use the PatBlt function to copy it to the screen; or the Rectangle, Ellipse, and other drawing functions can use the brush to fill interiors. When Windows draws with a pattern brush, it fills the specified area by repeatedly copying the bitmap horizontally and vertically as necessary. It does not adjust the size of the bitmap to fit in the area as the StretchBlt function does.
If you use a bitmap in a pattern brush, the bitmap should be at least 8 pixels wide by 8 pixels high—the default pattern size used by most display drivers. (You can use large bitmaps, but only the upper-left, 8-by-8 corner will be used.) You may hard-code the bitmap, create and draw it, or load it as a resource. In any case, once you have the bitmap handle, you can create the pattern brush by using the CreatePatternBrush function. The following example loads a bitmap and uses it to create a pattern brush:
hBitmap = LoadBitmap(hInstance, “checks”);
hBrush = CreatePatternBrush(hBitmap);
Once a pattern brush is created, you can select it into a device context by using the SelectObject function:
hOldBrush = SelectObject(hDC, hBrush);
Since the bitmap is part of the brush, this call to the SelectObject function does not affect the device context's selected bitmap.
After selecting the brush, you can use the PatBlt function to fill a specified area with the bitmap. For example, the following statement fills the upper-left corner of a window with the bitmap:
PatBlt(hDC, 0, 0, 100, 100, PATCOPY);
The PATCOPY raster operation directs PatBlt to completely replace the destination image with the pattern brush.
You can also use a pattern brush as a window's background brush. To do this, simply assign the brush handle to the hbrBackground field of the window-class structure as in the following example:
pWndClass->hbrBackground = CreatePatternBrush(hBitmap);
Thereafter, Windows uses the pattern brush when it erases the window's background. You can also change the current background brush for a window class by using the SetClassWord function. For example, if you want to use a new pattern brush after a window has been created, you can use the following statement:
SetClassWord(hWnd, GCW_HBRBACKGROUND, hBrush);
Be aware that this statement changes the background brush for all windows of this class. If you only want to change the background for one window, you need to explicitly process the WM_ERASEBKGND messages that the window receives. The following example shows how to process this message:
RECT Rect;
HBRUSH hOldBrush;
.
.
.
case WM_ERASEBKGND:
UnrealizeObject(hMyBkgndBrush);
hOldBrush = SelectObject(wParam, hMyBkgndBrush);
GetUpdateRect(wParam, (LPRECT)&Rect, FALSE);
PatBlt(wParam, Rect.left, Rect.top,
Rect.right - Rect.left, Rect.bottom - Rect.top,
PATCOPY);
SelectObject(wParam, hOldBrush);
break;
The WM_ERASEBKGND message passes a handle to a device context in the wParam parameter. The SelectObject function selects the desired background brush into the device context. The GetUpdateRect function retrieves the area that needs to be erased (this is not always the entire client area). The PatBlt function copies the pattern, overwriting anything already in the update rectangle. The final SelectObject function restores the previous brush to the device context.
The UnrealizeObject function is used in the preceding example. Whenever your application or the user moves a window in which you have used or will use a pattern brush, you need to align your pattern brushes to the new position by using the UnrealizeObject function. This function resets a brush's drawing origin so that any patterns displayed after the move match the patterns displayed before the move.
You can use the DeleteObject function to delete a pattern brush when it is no longer needed. This function does not, however, delete the bitmap along with the brush. To delete the bitmap, you need to use DeleteObject again and specify the bitmap handle.