Home

GDI Tools: Brushes

 

The Image Editor

 

Introduction

C++ Builder ships with a graphic application called Image Editor. Image Editor is used to create or manipulate small to medium, various types of, pictures needed in computer and graphic applications. These graphics are divided in categories that have different roles. Image Editor provides pens and brushes used to design its objects.

Starting Image Editor

There are various ways you can launch Image Editor:

  • If you had started C++ Builder, to start a graphic, on the main menu of C++ Builder, you can click Tools -> Image Editor
  • Image Editor is installed in the same group as C++ Builder. To start Image Editor at anytime, from the taskbar, you can click Start -> (All) Programs -> Borland C++ Builder -> Image Editor
  • Image Editor is installed in the same location as C++ Builder. Therefore, in Windows Explorer or My Computer, locate C:\Program Files\Borland\Cbuilder6\Bin, and double-click imagedit or imagedit.exe

Using the Image Editor

When Image Editor appears, it is mainly made of four areas.

On top, there is the title bar that displays Image Editor and the main menu. The title bar has the same classic look shared by Windows applications. Under the title bar, the menu, here called the main menu, allows you to perform all regular operations of an application. Image Editor is a Multiple Document Interface (MDI) application. This means that it allows you to open or work on different child windows. By default, when Image Editor starts, it does not create a new document. To create a graphic, you will have to let Image Editor know what kind of graphic you want to work on. Once you open or start a new document, the menu would change according to the type of graphic you are using.

To open an existing document, on the main menu, you can click File -> Open… and locate the desired document. To create a new document, on the main menu, you would click File -> New… and select the type of document you want.

The menu is used as on all other documents. For example, if you make a mistake on a graphic and want to dismiss the last action, you can click Edit -> Undo or press Ctrl + Z. In the same way, you can copy by clicking Edit -> Copy or pressing Ctrl + C. In other words, most of the shortcuts you are familiar with are available.

On the left side of the application, the Tools Palette displays buttons that will be used to create new graphics or manipulate existing ones.

To find out what a button is used for, position the mouse on top. A tool tip, or hint, would display. The buttons are used for various goals and exhibit different behaviors.

 

Some tools such as the Pencil, lines, and the geometric shapes (rectangle, round rectangle, and ellipse) allow you to specify a width for their lines.
Some tools such as the Brush or the Spray allow you to select a thickness for the dot or mark they would apply to a graphic. To access this change, first select the Brush or Spray, then, in the lower section of the Tools Palette, select the the thickness you want.

I f you change the default line width of a tool, the selected width or thickness stays in memory and can be applied to a tool that does not obviously display this option. This happens if you a great width for a rectangle and then decide to use a Filled Rectangle tool, the last width would apply to the new tool. Therefore, if you do not want to use the same width, select the default before using another tool.

The main area of the application is made of a wide black rectangle that is used to host the graphics you will be using.

Like the top section, the bottom area of the application contains two objects. The Color Palette displays a list of 16 colored buttons (by default)

Under the Color Palette, there is the Status Bar.

After using Image Editor, you can close it. You have a few alternatives:

  • On the main menu, you can click File -> Exit
  • The shortcut to close such an application as Image Editor is Alt + F4
  • To close Image Editor, you can press either Alt, f, x or Alt + X

When closing Image Editor, if you had a modified document that needs to be saved, you would be prompted to save it.

Graphics used in the Windows operating system are divided in categories. Probably the most popular of the graphics natively used in the operating system is called a bitmap.

 

Introduction

A brush is a drawing tool used to fill out a closed shape. It is similar to picking up a bucket and pouring its contents somewhere. In the case of computer graphics, the area where you position the brush is called the brush origin. The color (or picture) that the brush holds would be used to fill the whole area until the brush finds a limit set by some rule. A brush can be characterized by its color (if used), its pattern used to fill the area, or a picture (bitmap) used as the brush.

The VCL provides support for brushes through the TBrush class. The TCanvas class has a TBrush member variable. This means that, any object that can receive or perform drawing, that is, every control that provides a Canvas member variable, already provides a TBrush variable ready for use. If you want to explicitly create a brush, you can declare a TBrush variable and use it to initialize the TCanvas::Brush member variable.

Win32 Support of Brushes

