Home

Win32 Controls: Check Boxes

 

Introduction to Check Boxes

 

Description

A check box is a Windows control that allows the user to set or change the value of an item as true or false. Although it can appear by itself, a check box sometimes comes in a group with others, allowing the user to select as many choices as are available. Depending on the application, a little square Check Box appears.

The user makes a selection by clicking in the square which toggles a check mark Check Box. Toggling means that if the square were empty, after clicking it, a check mark would appear in it. Otherwise, the check mark would be removed. Like a radio button, a check box is usually accompanied by a label to indicate what the check control is used for.

From the userís standpoint, a check box is selected when its check mark is set; and the item is not selected when its square is empty. From the developer standpoint, a check mark has two (Boolean) values: true or false (or TRUE or FALSE, or True or False). When a check mark is selected, its value is true. Otherwise, its value is false.

 

Practical LearningPractical Learning: Introducing Check Boxes

  1. Start Embarcadero RAD Studio
  2. To start a new project, in the Tool Palette, click C++Builder
  3. Double-click the VCL Forms Application icon VCL Forms Application
  4. In the Object Inspector, change the formís following properties:
    Caption: Payroll Evaluation
    Name: frmEvaluation
    Position: poScreenCenter
  5. Design the form as follows:
     
    Payroll Evaluation
    Control Alignment Caption/Text Name
    TBevel TPanel      
    TLabel TLabel   Employee Name:  
    TEdit TSpeedButton     edtEmployeeName
    TLabel TLabel   Hourly Salary:  
    TEdit TSpeedButton taRightJustify 0.00 edtHourlySalary
    TBevel TPanel      
    TLabel TLabel   Monday  
    TLabel TLabel   Tuesday  
    TLabel TLabel   Wednesday  
    TLabel TLabel   Thursday  
    TLabel TLabel   Friday  
    TLabel TLabel   Saturday  
    TLabel TLabel   Sunday  
    TLabel TLabel   Week 1:  
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Monday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Tuesday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Wednesday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Thursday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Friday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Saturday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek1Sunday
    TLabel TLabel   Week 2:  
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Monday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Tuesday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Wednesday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Thursday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Friday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Saturday
    TEdit TSpeedButton taRightJustify 0.00 edtWeek2Sunday
    TBevel TPanel      
    TButton TButton   Calculate btnCalculate
    TLabel TLabel   Time  
    TLabel TLabel   Pay Amount  
    TStaticText TLabel   Pay Without Overtime Rule  
    TLabel TLabel   Regular:  
    TEdit TSpeedButton taRightJustify 0.00 edtRegularTime
    TEdit TSpeedButton taRightJustify 0.00 edtRegularPay
    TLabel TLabel   Net Pay:  
    TEdit TSpeedButton taRightJustify 0.00 edtNetPay
    TLabel TLabel   Overtime:  
    TEdit TSpeedButton taRightJustify 0.00 edtOvertime
    TEdit TSpeedButton taRightJustify 0.00 edtOvertimePay
    TButton TButton   Close btnClose
     

Creating a Check Box

To support check boxes, the VCL provides the a TCheckBox class. The TCheckBox class is derived from the TCustomCheckBox class. Both classes are members of the StdCtrls.hpp header file. In Microsoft Windows, a check box is just a special button. For this reason, the TCustomCheckBox class is based on the TButtonControl class. The TButtonControl class is based on the TWinControl class:

TCheckBox Inheritance

To visually create a check box, from the Standard section of the Tool Palette, click the TCheckBox control TCheckBox and click the desired section of the form or container. In the same way, you can add as many check boxes as you want. If you want to use more than one check box, you should first place a group control on your form, then add the desired check boxes in it.

To dynamically create the control, declare a variable of type TCheckBox, use the new operator to initialize the object. You must also specify what control owns the check box. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TCheckBox* Checker = new TCheckBox(Form1);
	Checker->Parent = Form1;
}
//---------------------------------------------------------------------------

If the check box will be hosted by a container other than the form, specify this as the parent:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TCheckBox* Checker = new TCheckBox(Form1);
	Checker->Parent = Group;
}
//---------------------------------------------------------------------------

