Home

Command Controls

 

Command Buttons

 

Overview

A button is a Windows control used to initiate an action. From the user’s standpoint, a button is useful when clicked, in which case the user positions the mouse on it and presses one of the mouse’s buttons. There are various kinds of buttons. The most common and most regularly used is a rectangular object. In some programming environments, the classic button is called a Command Button. There are other controls that can serve as click controls and initiate the same behavior as if a button were clicked. Such controls include a label, a static control, or a panel.

For a programmer, a button needs a host or container. The container could be a form, a toolbar, etc. Once you have decided where the button will reside, you can use the drag n’ drop process of Borland C++ Builder to add it to your program.

The most popular button used in Windows applications is a rectangular control that displays a word or a short sentence that directs the user to access, dismiss, or initiate an action or a suite of actions. In C++ Builder, this control is implemented using the Button control from the Standard section of the Tool Palette. Therefore, to add a button to a container, click the Button control and click on the container, which is usually a form. Once you have added the control to your application, you can set its properties using the Object Inspector.

Button Properties

For a user, the only things important about a button are the message it displays and the action it performs. The default property of a button is the Caption: this is the word or group of words that display(s) on top of the control, showing the message that would direct the user as to what the button is used for. By default, after adding a button to a form, the Caption property of the Object Inspector has focus; this allows you to just type a caption.

When adding a button to a form, the Caption field would have focus only if the last action you performed on the Object Inspector was for a control that does not have Caption. If the last control you were working on has a Caption property but you were setting another property, when you add a button, the Caption field would not have focus.

The most popular captions are OK and Cancel. The OK caption is set for a form or a dialog box that informs the user of an error, an intermediary situation, or an acknowledgement of an action that was performed on the dialog that hosts the button. The Cancel caption is useful on a button whose main parent (the form) would ask a question or request a follow-up action from the user. Whenever a dialog box allows the user to dismiss it without continuing the action, you should provide a button with a Cancel caption.

The easiest way to change the caption on a control, on the Object Inspector, is to click the word Caption and type the desired text.

After adding a button to a form (by design or with code), you can change its caption with code by calling the TControl::Caption property. For example, you can change the caption of a button as follows:

//---------------------------------------------------------------------------
void __fastcall TForm1::ChangeButtonCaption()
{
	Button1->Caption = "Let Me Go!";
}
//---------------------------------------------------------------------------
When a form is hosting many controls, including buttons, it is a good idea to set the control that has focus when the form opens. This is done using the form’s ActiveControl property. By default, as we know about the Tab Order, the order of controls on a container is directed by the order of adding them to the container. Even if a control was added last, and regardless of the Tab Order, you can set a certain control to have focus when the form launches.

To set the ActiveControl at design time, give focus to the form. On the Object Inspector, click the ActiveControl field to reveal its combo box; click its combo box and select a control from the list.

To set the active control programmatically, call the TForm::ActiveControl property (actually, the ActiveControl property belongs to the TCustomForm class). Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::SetTheActiveControl()
{
	ActiveControl = Button3;
}
//---------------------------------------------------------------------------

A very important characteristic of a button is the Default property, which is a Boolean type. If you set its value to true, this button would have a thick border. If the user presses Enter any time, the action associated with the button would be executed. This is usually set on a dialog box with a button whose caption displays OK.

Another useful property is Cancel. Using a Boolean variable, the Cancel property allows the user to press Esc to perform the same action that would be used to dismiss a dialog box. This is important on a dialog box if the button’s caption is Cancel or Close.

As mentioned already, a dialog box can be created with one or more buttons. If you create a modal dialog box and equip it with more than one button, when the user closes it, you must know what button the user had clicked. To support this, the VCL provides the ModalResult property. This property autonomously can control the behavior of the closing dialog box depending on the button that was clicked.

The ModalResult property is an integer defined as TModalResult and provides various values that each can be used on a button of a dialog box. To set the desired value, after adding a button to a dialog box and while the button is selected, on the Object Inspector, access its ModalResult property and select the desired value. 

The possible values of the ModalResult property are:

Constant Value Description
mrNone 0 No special role
mrOk idOK The user clicked OK or pressed Enter (assuming the button has the Default property set to true) to close
mrCancel idCancel The used clicked Cancel or pressed Esc (assuming the button has the Cancel property set to true) to close
mrAbort idAbort The user clicked Abort to close
mrRetry idRetry The user clicked Retry to close
mrIgnore idIgnore The user clicked Ignore to close
mrYes idYes The user clicked Yes to close
mrNo idNo The user clicked No to close
mrAll mrNo + 1 The user clicked All to close
mrNoToAll mrAll + 1 The user clicked No To All to close
mrYesToAll mrNoToAll + 1 The user clicked Yes To All to close

If the form that is hosting the button is not the first form or dialog (in other words, if the form is accessed by a call from another form), you can use the ModalResult property to conveniently associate an action. By default, the ModalResul is set to mrNone.

The ModalResult property is an integer that represents a button that the user has clicked on a dependent dialog box. To use a button as a valid integral ModalResult value, set its ModalResult property. When coding the result of the user clicking one of the buttons, call the TForm::ShowModal() method (once again, the ShowModal() method actually belongs to the TCustomForm class) and assign it the corresponding value of the TModalResult integer.

The following example uses two forms. The first form has a button used to call the second. The second form has buttons with different ModalResult values. After the user clicks the button on the first form, the second would display, the program simply finds out what button was clicked, and the programmer can act accordingly:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	if( Form2->ShowModal() == mrOk )
		Caption = "I am OK now";
		else if( Form2->ShowModal() == mrCancel )
		Caption = "Soldier, dismiss!!!";
	else
	{
		Form2->Close();
		Caption = "What happened? Where are you?";
	}
}
//---------------------------------------------------------------------------

Button Events

The most regular action the user performs on a button is to click it. Based on this, the default event on a button is OnClick. To initiate the OnClick event on a button, you can double-click it.

One of the most regular actions you will assign to a button is to close its parent form when the user clicks the button. There are different reasons you would want to close a form. If the form that hosts the button displays an intermediary message to the user, you should provide all the necessary code to follow up after the user has clicked the button; this is the case of property sheets or wizard pages, among others.

There are various ways you can close a dialog box from a button. The simplest way is to call the TCustomForm::Close() method. This dismisses the form. To close a form, you can also use the Win32 API’s PostQuitMessage() function. This function takes one argument that is an integer. The argument could be set to almost any integer value although it should be WM_QUIT.

Button Methods

The Button doest not have many methods to customize its behavior. This is because a button does not need more than what you would expect from it: point and click. Probably the only method you would use from a button is the constructor used to dynamically create a button. Most of the other methods used on a button are derived from member variables of the TWinControl class.

Bitmap Buttons

 

Introduction

A bitmap button is a command button that displays a bitmap and possibly a caption on top. The main difference between a bitmap button and a command button is that, by design, the former displays a bitmap.

A bitmap button is based on the TBitBtn class. To create a bitmap button, you can use the BitBtn button from the Additional tab of the Tool Palette.

Bitmap Button Characteristics

Because a bitmap button is usually meant to display a bitmap, you may want to provide a bitmap for it. If you want the button to also display a caption, you can proceed as the regular button and use the Caption property on the Object Inspector.

There are two primary ways you can provide or add a bitmap to the button. C++ Builder ships with combinations of bitmaps and captions for a bitmap button. To use one of these, after adding a BitBtn control to a container, on the Object Inspector, click Kind and select one of the types of buttons. Some of the buttons you create using one of the Kind types have already been configured to properly respond to the dialog box or form on which they are used. This works only if the form or dialog box is added to an existing form. The possible values of the Kind property and their effect on the application are:

Constant Picture Observation Returns
bkCustom See Below No special role mrNone
bkOK This value should be used if either it is the only button on a dialog box or the user will need to acknowledge a message after performing some action on the form. In this case the user should either click this button or press Enter.
After this Kind value is set, the Default property is automatically set to true, which gives the button a thick border.
mrOk
bkCancel This value should be used if the user will need the opportunity to dismiss whatever action would have been performed on the form. The button that uses this Kind is usually accompanied by another button labeled OK.
After this Kind value is set, the Cancel property is automatically set to true. 
mrCancel
bkAbort Used to display Abort. mrAbort
bkRetry Used to display Retry. mrRetry
bkIgnore Used to display Ignore. mrIgnore
bkYes This value should be used the user will be presented with a Yes/No question. The button should not be used with another button labeled OK on the same container.
After this Kind value is set, the Default property is automatically set to true and the button gets equipped with a thick border.
mrYes
bkNo Used to display No and return the mrAbort value mrNo
bkHelp Used to display Help  
bkClose    
bkAll Used to display Yes to All and return the mrYesToAll value mrYesToAll