Because there can be so many variations of brushes, the Win32 library provides various functions for creating or managing brushes. Nevertheless, the Win32 API considers a brush to be a handle to a brush and it is defined as HBRUSH. Each of the functions used to create a brush returns HBRUSH.

Besides using a function to create a brush, the Win32 library provides the LOGBRUSH structure that can be used to create a logical brush by specifying its characteristics.

The TBrush class is equipped with a Handle member variable. After using one of the Win32 functions used to create a brush object, retrieve its HBRUSH value and initialize the TBrush::Handle member variable with it. After this initialization, the brush is ready to be used by the TCanvas class.

Solid Brushes

A brush is referred to as solid if it is made of a color simply used to fill a closed shape. The TBrush class is equipped with a Color member variable. To create a solid brush, simply assign a TColor value to the TBrush::Color variable. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	Canvas->Brush->Color = static_cast<TColor>(RGB(250, 25, 5));

	Canvas->Rectangle(20, 20, 250, 125);
}
//---------------------------------------------------------------------------

Once a brush has been selected, it would be used on all shapes that are drawn under it, until you delete or change it. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	Canvas->Brush->Color = static_cast<TColor>(RGB(255, 2, 5));

	TPoint Pt[3];

	// Top Triangle
	Pt[0] = Point(125, 10);
	Pt[1] = Point( 95, 70);
	Pt[2] = Point(155, 70);

	Canvas->Polygon(Pt, 2);

	// Left Triangle
	Pt[0] = Point( 80, 80);
	Pt[1] = Point( 20, 110);
	Pt[2] = Point( 80, 140);

	Canvas->Polygon(Pt, 2);

	// Bottom Triangle
	Pt[0] = Point( 95, 155);
	Pt[1] = Point(125, 215);
	Pt[2] = Point(155, 155);

	Canvas->Polygon(Pt, 2);

	// Right Triangle
	Pt[0] = Point(170, 80);
	Pt[1] = Point(170, 140);
	Pt[2] = Point(230, 110);

	Canvas->Polygon(Pt, 2);
}
//---------------------------------------------------------------------------

If you want to use a different brush, you must change the characteristic(s) of the currently selected brush or create a new one. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	Canvas->Brush->Color = static_cast<TColor>(RGB(255, 2, 5));

	TPoint Pt[3];

	// Top Triangle
	Pt[0] = Point(125, 10);
	Pt[1] = Point( 95, 70);
	Pt[2] = Point(155, 70);

	Canvas->Brush->Color = clGreen;
	Canvas->Polygon(Pt, 2);

	// Left Triangle
	Pt[0] = Point( 80, 80);
	Pt[1] = Point( 20, 110);
	Pt[2] = Point( 80, 140);

	Canvas->Brush->Color = clRed;
	Canvas->Polygon(Pt, 2);

	// Bottom Triangle
	Pt[0] = Point( 95, 155);
	Pt[1] = Point(125, 215);
	Pt[2] = Point(155, 155);

	Canvas->Brush->Color = clYellow;
	Canvas->Polygon(Pt, 2);

	// Right Triangle
	Pt[0] = Point(170, 80);
	Pt[1] = Point(170, 140);
	Pt[2] = Point(230, 110);

	Canvas->Brush->Color = clBlue;
	Canvas->Polygon(Pt, 2);
}
//---------------------------------------------------------------------------

To support solid brushes, the Win32 API provides the CreateSolidBrush() function. Its syntax is:

HBRUSH CreateSolidBrush(COLORREF crColor);

Therefore, to create a brush, you can call this function and pass it a COLORREF color value. Retrieve the return value of this function and use it to initialize the Handle member variable of the TBrush class.

Hatched Brushes

A hatched brush is one that uses a drawn pattern to regularly fill an area. Microsoft Windows provides 6 preset patterns for such a brush.

To create a hatched brush, the TBrush class is equipped with the Style property. Style can have the following values: bsSolid, bsClear, bsBDiagonal, bsFDiagonal, bsCross, bsDiagCross, bsHorizontal, and bsVertical.

The Win32 API supports hatched brushes through the CreateHatchBrush() function. Its syntax is:

HBRUSH CreateHatchBrush(int fnStyle, COLORREF clrref );

