Home

GDI Tools

 

Pens

 

The Fundamentals of a Pen

In the previous lesson, we mentioned that, in order to draw, two primary objects are needed: a platform and a tool. So far, we were using the platform, called a device context. We introduced the main device context represented by, or accessed with, the TCanvas class. To draw, we have been using a pointer to TCanvas. A TCanvas variable does not just give us access to the device context, it also initializes it.

A pen is a tool used to draw lines and curves on a device context. In graphics programming, a pen is also used to draw the borders of a geometric closed shape such as a rectangle or a polygon. To make it an efficient tool, a pen must produce some characteristics on the lines it is asked to draw. These characteristics can range from the width of the line drawn to their colors, from the pattern applied to the level of visibility of the lines. To manage these properties, Microsoft Windows considers two types of pens: cosmetic and geometric.

  • A pen is referred to as cosmetic when it can be used to draw only simple lines of a fixed width, less than or equal to 1 pixel
  • A pen is geometric when it can assume different widths and various ends.

Creating and Selecting a Pen

As mentioned already, the device context is a combination of the platform on which the drawing is performed and the necessary tools to draw on it. To make drawing quick, when selecting a device context, which is already done for all objects that have a TCanvas member variable, the device context is initialized with some default values. One of these is a pen. This is why we have been able to draw shapes so far, without realizing that the device context was already equipped with a pen for us. A pen is like any other device context tool. It is equipped with characters that define its behavior and control its role on the canvas.

The VCL supports pens through a class called TPen. When an object that has a TCanvas member variable comes up, it is equipped with a pen already and you can use it as you see fit. To use that pen, simply access the Pen member variable of the TCanvas class. If you want to explicitly create a pen, you can declare a TPen variable using the new operator. Whether using the TCanvas::Pen member variable or a TPen variable, once you have a pen, you can change its characteristics through its own member variables.

Win32 Support of Pens

The Win32 library defines a pen as HPEN, a handle to a pen. The Win32 library supports pens through various functions. To make sure an HPEN can be used on a canvas, the TCanvas class of the VCL is equipped with a Handle member variable. This variable is used to get a handle to a Win32 HPEN and make it available to a VCL object.

To create a pen in Win32, you can call the CreatePen() function. Its syntax is:

HPEN CreatePen(int fnPenStyle, int nWidth, COLORREF crColor);

After calling this function, make sure you retrieve its return value so you can assign it to the Handle member variable of TCanvas::Pen.

The Win32 API also provides the LOGPEN structure that you can use to individually specify each characteristics of a logical pen. The LOGPEN structure is created as follows:

typedef struct tagLOGPEN { 
	UINT nStyle; 
	POINT nWidth; 
	COLORREF nColor; 
} LOGPEN, *PLOGPEN;

To use this structure, declare a variable of LOGPEN type or a pointer. Then initialize each member of the structure. If you do not, its default values would be used and the line may not be visible. After initializing the LOGPEN variable, call the CreatePenIndirect() function to create a pen. The syntax of the CreatePenIndirect() function is:

HPEN CreatePenIndirect(CONST LOGPEN *lplgpn);

The LOGPEN value is passed to this method as a pointer. After this call, the new pen is available and can be selected into a device context variable for use.

Characteristics of a Pen

The color of a pen is one of its most visual characteristics. To support colors, the TPen class provides a Color property. Its value follows the same rules we reviewed for a color object. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	Canvas->Pen->Color = clRed;
	Canvas->MoveTo(20, 15);
	Canvas->LineTo(255, 82);
}
//---------------------------------------------------------------------------

Although most lines are drawn continuously, the VCL and the Win32 library support non-continuous lines. This characteristic is controlled by the style of the pen. For a TPen object, this would be the Style property. For the CreatePen() function or the LOGPEN structure, this would be the fnPenStyle argument or member variable. The possible values of the style are:

TPen::Style CreatePen() and
LOGPEN
Illustration Description
psSolid PS_SOLID A continuous solid line
psDash PS_DASH A continuous line with dashed interruptions
psDot PS_DOT A line with a dot interruption at every other pixel
psDashDot PS_DASHDOT A combination of alternating dashed and dotted points
psDashDotDot PS_DASHDOTDOT A combination of dash and double dotted interruptions
psClear PS_NULL   No visible line
psInsideFrame PS_INSIDEFRAME   A line drawn just inside of the border of a closed shape

