You can use a bitmap in a brush by creating a pattern brush. After creating the pattern brush, 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 does the StretchBlt function.
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(hinst, "checks");
hBrush = CreatePatternBrush(hBitmap);
You can then select the brush 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 member of the window-class structure, as in the following example:
pWndClass->hbrBackground = CreatePatternBrush(hBitmap);
Once you have assigned the brush handle to hbrBackground, Windows uses the pattern brush whenever 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);
Note that this statement changes the background brush for all windows of this class. If you want to change only the background for one window, you must explicitly process the WM_ERASEBKGND messages that the window receives. The following example shows how to process this message:
case WM_ERASEBKGND:
UnrealizeObject(hBrush);
hOldBrush = SelectObject((HDC) wParam, (HGDIOBJ) hBrush);
GetClientRect(hwnd, &Rect);
PatBlt((HDC) wParam, Rect.left, Rect.top,
Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
SelectObject((HDC) wParam, (HGDIOBJ) hOldBrush);
return TRUE;
The WM_ERASEBKGND message passes a handle of a device context in the wParam parameter. The SelectObject function selects the desired background brush into the device context. The GetClientRect function retrieves the area that needs to be erased. 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.
Whenever your application or the user moves a window in which a pattern brush has been or will be used, your application must align the 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 that is no longer needed. This function does not, however, delete the bitmap along with the brush. To delete the bitmap, call DeleteObject again and specify the bitmap handle.