Brushes
Tutorial


by Itay Sagui

Brushes are a tool provided by the system in order to paint the interior or polygons, ellipses and paths. When using a brush, the system puts the selected brush in the 'brush origin', usually the (0,0) coordinate of the device, and copy it over and over again, until the entire device is filled. However, the brush pattern is visible only within the boundaries of the specified shape.

There are several ways to create the different types of brushes. Let's look at them:

1. CreateSolidBrush


Private Declare Function CreateSolidBrush Lib "gdi32" Alias "CreateSolidBrush" (ByVal crColor As Long) As Long



This function accept an RGB color, and return the handle of a solid brush using that color.

2. GetStockObject


Private Declare Function GetStockObject Lib "gdi32" (ByVal nIndex As Long) As Long



This function accept the index of the demanded object, and returns its handle. Although this function is used for other purposes too, I'll give you only the brushes indexes:


Private Const WHITE_BRUSH = 0
Private Const LTGRAY_BRUSH = 1
Private Const GRAY_BRUSH = 2
Private Const DKGRAY_BRUSH As Long = 3
Private Const BLACK_BRUSH As Long = 4
Private Const NULL_BRUSH = 5
Private Const HOLLOW_BRUSH = NULL_BRUSH



The stocked brushes are a set of brushes that the system always keeps in memory. They are pretty simple to understand - they are actually solid brushes, with a predefined color.

3. GetSysColorBrush


Private Declare Function GetSysColorBrush Lib "user32" Alias "GetSysColorBrush" (ByVal nIndex As Long) As Long



Similar to the GetStockObject, this function returns the handle to a always-in-memory brush that uses one of the system colors.


Private Const COLOR_SCROLLBAR As Long = 0
Private Const COLOR_BACKGROUND As Long = 1
Private Const COLOR_ACTIVECAPTION As Long = 2
Private Const COLOR_INACTIVECAPTION As Long = 3
Private Const COLOR_MENU As Long = 4
Private Const COLOR_WINDOW As Long = 5
Private Const COLOR_WINDOWFRAME As Long = 6
Private Const COLOR_MENUTEXT As Long = 7
Private Const COLOR_WINDOWTEXT As Long = 8
Private Const COLOR_CAPTIONTEXT As Long = 9
Private Const COLOR_ACTIVEBORDER As Long = 10
Private Const COLOR_INACTIVEBORDER As Long = 11
Private Const COLOR_APPWORKSPACE As Long = 12
Private Const COLOR_HIGHLIGHT As Long = 13
Private Const COLOR_HIGHLIGHTTEXT As Long = 14
Private Const COLOR_BTNFACE As Long = 15
Private Const COLOR_BTNSHADOW As Long = 16
Private Const COLOR_GRAYTEXT As Long = 17
Private Const COLOR_BTNTEXT As Long = 18
Private Const COLOR_INACTIVECAPTIONTEXT As Long = 19
Private Const COLOR_BTNHIGHLIGHT As Long = 20
Private Const COLOR_3DDKSHADOW As Long = 21
Private Const COLOR_3DLIGHT As Long = 22



Those are the main indexes, but there are several more that I didn't show here.

4. CreateHatchBrush


Private Declare Function CreateHatchBrush Lib "gdi32" (ByVal nIndex As Long, ByVal crColor As Long) As Long



This function accept the index of the hatch and a color. Here is a list of some of the hatches:


Private Const HS_HORIZONTAL As Long = 0
Private Const HS_VERTICAL As Long = 1
Private Const HS_FDIAGONAL As Long = 2
Private Const HS_BDIAGONAL As Long = 3
Private Const HS_CROSS As Long = 4



Again, I urge you to play a bit with these values, and figure out yourself what each one of them means.

5. CreatePatternBrush


Private Declare Function CreatePatternBrush Lib "gdi32" (ByVal hBitmap As Long) As Long



In order to create a pattern brush, you must first create a bitmap. One of the ways to do so is to set an array of integers that will create the pattern.


Private Declare Function CreateBitmap Lib "gdi32" (ByVal nWidth As Long, ByVal nHeight As Long,
ByVal nPlanes As Long, ByVal nBitCount As Long, lpBits As Integer) As Long Dim bBytes(1 To 8) As Integer For i = 1 To 8 bBytes(i) = 170 '170 = 10101010 Next hBitmap = CreateBitmap(8, 8, 1, 1, bBytes(1)) mBrush = CreatePatternBrush(hBitmap)


We create a bitmap according to our array, and then we pass the created bitmap to the CreatePatternBrush function.

Another option for creating a pattern brush is using the CreateDIBPatternBrushPt function, that I will not show here.

6. CreateBrushIndirect


Private Declare Function CreateBrushIndirect Lib "gdi32" Alias "CreateBrushIndirect" (lpLogBrush As
LOGBRUSH) As Long Private Type LOGBRUSH lbStyle As Long lbColor As Long lbHatch As Long End Type


Using this function you can just fill in the LOGBRUSH structure with a color, a style and an hatch, can call the function. For the different hatches look at the previous 'CreateHatchBrush' section. For the style, here a partial list:


Private Const BS_SOLID As Long = 0
Private Const BS_HOLLOW As Long = 1
Private Const BS_HATCHED As Long = 2
Private Const BS_PATTERN As Long = 3



Now that we've created a brush, we can finally use it. There are several ways to use the brushes, and here I will show you one of them, without going too much into details:


Private Declare Function PatBlt Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal
y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal dwRop As Long) As Long Private Const PATCOPY = &HF00021 SelectObject Me.hdc, hBrush PatBlt Me.hdc, 0, 0, 30, 30, PATCOPY


The general idea is that you select you newly created brush into a certain device, and then you whatever drawing function you wish, as long as that function uses the device's selected brush.

One last thing to remember when using brushes, is that you should always remove the brushes that you've created from memory, using the DeleteObject API. Although Windows do that automatically, it is not recommended to count on that, but to do it yourself:


Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long
DeleteObject hBrush