The Width or nWidth of a pen specifies how wide its line(s) would be. Its value should be greater than or equal to 1. If you specify a width less than 1, it would be restored to 1. The value of the width cannot be applied to all types of pens. This property is directly influenced by the style. A cosmetic pen can have a width of only 1 pixel. If you specify a higher width, it would be ignored. A geometric pen can have a width of 1 or more pixels but the line can only be solid or null. This means that, if you specify the style as psDash, PS_DASH, psDot, PS_DOT, psDashDot, PS_DASHDOT, psDashDotDot, or PS_DASHDOTDOT but set a width higher than 1, the line would be drawn as PS_SOLID.

If you are using the CreatePen() function, to specify the type of pen you are creating, as cosmetic or geometric, use the bitwise OR operator to combine one of the above styles with one of the following:

  • PS_COSMETIC: used to create a cosmetic pen

  • PS_GEOMTERIC: used to create a geometric pen

If you are creating a cosmetic pen, you can also add (bitwise OR) the PS_ALTERNATE style to set the pen at every other pixel.

Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	Canvas->Pen->Style = psDashDotDot;
	Canvas->Pen->Width = 1;
	Canvas->Pen->Color = TColor(RGB(255, 25, 5));

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

Once a pen has been selected, any drawing performed and that uses a pen would use the currently selected pen. If you want to use a different pen, you can either create a new pen or change the characteristics of the current pen.

Here is an example that uses the HPEN:

//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
	HPEN NewPen;
	LOGPEN LogPen;

	LogPen.lopnStyle = PS_SOLID;
	LogPen.lopnWidth = Point(1, 105);
	LogPen.lopnColor = RGB(235, 115, 5);

	NewPen = CreatePenIndirect(&LogPen);
	Canvas->Pen->Handle = NewPen;

	Canvas->Ellipse(60, 40, 82, 80);
	Canvas->Ellipse(80, 20, 160, 125);
	Canvas->Ellipse(158, 40, 180, 80);

	Canvas->Ellipse(100, 60, 110, 70);
	Canvas->Ellipse(130, 60, 140, 70);
	Canvas->Ellipse(100, 90, 140, 110);
}
//---------------------------------------------------------------------------
 

Retrieving a Pen

If you want to know the currently selected pen used on a device context, simple declare a pointer to TPen an initialize it with the TCanvas::Pen of the current Canvas.

Brushes

 

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 Borland C++ Builder

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);
}
//---------------------------------------------------------------------------
 

Using Pens and 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.

If 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.

Icons

 

Introduction

Like a bitmap, an icon is used to display graphics on window objects. While a bitmap can have any dimension the window needs, the size of an icon must be limited. This is because icons assume different roles on an application.

Icons are used to represent folders in Windows Explorer and My Computer:

Creating Icons

To create an icon, on the main menu of Image Editor, you can click File -> New… -> Icon File (.ico). This would call the Icon Properties dialog box, which allows you to specify the icon as a 16x16 or 32x32 pixel graphic. You can also design an icon that consists of 2 or 16 colors. After creating and designing your icon you must save it. An icon is a Windows file whose extension is .ico