If none of the default bitmaps is satisfying to you, you can replace it with a bitmap of your choice. If you do not like the caption, you can simply click the Caption field in the Object Inspector and type a string of your choice.

The bkCustom value of the Kind property allows you to set both the bitmap and the caption without using the pre-selections. In either case, the bitmap of the button is specified using the Glyph property of the Object Inspector. To change it, click the Glyph field and then click its ellipsis button to display the Picture Editor. This allows you to load, select, and open a bitmap of your choice. You can either design your own bitmap or use those that get installed with C++ Builder. By default, they are located in the C:\Program Files\Common Files\Borland Shared\Images\Buttons.

To position itself, a bitmap uses a margin distance between its location and the button’s borders. This is controlled by the Margin property.

On a bitmap button, you can use only the bitmap, only the caption, or both the bitmap and the caption. If you decide to use both, you have the opportunity to specify how they would appear next to each other. The alignment of the bitmap with regards to the caption is controlled by the Layout property, which is based on the TButtonLayout enumerator. Its possible values are:

Value Appearance
blGlyphLeft
blGlyphRight
blGlyphTop
blGlyphBottom

If you decide to use both a bitmap and a caption, the distance between them is controlled by the Spacing property whose default value is 4 pixels. You can change it to a reasonable value if you need to.

The bitmap used should/must have at least a 16x16 pixels size. C++ Builder allows you to use a bitmap made of more than one glyph. In this case, the bitmap must be created like a single picture image list with a height of 16 pixels at most. If it contains two bitmaps, it should have a size of 32x16. The picture used for a bitmap button should not have more than 3 bitmaps. Otherwise, the fourth and beyond glyphs would be ignored.

After adding the bitmaps, C++ Builder would find the number of glyphs that the bitmap contains using the “physical” size of the picture based on the fact that each bitmap has a width of 16 pixels. The number of glyphs is set using the NumGlyphs property and it is automatically set by C++ Builder. Based on this, if you add a 16x16 pixels bitmap, its NumGlyphs value would be set to 1. A 32x16 bitmap would have a NumGlyphs value set to 2. A 48x16 bitmap would have the NumGlyph property set to 3. If you think that the number set by C++ Builder is not right, you can change it on the Object Inspector.

Here is how the number of glyphs influences the appearance of the bitmap button:

  • If the bitmap contains 1 glyph, the single bitmap would always be used except when the button is disabled. The operating system is in charge of painting the face of the button when it is disabled
  • If the bitmap contains 2 glyphs, the first glyph would be used both when the button is clicked and not clicked. The second glyph would be used when the button is disabled
  • If the bitmap contains 3 glyphs, the first would be used when the button displays normally. The second glyph would display while the button is down when it has been clicked. The third would display when the button is disabled.