If you do not have or cannot get a container at design time, you can also dynamically create one that would host the dynamic check boxes.

Check boxes provide "non-exclusive" choice, which means that each check box behave independently with regards to the other check boxes of the same container. If you are creating just one check box, you can place it where you want on the form. If you are creating more than one check box that are addressing the same issue, you should include them in a rectangular container so their belonging to the same group would be obvious to the user. The group can be hosted by a group box, a bevel, a radio group, or a panel controls. If you place the controls in a bevel or a radio group, since these two are true containers for other controls, you will not be able to move all controls as one object during design.

Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TGroupBox* Group = new TGroupBox(Form1);
	Group->Parent = Form1;
	Group->Left = 16;
	Group->Top = 32;
	Group->Caption = "Preferred Sports";

	TCheckBox* chkFootball = new TCheckBox(Form1);
	chkFootball->Parent = Group;

	TCheckBox* chkHandball = new TCheckBox(Form1);
	chkHandball->Parent = Group;
}
//---------------------------------------------------------------------------

Practical Learning Practical Learning: Creating a Check Box

  1. In the Tool Palette, if necessary, click Standard.
    In the Standard section, click the TCheckBox button TCheckBox
  2. On the form, click the top border of the bottom bevel
  3. In the Object Inspector, click Name
  4. Type chkApplyOvertimeRules and press Enter

Characteristics of Check Boxes

 

Introduction

A check box is programmed as a regular control. It inherits the location from its ancestors: the Left and Top properties. You can specify these characteristics during design or at run time. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TGroupBox* Group = new TGroupBox(Form1);
	Group->Parent = Form1;
	Group->Left = 16;
	Group->Top = 32;
	Group->Caption = "Preferred Sports";

	TCheckBox* chkFootball = new TCheckBox(Form1);
	chkFootball->Parent = Group;
	chkFootball->Left = 16;
	chkFootball->Top = 16;

	TCheckBox* chkHandball = new TCheckBox(Form1);
	chkHandball->Parent = Group;
	chkHandball->Left = 16;
	chkHandball->Top = 36;
}
//---------------------------------------------------------------------------

An important characteristic of a check box is its title, which is controlled by the Caption property that it inherits from the TControl class. This can easily be set at design or runtime. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TGroupBox* Group = new TGroupBox(Form1);
	Group->Parent = Form1;
	Group->Left = 16;
	Group->Top = 32;
	Group->Caption = "Preferred Sports";

	TCheckBox* chkFootball = new TCheckBox(Form1);
	chkFootball->Parent = Group;
	chkFootball->Left = 16;
	chkFootball->Top = 16;
	chkFootball->Caption = "Football";

	TCheckBox* chkHandball = new TCheckBox(Form1);
	chkHandball->Parent = Group;
	chkHandball->Left = 16;
	chkHandball->Top = 36;
	chkHandball->Caption = "Handball";
}
//---------------------------------------------------------------------------

Depending on the applicationís needs, you can display or hide it (using the Visible property), enable or disable it (using the Enabled property). You can adjust the controlís behavior depending on other controls on the same form, the same application, or external factors.

Most of the other characteristics a check box uses derive from its ancestors the TControl and the TWinControl classes.

Practical LearningPractical Learning: Creating a Check Box

  1. While the check box is still selected on the form, in the Object Inspector, click Caption
  2. Type Apply Overtime Rules and press Enter. Enlarge the check box so the whole caption appears

Checking the Box

The most obvious property of the check box is its state as being checked or not. By default, a check box is not checked (it is empty). To support this, the check box inherits the Checked property from the TButtonControl class:

__property bool Checked = {read=GetChecked,write=SetChecked};

At design time, you can make sure that a check box appears checked or not by changing the Boolean value of the Checked property in the Object Inspector. When you set this property, it would be updated automatically on the form. You or the user can also control this property at runtime. To change the Checked property programmatically, simply assign a True or False value to the Checked property. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	CheckBox1->Checked = True;
}
//---------------------------------------------------------------------------