Practical Learning Practical Learning: Creating Icons

  1. Start Borland C++ Builder if necessary.
    On the main menu, click Tools -> Image Editor
  2. On the main menu of Image Editor, click File -> New… -> Icon File (.ico)
  3. On the Icon Properties dialog box, click the 32 x 32 (Standard Icon) radio button. In the Colors section, click the 16 Color radio button
  4. Click OK
  5. Press Ctrl + I three times to zoom
  6. On the Tools Palette, click the Rectangle button
  7. On the Color Palette, click the gray button (2nd column, 1st row)
  8. On the drawing area, draw a rectangle as follows:
     
  9. On the Tools Palette, click the Fill button
  10. On the Color Palette, click the red color (3rd column, 2nd row)
  11. Click inside of the drawn gray rectangle
  12. On the Tools Palette, click the Filled Rectangle button
  13. On the Color Palette, click the yellow color (4th column, 2nd row)
  14. Using the drawing tools and the colors on the Color Palette, draw a rectangle as follows:
     
  15. To associate an equivalent smaller icon, under the title bar of the child window, click the New… button:
     
  16. Notice that the 16 x 16 (Small Icon) and 16 Color radio buttons are already selected. Therefore, click OK
  17. Press Ctrl + I five times to zoom
  18. Using the drawing tools on the Tools Palette and the colors on the Colors Palette, draw the flag as follows:
     
  19. On the Tool Palette, click the Line tool
  20. Save the icon as Belgium in the Icons folder of our exercises and return to C++ Builder
  21. Create a new Application and change the form’s caption to Applications Resources
  22. Save the project in a New Folder named Applications Resources
  23. Save the unit as Main and save the project as AppResources
  24. To use the Belgium icon we have just created, on the main menu, click Project -> Options...
  25. In the Project Options dialog box, click the Application property page and click the Load Icon button
  26. Locate the Icons folder in which the Belgium icon was saved and display it in the Look In combo box
     
  27. Click Belgium and click Open
     
  28. On the Project Options, click OK
  29. To execute your project, on the main menu, click Run -> Run
  30. When the main form displays, notice that it uses the small (16x16) Belgium icon
     
  31. After viewing the form, close it
  32. Open Windows Explorer or My Documents and display the contents of the Applications Resources folder. Display the content in Small Icons and Large Icons views
     

     
  33. Notice that the executable file uses the the right icon for each display
  34. Return to Borland C++ Builder

Cursors

 

Introduction

Cursors are another type of application accessory you can design using pens and brushes in Image Editor. A cursor is a small graphic that represents the position of the mouse on a Windows screen. Because Windows is a graphic-oriented operating system, when it installs, it creates a set of standard or regularly used cursors. These can be seen by opening the Control Panel window and double-clicking the Mouse icon. This opens the Mouse Properties dialog box where you can click the Pointers tab to see a list of standard cursors installed by Windows:

Creating Cursors

Microsoft Windows installs a wide array of cursors for various occasions. Besides the cursors provided by Windows, Borland C++ Builder installs additional cursors that can accommodate even more scenarios. If these are still not enough, you can create your own cursors. Using your own, custom cursors involves more steps than using bitmaps and icons.

To create your own cursor, on the main menu of Image Editor, you can click File -> New -> Cursor File (.cur). A starting but empty cursor would be displayed. After designing a cursor, you must save it. It has an extension of .cur.

Essentially, a cursor uses only two colors, black or white. This is because a cursor is only used as an indicator of the presence or position of the mouse pointer on the screen. Based on this (limitation), you ought to be creative. The minimum you can give a cursor is a shape. This can be a square, a rectangle, a circle, an ellipse, a triangle, or any shape of your choice. You can make the cursor fully black by painting it with that color. If you decide to make the cursor completely white, make sure you draw the borders of the cursor. By playing with the frequency of pixels and varying the frequencies of black and white, you can create variances of gray.

Between the black and white colors, two gray degrees are provided to you. In reality these two colors are used to give a transparency to the cursor so the background can be seen when the mouse passes over a section of the document.

Practical Learning Practical Learning: Creating a Cursor

  1. On the main menu of Image Editor, click File -> New… -> Cursor File (.cur)
  2. On the Tools Palette, click the Fill button and right-click the drawing area to give it a white background
  3. On the Tools Palette, click the Line tool
  4. In the line width section, make sure the top line is selected. In the Color Palette, make sure the black color is selected
  5. Draw a vertical line from the pixel on the 6th column and 2nd row from top
  6. Draw a diagonal line at 45˚ from the top border of the new line to the lower-right until the line is at 5 pixels from the right border of the drawing area
     
  7. Draw a horizontal line from the lower border of the dialog line to half-left
  8. Draw a diagonal line from the lower border of the vertical line to the left border of the horizontal line:
     
  9. Draw another diagonal line from the top corner of the current shape to the intersection of horizontal and left diagonal line:

  10. On the Tools Palette, click Fill
  11. On the Color Palette, click the button with a red color and a green S
  12. On the drawing area, click the right triangle
  13. On the Color Palette, click the button with a green background and a red S
  14. On the drawing area, click in the left triangle

  15. To test the cursor, on the main menu, click Cursor -> Test…
  16. Draw a curved line. After previewing the cursor, click Close
  17. On the Color Palette, right-click the button with a green background and a red S
  18. On the drawing area, right-click outside of the shape to apply the necessary background
  19. In the Color Palette, click the black color and click inside the left triangle
  20. In the Color Palette, click the white color and click inside the right triangle
  21. To set the position of the cursor pointer, on the main menu, Cursor -> Set Hot Spot…
  22. Change the Horizontal (X) value to 5 and change the Vertical (Y) value to 1
     
  23. Click OK
  24. To test the cursor, on the main menu, click Cursor -> Test…
  25. Draw various shapes
     
  26. After previewing the cursor, click Close
  27. Save the cursor as Push in the Cursors folder but do not close the cursor window