Practical Learning Practical Learning: Using Speed Buttons

  1. Start a new application with its default form
  2. Start saving it and create a new folder named BitmapButtons1
  3. Save the unit as Main and save the project as BitmapButtons
  4. Open Image Editor and create a new 16 x 16 pixels bitmap
  5. Design it as follows:
     
  6. Save it as Library in the BitmapButtons folder of the current project
  7. Create a new 48 x 16 pixels bitmap and design it as follows:
     
  8. Save it as Attached and return to Borland C++ Builder
  9. While the form is displaying, on the Object Inspector, Set the following properties:
    Caption = Bitmap Buttons
    Name = frmMain
    BorderStyle: bsDialog
    Height: 210
    Width: 144
    ShowHint = true
  10. From the Additional tab of the Tool Palette, click the BitBtn control BitBtn and click on the form
  11. On the Object Inspector, click Kind and click the arrow of its combo box. Select bkClose
  12. Add another BitBtn control BitBtn under the first one
  13. While the new bitmap button is still selected, on the Object Inspector, click Glyph and click its ellipsis button
  14. On the Picture Editor dialog box, click the Load button. In the Load Picture dialog box, click Library
     
  15. Click Open and click OK
  16. While the new button is still selected, in the Object Inspector, click Caption and type Library
  17. Set its Hint to Consult the Library and check that the NumGlyphs property has a value of 3
  18. Add another BitBtn control under the second one. While the new bitmap button is still selected, on the Object Inspector, click Glyph and click its ellipsis button . Using the Load button of the Picture Editor dialog box and the Load Picture dialog box, select the Attached bitmap
  19. On the Object Inspector, check that the NumGlyphs property has a value of 3 and change the button’s properties as follows:
    Caption: Attach
    Enabled: false
    Name: btnAttachment
    Hint: Send With Attachment
  20. Add one BitBtn control BitBtn under the previous one. Set its Glyph to C:\Program Files\Common Files\Borland Shared\Images\Buttons\bulbon.bmp
  21. Change its following properties:
    Name: btnAllowIt 
    Caption: Allow It
    Hint: Allow item if ready
  22. On the form, double-click the last button to access its OnClick event and implement it as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TfrmMain::btnAllowItClick(TObject *Sender)
    {
    	btnAttachment->Enabled = !btnAttachment->Enabled;
    }
    //---------------------------------------------------------------------------
  23. Save your project and test it:
     
  24. After using it, close it and return to Borland C++ Builder

Speed Buttons

 

Introduction

The speed button control provides the ability to create command buttons that behave either like optional, mutual-exclusive items or like checked objects. A speed button can be configured so that, when it has been clicked, it would stay down until it is clicked again (this behavior is the same as a check box). You can also create a group of speed buttons so that, out of the group, the selected one would display and keep a clicked or down state (like radio buttons) while the other button(s) of the same group is (are) down. This allows only one of the items in the group to appear clicked when chosen.

Over all, a speed button’s behavior is configured as that of a regular button. The design of the speed button provides the most different aspect of the control.

Speed Buttons Characteristics

To create a speed button, use the SpeedButton control from the Additional tab of the Tool Palette to add it to the desired container. Unlike most other actions, when using either a speed or a radio buttons, you should pay attention to the container you are using as it can play a critical role to the behavior of the button.

A newly added speed button appears with a 3D border, like the regular command button. You can make it appear flat with a mouse over effect. This appearance is controlled by the Flat property. Its default value is false. If you set it to true, its border would disappear. When the mouse passes over it, its borders would be raised and they would disappear when the mouse is no longer over it. Because its borders disappear with a true value, when you set this property like that, make sure you provide a way for the user to know that the button is present. This can be done using a caption, a bitmap, or both on the face of the button.

By default, when a speed button is clicked, it performs its Click action and remains as it was before. As mentioned already, a speed button can be configured to keep its clicked or not clicked state. This means that, after a speed button has been clicked, it can stay down even after the mouse gets set to another control. To provide this down appearance, change the value of the GroupIndex property. The default value of the GroupIndex property is 0, which means that it would appear down only when clicked and while the mouse is pressing it. If you change it to a value other than 0 but with a value used by no other speed button on the same container, after the the button has been clicked, it would stay clicked until the user clicks it again.

Alternatively, you can create a series of speed buttons that behave in what is described as “mutually exclusive”. In this case, when one button has been clicked, it stays down and the other buttons stay up. If another button of the same group gets clicked, it becomes down; the previous down button and all the other buttons, if more than one, would stay up. To provide this mutual-exclusive functionality, set the same value of GroupIndex to all button that should be part of the group.

The value of the GroupIndex property can be specified in decimal or hexadecimal format. At design time, if you set it to a hexadecimal format, C++ Builder would convert it to its decimal value.

After changing the GroupIndex value of a button or a group of buttons, you can give a primary down state to the button or to one of the buttons of the group or keep it or them to its, or their, default appearance. The state of the button can be set using the Down property. At design time and at run time, you can set its value to true or false. At run time, you can check the value of the Down property to find out whether the button is down or not.