When a check box is clicked, its Checked property has a value of True. Otherwise, the value is False. Since the Checked property is a Boolean value, you can toggle its state based on an intermediary action from the program, the user, or the computer:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	CheckBox1->Checked = !CheckBox1->Checked;
}
//---------------------------------------------------------------------------

Algebra & Trigonometry - Page 447: Solving a right triangle: We know 2 sides and an angle of a triangle (3 measures). Use 3 check boxes to let the user specify what 2 values are known (the user must select only check boxes, not all three. Add a group of two radio buttons. The user must select the radio button of the angle that is known. Find the other two sides and the other angle.

Practical LearningPractical Learning: Checking a Check Box

  • While the check box is still selected on the form, in the Object Inspector, click the check box of Checked to make it True

The Alignment

The position of the caption is controlled by the Alignment property. This property is of type TAlignment:

__property Classes::TAlignment Alignment = {read=FAlignment,write=SetAlignment};

By default, the control's caption is aligned to the right side of the check box. To change the caption alignment of a check box, use the Alignment property of the Object Inspector:

Check Boxes Check Boxes
Right Aligned Left Aligned

The TAlignment enumerator has two members: taRightJustify for the right alignment and the taLeftJustify. You can specify the alignment with code. Here is an example:

//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	TGroupBox* Group = new TGroupBox(Form1);
	Group->Parent = Form1;
	Group->Left = 16;
	Group->Top = 32;
	Group->Caption = "Preferred Sports";

	TCheckBox* chkFootball = new TCheckBox(Form1);
	chkFootball->Parent = Group;
	chkFootball->Left = 16;
	chkFootball->Top = 16;
	chkFootball->Alignment = taRightJustify;
	chkFootball->Caption = "Football";
	chkFootball->Checked = True;
}
//---------------------------------------------------------------------------

If you want to know the alignment applied on a check box, call the GetControlsAlignment() method of the TControl class. Its syntax is:

TAlignment __fastcall GetControlsAlignment(void);

Practical LearningPractical Learning: Aligning the Caption

  • While the check box is still selected on the form, in the Object Inspector, double-click Alignment to change its value to taLeftJustify
     
    Payroll Evaluation

Allowing the Gray Appearance

Fundamentally, a check box can have one of two states: checked or unchecked. When a check boxí Checked property is dependent of other controls or actions, sometimes, you cannot categorically set it to Checked or not Checked. Imagine that, in a certain company, for an employee to qualify for stock options, she must be have a full-time status and must have been in the company for at least two years. If an (important) employee fulfills one of these requirements but not the other requirements, you can gray out the Stock Options check box. Since the control would not be completely checked, you can show it as half checked:

Check Boxes

This property is controlled by the AllowGrayed property:

__property bool AllowGrayed = {read=FAllowGrayed,write=FAllowGrayed};

In the Object Inspector, change the (Boolean) AllowGrayed property of the desired check box to True or False (the default). Programmatically, to set this property, assign it a True value (because otherwise the false value is set by default).

At design time or when the user is interacting with your application, you can control the display of a check box using one of three states. Unlike being checked or unchecked, like the AllowGrayed property, you can use an intermediary state that would help you and/or the user know that the controlís condition cannot be definitely decided. This is set using the State property. This property, based on the TCheckBoxState enumerator:

__property Stdctrls::TCheckBoxState State = {read=FState,write=SetState};

The TCheckBoxState enumerator is defined as follows:

enum TCheckBoxState{
	cbUnchecked,
	cbChecked,
	cbGrayed
};

The State property allows you to set a check box as unchecked (the default) by assigning the cbUnchecked value To definitely check it, set this property to cbChecked. As a 3rd alternative, you can assign it a cbGrayed value.

Practical LearningPractical Learning: Allowing the Gray Appearance

  • While the check box is still selected on the form, in the Object Inspector, click the check box of AllowGrayed to make it True

Check Box Events

As far as Microsoft Windows is concerned, a check box is just a modified button. This allows it to use the common characteristics of command buttons and radio controls. Based on this, when the user clicks a check box, an OnClick() event fires. All the other events derive from its ancestors the TControl and the TWinControl classes.