Other Techniques of Creating Icons and Cursors

 

Icons and Cursors Design

Sometimes in your application, you will want to use the same picture for a bitmap, an icon, and a cursor. Although each category has some predefined rules regarding its design, you can still cleverly use a common design among them. This can be done by simply copying one graphic from one category and pasting it into another category. All you have to do is to adapt the pasted picture to the category you are designing. Of course, there are some rules you will submit to.

If you want to use the same design for a bitmap and an icon, it must be designed with a maximum width and height of 32 pixels. This means that you can use 16, 24, or 32 pixels width and height and you must use a maximum of 16 colors. If you want to use the same design for a bitmap, an icon, and a cursor, you should use a graphic that fits in 32 pixels width and height. Although you can interchangeably copy and paste between a bitmap and an icon, when pasting the same graphic into a cursor, keep in mind that you would be restricted to 2 colors only.

Practical Learning Practical Learning: Sharing Graphics

In the following exercise, the instructions are approximate and you should not take them exactly at face value. As long as you draw a line that approximately resembles the screenshot, you are fine. You do not have to have exactly the same result as the corresponding screenshot.
  1. On the main menu of Image Editor, click File -> New… Cursor (.cur)
    If necessary, press Ctrl + I a few times to zoom in
  2. On the Tools Palette, click Curve
  3. In the drawing area, position your mouse on the top right corner 3 pixels from the right border and one pixel from top
  4. Click and drag down and left to draw a diagonal line to stop at 3 pixels from the left border and 1 pixel from the bottom border:
     
  5. To start the curved line, count the pixels on the line from top. Then click and drag the 5th pixel to the left as if you were drawing a square as follows:
     
  6. To smooth the curved line, click the top-left pixel that is at the intersection of both lines. Drag down and right:
     
  7. With the Curve tool still selected, draw the same diagonal line you drew earlier
  8. Drag the 5th pixel from top of the line to right and down as if you were drawing a square:
     
  9. Click the pixel at the intersection of both lines then drag left and up to draw a curved line:
     
  10. While the Curve tool is selected, draw one more diagonal line similar to the previous ones
  11. To make the line curved, click in the middle of the diagonal line and slightly drag left and up:
     
  12. As you may realize, we are drawing a leaf or feather. Therefore, add a few black pixels to decorate the graphic. Using the Fill tool, add a white background to the cursor:
     
  13. To specify the position of the pointer, on the main menu, click Cursor -> Set Hot Spot…
  14. Set the Horizontal value to 3 and the Vertical value to 30. Click OK
  15. On the main menu, click Cursor -> Test...
  16. Draw a few lines to test the cursor and click Close
  17. Save the file as Feather
  18. Back in Image Editor, make sure the window that has the previously designed cursor has focus
    Press Ctrl + A to select the cursor. Press Ctrl + C to copy the graphic
  19. On the main menu, click File -> New… -> Icon File (.ico)
  20. On the Icon Properties dialog box, click the 32 x 32 (Standard Icon) radio button. In the Colors section, click the 16 Color radio button and click OK
  21. Press Ctrl + V to paste the graphic
  22. On the Tools Palette, click Fill
  23. On the Color Palette, right-click the button with a green color and red S
  24. In the drawing area, right-click outside of the graphic to make background transparent
  25. On the Tools Palette, click Pencil
  26. On the Color Palette, click the dark red (3rd column, 1st row)
  27. In the drawing area, click all black pixels to change their color to dark red
  28. Use the Fill tool and the dark Olive color (4th column, 1st row) the change the areas on both sides of the middle line of the icon
  29. Click the Line tool and select the white color
  30. In the drawing area, without touching the dark red pixels, draw a checkered area on the right side of the middle line:
     
  31. Select the silver color (2nd column, 2nd row) and create a checkered area on the left side of the middle line
  32. Save the icon as Feather but do not close its child window