If you have created a group of speed buttons and gave them the same GroupIndex value, as mentioned already, they behave in a mutual exclusive scenario. At any given time, one button in the group would always be down while the others are up. If the user clicks a button that is already down, nothing would happen with regards to their appearance. This is the default behavior of the group. If you want the buttons to be up all of them in response to an action of your choice, use the AllowUp Boolean property. Here is what this characteristic provides:

  • If the AllowUp property is set to false:
    • If the user clicks a button that is not down in the group, it would become down and the other button(s) would become up
    • If the user clicks a button that is already down in the group, nothing would change with regards to their appearances
  • If the AllowUp property is set to true:
    • If the user clicks a button that is not down in the group, it would become down and the other button(s) would become up
    • If the user clicks a button that is already down in the group, the button would become up like the other button(s) and no button would be down

By default, a newly added speed button has a Height of 22 pixel and a Width of 23 pixels. These dimensions are appropriate to display a 16x16 pixels bitmap. A speed button is usually used to display a bitmap but you can use it to show a bitmap and a caption. After adding the button to a container, if you want it to display only a caption, you can type it in the Caption property of the Object Inspector. If you prefer only a bitmap, use the Glyph property to select and specify the bitmap. If you want both a caption and a bitmap, you should resize the button enough to accommodate them.

If you plan to use a bitmap on the speed button, its Glyph, its Spacing, its NumGlyphs, its Margin, and its Layout properties function similar to the same properties of the bitmap button. The Glyph property of the speed button provides a small addition. Like the bitmap button, the speed button can use a bitmap made of one or more glyphs. Unlike the bitmap button, the speed button can use up to four glyphs and here is how they work:

  • If the bitmap contains 1 glyph, the bitmap should have a size of 16x16 pixels (width x height). This single bitmap would always be used except when the button is disabled. The operating system is in charge of displaying or painting the face of the button when it is disabled.
  • If the bitmap contains 2 glyphs, the bitmap should have a size of 32x16 pixels. The first glyph would be used both when the button is clicked or down and when the button is not clicked or is not down. The second glyph would be used when the button is disabled.
  • If the bitmap contains 3 glyphs, it should have a size of 48x16 pixels. The first would be used when the button displays normally. The second glyph would display when the button is disabled. The third glyph would display while the button is down when it has been clicked.
  • If the bitmap contains 4 glyphs, it should have a size of 64x16 pixels. This style is valid only if the button is a member of a group (like radio buttons). The first would be used when the button displays normally. The second glyph would display when the button is disabled. The third glyph would display while the button is down when it has been clicked, exactly like the button with a NumGlyphs value equal to 3 but with the following exception. If the button is a member of a group, the third glyph would display while the mouse is still “pushing” it; that is, while the button is down but held by the mouse. The fourth glyph is used only if the button is part of a group and when it is down after the mouse has been released.

Property Sheet and Wizards Buttons

 

Buttons on a Property Sheet

A priori, a property page is just a control container and does not need buttons to function. Here is an example of a property sheet without communication buttons:

Microsoft Visual C++ 6 Properties Window

Most other property sheets are equipped with buttons like a regular dialog box. As such, a property sheet is usually equipped with the OK and Cancel buttons. Sometimes it is additionally equipped with an Apply button. And sometimes it has a Help button.

Property Sheet Buttons Implementation

You add the buttons on a property sheet the same way you would for a dialog box. Simply click the Button control from the Standard section or the BitBtn bitmap button from the Additional tab of the Tool Palette and click the area of the property page where you want to place the button(s).

Normally, in the strict sense, the buttons that perform the exchange of information with other parts of the application are positioned on the property sheet and not on the property page(s). That is, the buttons are positioned outside of the property page. The buttons can be positioned on the right side of the property sheet. That is the case for the Colors dialog box of Microsoft Word:

Most of the time, the buttons are positioned on the bottom section of the property sheet.

Generally, the button labeled OK, if present, should have the Default property set to true. The Cancel button should have the Cancel property set to true. By convention, the OK button, if available should be either the top most or the left most. If the Apply button is used, it should be the right most, which should have the Cancel button between both.

