Brushing the Interior

The interiors of the Rectangle, RoundRect, Ellipse, Chord, Pie, Polygon, and PolyPolygon figures are filled in with the current brush (also sometimes called a ”pattern“) selected in the device context. A brush is an 8-by-8 bitmap that is repeated horizontally and vertically to fill the area.

When Windows uses dithering to display more colors than are normally available on a display, it actually uses a brush for the color. On a monochrome system, Windows can use dithering of black and white pixels to create 64 different shades of gray. More precisely, Windows can create 64 different monochrome brushes. For pure black, all bits in the 8-by-8 bitmap are 0. One bit out of the 64 is made 1 (that is, white) for the first gray shade, two bits are white for the second gray shade, and so on, until all bits in the 8-by-8 bitmap are 1 for pure white. On a color video system, dithered colors are also bitmaps, and a much wider range of color is available.

We've already used stock brushes. Windows also has four functions that let you create logical brushes. You select the brush into the device context with SelectObject. Like logical pens, logical brushes are GDI objects. Any brush that you create must be deleted, but it must not be deleted while it is selected in the device context.

Here's the first function to create a logical brush:

hBrush = CreateSolidBrush (rgbColor) ;

The word Solid in this function doesn't really mean that the brush is a pure color. When you select the brush into the device context, Windows creates an 8-by-8 bitmap for a dithered color and uses that bitmap for the brush. We used CreateSolidBrush in the COLORS1 program in Chapter 6. The brush was used as the background color defined in the window class structure.

You can also create a brush with ”hatch marks“ made up of horizontal, vertical, or diagonal lines. Brushes of this style are most commonly used for coloring the interiors of bar graphs and when drawing to plotters. The function for creating a hatch brush is:

hBrush = CreateHatchBrush (nHatchStyle, rgbColor) ;

The nHatchStyle parameter describes the appearance of the hatch marks. The parameter can be one of the following styles: HS_HORIZONTAL, HS_VERTICAL, HS_FDIAGONAL, HS_BDIAGONAL, HS_CROSS, and HS_DIAGCROSS. Figure 12-13 shows the kind of hatch marks that each of these styles produces.

The rgbColor parameter of CreateHatchBrush is the color of the hatch lines. When you select the brush into a device context, Windows converts this color to the nearest pure color. The area between the hatch lines is colored based on the background mode and background color defined in the device context. If the background mode is OPAQUE, the background color (which is also converted to a pure color) is used to fill in the spaces between the lines. In this case, neither the hatch lines nor the fill color can be a dithered color. If the background mode is TRANSPARENT, Windows draws the hatch lines without filling in the area between them.

Earlier I discussed the problems that you can encounter with pen colors when you develop a program on a color display and later run the program on a monochrome display. You should beware of the same problems when you choose colors for hatch marks and the brush background. Colored hatch marks that look fine on a color display may disappear into the background when displayed in monochrome.

Because brushes are always 8-by-8 bitmaps, the appearance of hatch brushes will also vary according to the resolution of the device on which they are displayed. Each of the hatch marks shown in Figure 12-13 was drawn in a 32-by-16-pixel rectangle, which means that the 8-by-8 bitmap was repeated 4 times horizontally and 2 times vertically. On a 300-dots-per-inch laser printer, the same 32-by-16-pixel rectangle would occupy an area about 1/9 inch wide and 1/19 inch high.

You can also create your own brushes based on bitmaps using CreatePatternBrush:

hBrush = CreatePatternBrush (hBitmap) ;

This function was discussed in Chapter 9. The hBitmap parameter is a handle to an 8-by-8 bitmap. How you get this bitmap handle is covered in the next section of this chapter.

Windows also includes a function that encompasses the three other functions for creating brushes (CreateSolidBrush, CreateHatchBrush, and CreatePatternBrush):

hBrush = CreateBrushIndirect (&logbrush) ;

The variable logbrush is a structure of type LOGBRUSH (”logical brush“). The three fields of this structure are shown below. The value of the lbStyle field determines how Windows interprets the other two fields:

lbStyle (WORD) lbColor (DWORD) lbHatch (short)

BS_SOLID Color of brush Ignored
BS_HOLLOW Ignored Ignored
BS_HATCHED Color of hatches Hatch brush style
BS_PATTERN Ignored Handle to bitmap

Earlier we used SelectObject to select a logical pen into a device context, DeleteObject to delete a logical pen, and GetObject to get information about a logical pen. You can use these same three functions with brushes. Once you have a handle to a brush, you can select the brush into a device context using SelectObject:

SelectObject (hdc, hBrush) ;

You can later delete a created brush with the DeleteObject function:

DeleteObject (hBrush) ;

Do not delete a brush that is currently selected into a device context, however. If you need to obtain information about a brush, you can call GetObject:

GetObject (hBrush, sizeof (LOGBRUSH), (LPSTR) &logbrush) ;

where logbrush is a structure of type LOGBRUSH.