Transforming an Icon or a Cursor

Besides creating an object from scratch or modifying an existing one we have seen in a few examples so far, you can play with various pictures on your computer or from other resources and get very creative bitmaps, icons, or cursors. This technique consists of taking an object that, by default, in not a bitmap, icon, or cursor, and transforming it into one.

Microsoft Windows installs a few fonts for its internal use and yours. Besides these fonts, you can also purchase new ones. Some of these fonts have curious types of characters you can use for your graphics objects. You can also find icons on the Internet and transform them.

If you find a character of a font that you want to use as an icon or a cursor, you can select it. You should be able to paste it into Image Editor but Image Editor does not faithfully retrieve objects from the clipboard. Therefore, you should first paste it into Microsoft Paint, copy it from Microsoft Paint, and then paste it into the type of graphic you want to create in Image Editor. The only thing left to do is to customize the appearance of your object.

Practical Learning Practical Learning: Transforming Objects for Graphics

  1. Start WordPad
  2. Using the Formatting toolbar, change the Font to Wingdings and change the Font Size to 32
  3. Type 7
    This would produce the picture of a keyboard
     
  4. Press Ctrl + A to select the symbol you have just typed
  5. Press Ctrl + C to copy the symbol (you can now close WordPad if you want)
  6. You should still have Microsoft Paint. Otherwise launch it (Start -> (All) Programs -> Accessories -> Paint)
    In Paint, click File -> New. If you are asked whether you want to save a file, click No
    Press Ctrl + V to paste the selection
  7. Using your mouse and the Select tool , select only the symbol you just pasted:
     
  8. Press Ctrl + C to copy the selection (you can now close Paint if you want)
  9. In Image Editor, to create a new icon, on the main menu, click File -> New -> Icon File (.ico)
  10. Accept the 32 x 32 size and click OK
  11. If necessary, press Ctrl + I a few times to zoom enough
    Press Ctrl + V to paste the picture of the keyboard
    While the picture is still selected, drag and position it to leave three empty lines at the bottom and one empty line on the right side
  12. Using the Tool and the Color Palettes, design the icon as follows:
     
  13. In WordPad, select the displaying character. Change the font size to 14. Copy and paste the character in a new document in Windows Paint
  14. Copy the character from Paint to the clipboard
  15. On the toolbar of Image Editor, click New. Accept the 16 x 16 size and click OK
  16. Zoom in and Paste
  17. Design the icon as follows:
     
  18. Save the icon as Keyword

Applications Resources

 

Introduction

In the programming world, a resource is any external object that you can use to complete your application. As you have seen so far, we had to use an external application to create icons and cursors. For a regular application, a resource can be picture, a sound file, a dialog box, a cursor, a menu, an icon, anything. Most of the time, when you need one of these, first check if you can get it inside C++ Builder; that will be the case for all dialog boxes and menus we will use in this book. Some other resources just have to be gotten from another application. For example, although you can program a music application in C++ Builder, you cannot create a music file using it; you would need an external application.

There is no strict rule on what a resource is or is not, except that it is a file with an extension. For a programming resource file, it (primarily) has an extension of rc dcr that helps the compiler identify it. In order to use it in your application, the file has to be compiled into a format that the compiler can understand. Fortunately, you can do this compilation and include the file into your application from C++ Builder. You must first create and gather the necessary resources, then make them available to your application.

Creating a Resource File

Although there are, and can be, various types of resources, here we will cover only icons and cursors. A resource for an application can include icons, pictures (bitmaps), and cursors. To create such a resource, on the main menu of Image Editor, you can click File -> New... You can click either Component Resource File (.dcr) or Resource File (.res). Once you have a resource file, you can add the objects by right-clicking, New, and clicking the category of object you want to include.