Like any regular dialog box, the property page(s) of a property sheet is(are) equipped with Windows controls whose values the user may be asked to modify. When a property sheet is equipped with buttons, there are rules you should follow when implementing their behavior, to be in accordance with other Windows applications:

  • After using the property sheet, if the user wants to validate the changes that were made on the property pages, he can click OK. The OK button closes the property sheet and acknowledges whatever the user would have done on the controls the page(s) is(are) hosting. If the user did not make any changes, clicking OK should not make any difference, unless you configured some controls to automatically change their values when the user opens the property sheet
  • When the property sheet comes up, if (many property sheets do not have an Apply button, as you can check on most dialog boxes of C++ Builder) it is equipped with it, the Apply button should be disabled, indicating to the user that, so far, there has not been any change made on any of the control(s) of the property page(s)



    After the property sheet is opened, once the user changes any value of any of the controls, the Apply button should be enabled, indicating to the user that the property sheet is now “dirty” (in computer programming, a document is referred to as dirty when it is not anymore the way it was when it was opened). Here is an example:



    While the user is making changes, if she wants to validate or check them without closing the property sheet, she can click the Apply button. This means that, clicking the Apply button (if available) would acknowledge the changes of values of the controls, just like the OK button. The difference is that the property sheet would not be closed. After clicking it, the Apply button should become disabled again, indicating that, at this time, the controls are clean



    The user can continue making changes and clicking the Apply button if necessary
  • If the property sheet is equipped with an OK and a Cancel button without an Apply button, if the user makes changes on some or all of the controls but does not want to validate them, he can click Cancel to dismiss the dialog box. In this case, any change(s) made on the control(s) would be discarded
  • If the property sheet is equipped with an OK, a Cancel, and an Apply buttons, if the user makes changes and clicks Apply, we saw that the changes would be acknowledged and validated. This would then disable the Apply button, again. If the user makes changes and clicks Cancel, only the new changes would be discarded; any change made before the Apply button was clicked would be validated and sent to the object that called the property sheet.

C++ Builder provides a fast means of creating a property sheet and equips it with the OK, the Cancel, and the Help buttons. To use it, open the New Items dialog box and click the Forms property page. Then double-click Tabbed Pages.

Wizards Buttons

As seen when reviewing controls containers, a wizard is a series of dialog boxes that assist the user with performing a task that requires intermediary steps. To implement its functionality, a wizard displays some button in the lower section of the dialog box.

Depending on the programmer, different wizards use a few or more buttons. Usually a wizard has buttons such as Back, Next, and Cancel. Here is an example:

Practical Learning Practical Learning: Creating a Wizard

  1. Create a new project with its default form
  2. From the Standard page of the Tool Palette, double-click the Panel control.
  3. Set the following properties for the panel (leave the other properties intact):
    BevelOuter: bvNone
    Caption: empty
    Height: 265
    Left: 0
    Name: pnlFirstPage
    Top: 0
    Width: 430
  4. From the Tool Palette, click the Edit control and click anywhere on the panel. This is a simple control that will serve as an indication when we are in the first page
  5. Click the panel on the form to make sure it is selected
  6. On the main menu, click Edit -> Copy
  7. Click an empty area on the form to deselect the panel and select the form
  8. On the main menu, click Edit -> Paste
  9. With the new pasted panel still selected, change its properties as follows:
    Left: 0
    Name: pnlSecondPage
    Top: 0
  10. From the Tool Palette, click the ScrollBox control and click on the panel.
  11. Click an empty area on the form to select the form
  12. From the main menu, click Edit -> Paste
  13. For the newly pasted panel, change the properties as follows:
    Left: 0
    Name: pnlThirdPage
    Top: 0
  14. On the Tool Palette, click the GroupBox control and click on the current panel
  15. On the Tool Palette, click the Additional tab
  16. Click the Bevel control
  17. Click an unoccupied area in the lower section of the form
  18. Change the properties of the Bevel control as follows:
    Height: 25
    Left: 0
    Shape: bsTopLine
    Top: 272
    Width: 430
  19. On the Tool Palette, click the Standard section
  20. Click the Button control
  21. Click in the lower section of the form
  22. Change the properties of the button as follows:
    Caption: &Back
    Left: 112
    Name: btnBack
    Top: 280
  23. Add another button on the right side of the Back button and change its name to btnNext
  24. Add another button of the right side of the Next button and change its name to btnFinish
  25. Add one more button on the right side of the finish button. Set its Cancel property to true and its name to btnCancel