The fnStyle parameter specifies the hatch pattern that must be used to fill the area. The possible values to use are HS_BDIAGONAL, HS_CROSS, HS_DIAGCROSS, HS_FDIAGONAL, HS_HORIZONTAL, or HS_VERTICAL. The clrref argument specifies the color applied on the drawn pattern.

 

Practical Learning Practical Learning: Displaying Brush Hatches

  1. Start a new Application with the default form
  2. Change the form’s Caption to Hatched Brushes
  3. Access the OnPaint event of the form and implement it as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormPaint(TObject *Sender)
    {
    	Canvas->Brush->Color = static_cast<TColor>(RGB(0, 0, 255));
    	Canvas->Brush->Style = bsBDiagonal;
    	Canvas->RoundRect( 20, 30, 160, 80, 10, 10);
    
    	Canvas->Brush->Style = bsFDiagonal;
    	Canvas->Brush->Color = static_cast<TColor>(RGB(0, 128, 192));
    	Canvas->RoundRect(180, 30, 320, 80, 10, 10);
    
    	Canvas->Brush->Style = bsDiagCross;
    	Canvas->Brush->Color = static_cast<TColor>(RGB(0, 128, 0));
    	Canvas->RoundRect(340, 30, 480, 80, 10, 10);
    
    	Canvas->Brush->Style = bsVertical;
    	Canvas->Brush->Color = static_cast<TColor>(RGB(0, 128, 0));
    	Canvas->RoundRect(20, 120, 160, 170, 10, 10);
    
    	Canvas->Brush->Style = bsHorizontal;
    	Canvas->Brush->Color = static_cast<TColor>(RGB(255, 128, 0));
    	Canvas->RoundRect(180, 120, 320, 170, 10, 10);
    
    	Canvas->Brush->Style = bsCross;
    	Canvas->Brush->Color = static_cast<TColor>(RGB(200, 0, 0));
    	Canvas->RoundRect(340, 120, 480, 170, 10, 10);
    
    	Canvas->Font->Style = TFontStyles() << fsBold;
    	Canvas->Font->Color = static_cast<TColor>(RGB(0, 0, 255));
    	Canvas->TextOut(40, 10, "HS_BDIAGONAL");
    	Canvas->Font->Color = static_cast<TColor>(RGB(0, 128, 192));
    	Canvas->TextOut(205, 10, " bsBDiagonal");
    	Canvas->Font->Color = static_cast<TColor>(RGB(0, 128, 0));
    	Canvas->TextOut(355, 10, " bsDiagCross");
    	Canvas->Font->Color = static_cast<TColor>(RGB(255, 0, 255));
    	Canvas->TextOut(44, 100, " bsVertical");
    	Canvas->Font->Color = static_cast<TColor>(RGB(255, 128, 0));
    	Canvas->TextOut(195, 100, " bsHorizontal");
    	Canvas->Font->Color = static_cast<TColor>(RGB(200, 0, 0));
    	Canvas->TextOut(370, 100, " bsCross");
    }
    //---------------------------------------------------------------------------
  4. Test the application
     
  5. Close it and return to Bcb

Logical Brushes

The Win32 library provides the LOGBRUSH structure to create a brush by specifying its characteristics. The LOGBRUSH structure is defined as follows:

typedef struct tagLOGBRUSH { 
	UINT lbStyle; 
	COLORREF lbColor; 
	LONG lbHatch; 
} LOGBRUSH, *PLOGBRUSH;

The lbStyle member variable specifies the style applied on the brush.

The lbColor is specified as a COLORREF value.

The lbHatch value represents the hatch pattern used on the brush. . It takes the same value as the fnStyle parameter of the CreateHatchBrush() function.

After initializing the LOGBRUSH variable, pass it to the CreateBrushIndirect() function. Its syntax is:

HBRUSH CreateBrushIndirect(CONST LOGBRUSH *lplb);

Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	LOGBRUSH LogBrush;

	LogBrush.lbStyle = BS_HATCHED;
	LogBrush.lbColor = RGB(255, 0, 255);
	LogBrush.lbHatch = HS_DIAGCROSS;

	HBRUSH NewBrush = CreateBrushIndirect(&LogBrush);
	Canvas->Brush->Handle = NewBrush;

	Canvas->Rectangle(20, 12, 250, 175);
}
//---------------------------------------------------------------------------
Home Copyright © 2005-2012, FunctionX, Inc.