Practical LearningPractical Learning: Implementing Check Boxes

  1. On the form, double-click the Calculate button
  2. Implement its OnClick event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmEvaluation::btnCalculateClick(TObject *Sender)
    {
    	double Monday1 = 0.00, Tuesday1 = 0.00, Wednesday1 = 0.00,
    		   Thursday1 = 0.00, Friday1 = 0.00, Saturday1 = 0.00,
    		   Sunday1 = 0.00, Monday2 = 0.00, Tuesday2 = 0.00,
    		   Wednesday2 = 0.00, Thursday2 = 0.00,
    		   Friday2 = 0.00, Saturday2 = 0.00, Sunday2 = 0.00;
    	double TotalWeekTime1, TotalWeekTime2;
    
    	double TotalTime = 0.00, TotalPay = 0.00;
    	double RegularTime1 = 0.00, RegularTime2 = 0.00,
    		   Overtime1 = 0.00, Overtime2 = 0.00;
    	double RegularPay1 = 0.00, RegularPay2 = 0.00,
    		   OvertimePay1 = 0.00, OvertimePay2 = 0.00;
    	double RegularTime, Overtime;
    	double RegularAmount, OvertimeAmount, NetPay;
    
    	double HourlySalary = 0.00;
    
    	// Retrieve the hourly salary
    	try
    	{
    		   HourlySalary = StrToFloat(edtHourlySalary->Text);
    	}
    	catch (EConvertError *)
    	{
    	ShowMessage(L"The value you typed for the salary is invalid \n"
    	L"Please try again");
    	}
    
    	// Retrieve the value of each day worked
    	try
    	{
    		 Monday1 = StrToFloat(edtWeek1Monday->Text);
    	}
    	catch (EConvertError *)
    	{
    		 ShowMessage(L"You typed an invalid value\n"
    					 L"Please try again");
    	}
    
    	try
    	{
    		Tuesday1 = StrToFloat(edtWeek1Tuesday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Wednesday1 = StrToFloat(edtWeek1Wednesday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Thursday1 = StrToFloat(edtWeek1Thursday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Friday1 = StrToFloat(edtWeek1Friday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Saturday1 = StrToFloat(edtWeek1Saturday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Sunday1 = StrToFloat(edtWeek1Sunday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Monday2 = StrToFloat(edtWeek2Monday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Tuesday2 = StrToFloat(edtWeek2Tuesday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Wednesday2 = StrToFloat(edtWeek2Wednesday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Thursday2 = StrToFloat(edtWeek2Thursday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Friday2 = StrToFloat(edtWeek2Friday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Saturday2 = StrToFloat(edtWeek2Saturday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	try
    	{
    		  Sunday2 = StrToFloat(edtWeek2Sunday->Text);
    	}
    	catch (EConvertError *)
    	{
    		  ShowMessage(L"You typed an invalid value\n"
    					  L"Please try again");
    	}
    
    	// Calculate the total time worked for each week
    	TotalWeekTime1 = Monday1 + Tuesday1 + Wednesday1 +
    			 Thursday1 + Friday1 + Saturday1 + Sunday1;
    	TotalWeekTime2 = Monday2 + Tuesday2 + Wednesday2 +
    			 Thursday2 + Friday2 + Saturday2 + Sunday2;
    
    	// If you are applying overtime rules --------------------------------
    	// The overtime is paid time and half
    	double OvertimeSalary = HourlySalary * 1.5;
    
    	// If the employee worked under 40 hours, there is no overtime
    	if (TotalWeekTime1 < 40)
    	{
    		RegularTime1 = TotalWeekTime1;
    		RegularPay1 = HourlySalary * RegularTime1;
    		Overtime1 = 0.00;
    		OvertimePay1 = 0.00;
    	} // If the employee worked over 40 hours, calculate the overtime
    	else if (TotalWeekTime1 >= 40)
    	{
    		RegularTime1 = 40;
    		RegularPay1 = HourlySalary * 40;
    		Overtime1 = TotalWeekTime1 - 40;
    		OvertimePay1 = Overtime1 * OvertimeSalary;
    	}
    
    	if (TotalWeekTime2 < 40)
    	{
    		RegularTime2 = TotalWeekTime2;
    		RegularPay2 = HourlySalary * RegularTime2;
    		Overtime2 = 0.00;
    		OvertimePay2 = 0.00;
    	}
    	else if (TotalWeekTime2 >= 40)
    	{
    		RegularTime2 = 40;
    		RegularPay2 = HourlySalary * 40;
    		Overtime2 = TotalWeekTime2 - 40;
    		OvertimePay2 = Overtime2 * OvertimeSalary;
    	}
    
    	RegularTime = RegularTime1 + RegularTime2;
    	Overtime = Overtime1 + Overtime2;
    	RegularAmount = RegularPay1 + RegularPay2;
    	OvertimeAmount = OvertimePay1 + OvertimePay2;
    	NetPay = RegularAmount + OvertimeAmount;
    
    	// If you are not applying overtime rules ------------------------------
    	TotalTime = TotalWeekTime1 + TotalWeekTime2;
    	TotalPay = HourlySalary * TotalTime;
    
    	// If the check box is (completely) unchecked, show only
    	// the calculations without considering overtime
    	if( chkApplyOvertimeRules->State == cbUnchecked )
    	{
    		edtRegularTime->Text = L"0.00";
    		edtOvertime->Text = L"0.00";
    		edtRegularPay->Text = L"0.00";
    		edtOvertimePay->Text = L"0.00";
    		edtNetPay->Text = L"0.00";
    
    		edtTotalTime->Text = FloatToStrF(TotalTime, ffFixed, 7, 2);
    		edtTotalPay->Text = FloatToStrF(TotalPay, ffFixed, 7, 2);
    	}
    	else if( chkApplyOvertimeRules->State == cbChecked )
    	{
    		// If the check box is (completely) checked, show only
    		// the calculations that take overtime in consideration
    		edtRegularTime->Text = FloatToStrF(RegularTime, ffFixed, 7, 2);
    		edtOvertime->Text = FloatToStrF(Overtime, ffFixed, 7, 2);
    		edtRegularPay->Text = FloatToStrF(RegularAmount, ffFixed, 7, 2);
    		edtOvertimePay->Text = FloatToStrF(OvertimeAmount, ffFixed, 7, 2);
    
    		edtNetPay->Text = FloatToStrF(NetPay, ffFixed, 7, 2);
    
    		edtTotalTime->Text = L"0.00";
    		edtTotalPay->Text  = L"0.00";
    	}
    	else if( chkApplyOvertimeRules->State == cbGrayed )
    	{
    		// If the check box is half-checked, show both calculations
    		edtRegularTime->Text = FloatToStrF(RegularTime, ffFixed, 7, 2);
    		edtOvertime->Text = FloatToStrF(Overtime, ffFixed, 7, 2);
    		edtRegularPay->Text = FloatToStrF(RegularAmount, ffFixed, 7, 2);
    		edtOvertimePay->Text = FloatToStrF(OvertimeAmount, ffFixed, 7, 2);
    		edtNetPay->Text = FloatToStrF(NetPay, ffFixed, 7, 2);
    
    		edtTotalTime->Text = FloatToStrF(TotalTime, ffFixed, 7, 2);
    		edtTotalPay->Text = FloatToStrF(TotalPay, ffFixed, 7, 2);
    	}
    }
    //---------------------------------------------------------------------------
  3. In the top box of the Object Inspector, select btnClose
  4. Click Events and double-click OnClick
  5. Implement the event as follows:
    //---------------------------------------------------------------------------
    void __fastcall TfrmEvaluation::btnCloseClick(TObject *Sender)
    {
    	Close();
    }
    //---------------------------------------------------------------------------
  6. Press F9 to execute
  7. Enter some values in the top edit boxes, namely the hourly salary and the day values
     
    Payroll Evaluation
  8. Click calculate
     
    Payroll Evaluation
     
    Payroll Evaluation
     
    Payroll Evaluation
  9. Close the form and return to your programming environment
 
 
 
 

Home Copyright © 2010-2011 FunctionX, Inc.