Wizard Implementation

When a wizard starts, the user is presented with the first page. After using it, he or she can click Next to move to the subsequent page. The user can continue clicking Next to complete the necessary task(s) on each page. At any time and except on the first page, the user can click the Back button to move backward.

Most wizards have a Cancel button that would allow the user to dismiss the dialog box. In this case, whatever change the user would have performed on the controls hosted by the wizard would be discarded.

Many wizards are also equipped with a Finish button. There are two scenarios in which the Finish button can be used:

  • If the button displays at all times, that is, regardless of the page that is displaying, the presence of a Finish button means the user can click it to close the dialog box and end the task(s) performed. Here is an example of such a wizard:
     
  • In most other wizards, when the user gets to the last page, the Next button would be changed to Finish. This allows the user to click Finish to close the dialog box. Here is an example:
     

    Clicking Finish closes the wizard and sends the results or values of the controls on the pages to whatever is the purpose of the wizard.

Practical Learning Practical Learning: Allowing Setup of a Print

  1. Double-click the Cancel button to access its OnClick() event
  2. Implement the event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btnCancelClick(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
  3. To bring back the form, press F12
  4. Double-click an empty area on the form to access the form's OnCreate() event
  5. Implement the FormCreate() event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormCreate(TObject *Sender)
    {
    	// We are in the first page now
    	pnlFirstPage->Visible = True;
    	pnlSecondPage->Visible = False;
    	pnlThirdPage->Visible = False;
    	btnBack->Enabled = False;
    }
    //---------------------------------------------------------------------------
  6. Press F12 to display the form
  7. Double-click the Back button to access its OnClick() event
  8. Implement it as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btnBackClick(TObject *Sender)
    {
    	if( pnlSecondPage->Visible == True )
    	{
    		pnlFirstPage->Visible = True;
    		pnlSecondPage->Visible = False;
    		pnlThirdPage->Visible = False;
    		btnBack->Enabled = False;
    		btnNext->Enabled = True;
    	}
    	else if( pnlThirdPage->Visible == True )
    	{
    		pnlFirstPage->Visible = False;
    		pnlSecondPage->Visible = True;
    		pnlThirdPage->Visible = False;
    		btnBack->Enabled = True;
    		btnNext->Enabled = True;
    		btnFinish->Enabled = True;
    	}
    }
    //---------------------------------------------------------------------------
  9. Press F12 to bring back the form
  10. Double-click the Next button and implement its OnClick() event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btnNextClick(TObject *Sender)
    {
    	// If you are in the first page
    	if( pnlFirstPage->Visible == True )
    	{
    		pnlFirstPage->Visible = False;
    		pnlSecondPage->Visible = True;
    		pnlThirdPage->Visible = False;
    		btnBack->Enabled = True;
    		btnNext->Enabled = True;
    		btnFinish->Enabled = True;
    	}
    	else if( pnlSecondPage->Visible == True )
    	{
    		pnlFirstPage->Visible = False;
    		pnlSecondPage->Visible = False;
    		pnlThirdPage->Visible = True;
    		btnBack->Enabled = True;
    		btnNext->Enabled = False;
    		btnFinish->Enabled = False;
    	}
    	else// if( pnlThirdPage->Visible == True )
    	{
    		btnNext->Enabled = True;
    		btnBack->Enabled = True;
    		btnFinish->Enabled = True;
    	}
    }
    //---------------------------------------------------------------------------
  11. Press F12 to bring back the form
  12. Double-click the Finish button and implement its OnClick() event as follows:
     
    //---------------------------------------------------------------------------
    void __fastcall TForm1::btnFinishClick(TObject *Sender)
    {
    	pnlFirstPage->Visible = False;
    	pnlSecondPage->Visible = False;
    	pnlThirdPage->Visible = True;
    	btnBack->Enabled = True;
    	btnNext->Enabled = False;
    }
    //---------------------------------------------------------------------------
  13. To test the application, press F9
Previous Copyright © 2005 Yevol Next