C++ Builder in combination with Image Editor make the process of using a resource file easy. You have two main alternatives.

  • If you plan to use just bitmaps, icons, and cursors, in Image Editor, create a Resource File (.res) and add the desired bitmaps, icons, and resources. Once you have created the res file, you can include it in your application by clicking Project -> Add To Project… from the main menu of C++ Builder. When you execute your project, C++ Builder would recognize it as a compiled file and you do not have to worry about anything else
  • Sometimes you will need to create a non-compiled file. In this case, in Image Editor, you can create a Component Resource File (*dcr) file and add the desired files to it. Once you have a dcr file, in C++ Builder, add it to your project (Project -> Add To Project). When you execute the project, C++ Builder would take care of compiling it and produce a res file, then use that res file where needed in your project.

Practical Learning Practical Learning: Creating and Using a Resource

  1. In the main menu of Image Editor, click File -> New... -> Resource File (.res)
  2. On the main menu, click Resource -> New -> Cursor
  3. While the new cursor is still selected, on the main menu, click Resource -> Rename. Type PointMe and press Enter
  4. In the resource window, click Contents to select it. Then right-click it and New -> Cursor
  5. Right-click the new cursor and click Rename. Type Scripter and press Enter
  6. On the main menu, click Window and click the line that has Push.cur
  7. To select the cursor, press Ctrl + A. to copy the selection, press Ctrl + C
  8. On the main menu, click Window -> Untitled1.res
  9. In the child window, double-click POINTME and press Ctrl + V to paste
  10. On the Tools Palette, click any button to dismiss the blinking line
  11. On the main menu, click Window and click the line that has Feather.cur
  12. Press Ctrl + A then press Ctrl + C
  13. On the main menu, click Window -> Untitled1.res
  14. Double-click SCRIPTER and press Ctrl + V. Click any button in the Tools Palette
  15. On the main menu, click Window -> Untitled1.res
  16. On the main menu, click File -> Save
  17. Locate and display the Applications Resources folder in which our current application is located. In the File Name box, click Untitled1 to select it
  18. Type Exercise and press Enter
  19. Go to C++ Builder
  20. To include the necessary resource, on the main menu, click Project -> Add To Project...
  21. Using the bottom combo box, change the Files Of Types to Compiled Resource (*.res)
  22. In the list, click Exercise.res
     
  23. In the header file of the main form, Main.h, on top of the class, declare two constant integers as follows:
     
    //---------------------------------------------------------------------------
    #ifndef MainH
    #define MainH
    //---------------------------------------------------------------------------
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    const int PushAway = 1;
    const int WriteItDown = 2;
    //---------------------------------------------------------------------------
    class TForm1 : public TForm
    {
    __published: // IDE-managed Components
    private: // User declarations
    public: // User declarations
    	__fastcall TForm1(TComponent* Owner);
    };
    //---------------------------------------------------------------------------
    extern PACKAGE TForm1 *Form1;
    //---------------------------------------------------------------------------
    #endif
  24. Press F12 to display the form
  25. On the Tool Palette, click Standard and click Panel
  26. On the form, draw a rectangle from the top-left side to the middle-center of the form
  27. In the Tool Palette, click Memo and draw a rectangle on the right side of the existing panel on the form
  28. Press F12 to display the Code Editor and click the Main.cpp tab
  29. In the constructor of the form, initialize the cursors as follows:
     
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
    {
    	Screen->Cursors[PushAway] = LoadCursor(HInstance, "POINTME");
    	Screen->Cursors[WriteItDown] = LoadCursor(HInstance, "SCRIPTER");
    }
    //---------------------------------------------------------------------------
    

     

  30. Press F12 to display the form. Double-click in the middle of the form to access its OnCreate event
  31. Implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	Panel1->Cursor = TCursor(PushAway);
    	Memo1->Cursor = TCursor(WriteItDown);
    }
    //---------------------------------------------------------------------------
  32. To test your application, press F9
     

     
  33. Close the project
Previous Copyright © 2005 Yevol Next