At the end of the last tutorial we were left with a working calculator which needed only a couple of refinements to make it fully functional. The first of these refinements (the CE key) is very simple to implement as all that is required is a line of code which will clear the last entry held in the ReadOut Editbox.
To enter the code into our program we first double click on the CE key and then enter the following code between the begin and end block markers:
Readout.Clear;
This code Clears the ReadOut EditBox so that
we can enter another number.
The last key we need to write code for is the % or percentage key. to do this we double click on the % key and add the following code between the begin and end statements:
Val(ReadOut.Text, op2, Code);
op2 := op1 / 100 * op2;
Str(op2:6:2, s);
ReadOut.Text := s;
The first line of code reads the string contained in the ReadOut EditBox and converts it into a Real value which is stored in op2.
The next line calculates the percentage and stores the result in op2
The third line converts the value in op2 to a string and stores it in s string
Finally s string is paseed to ReadOut.Text and displayed on the screen.
We have now completed the coding for each of the keys, but we still have the problem of how to clear the last answer from the ReadOut EditBox.
A solution to the problem lies within the procedure call made each time a button is pressed. In the case of the 9 button when we double clicked on it in design mode the procedure:
procedure TForm1.Num9Click(Sender: TObject);
is created automatically because this is the default event for a button, if you press the events tab in the object inspector you will see that there are other events we can use but the Click event is the one we use the most that is why it's set as the default event.
At the end of each of our procedures is a parameter:
(Sender: TObject)
Sender tells Delphi which component received the event and called the handler which in our case would be the num9 button.
To use the information contained in Sender we need to use the if then else statement e.g.
if Sender = num9 then
ReadOut.Text := ReadOut.Text + '9'
else
These three lines read Sender to find out if num9 called the procedure and if it did updates Readout.
We can now enter all the number buttons in to one procedure which for our purpose will be num9.
Enter the following lines inside the begin and end block markers
if Sender = num9 then ReadOut.Text := ReadOut.Text + '9'
else if Sender = num8 then ReadOut.Text := ReadOut.Text + '8'
else if Sender = num7 then ReadOut.Text := ReadOut.Text + '7'
else if Sender = num6 then ReadOut.Text := ReadOut.Text + '6'
else if Sender = num8 then ReadOut.Text := ReadOut.Text + '5'
else if Sender = num7 then ReadOut.Text := ReadOut.Text + '4'
else if Sender = num6 then ReadOut.Text := ReadOut.Text + '3'
else if Sender = num8 then ReadOut.Text := ReadOut.Text + '2'
else if Sender = num7 then ReadOut.Text := ReadOut.Text + '1'
else if Sender = num6 then ReadOut.Text
:= ReadOut.Text + '0'
We now need to tell Delphi which procedure each keys event should point to. We do this by clicking on each number key and then pressing the event tag on the Object inspector. If you look to the right of the OnClick event you will see the name of the procedure that each key calls this needs to be changed so that all the keys OnClick events point to the num9 procedure. To do this click on the down arrow at the right of the procedure name and a list of procedures will be displayed, from this list choose num9Click do this for all the number keys following the same procedure as stated above.
We can now delete all the num. procedures declaration in the Tform1 class and the actual procedures except of course the num9Click procedure. If we now run the program a message box appears asking if we want to get rid of the reference to the redundant procedures press OK and then run the program.
We now need to add another global variable and this time it will be a Boolean variable. Boolean type variables have two states True or False and we will use this variable to tell the program if we are continuing a calculation or starting a new one. Under the following code add the line shown in cyan italics.
{$R *.DFM}
var
op1, op2: Real;
Code, operator: Integer;
s, number: string;
first: Boolean;
we now add the following code to the num9Click procedure below the begin
if first = False then
begin
ReadOut.Text := '';
first := true
end;
We also need to add
first := False;
to the Operator5Click and CancelClick procedures.
You should now have a fully working calculator if you don't the
full source code is provided below with some more modifications
for you to try out.
The Calculator source code.
Note remember Delphi already provides some of the source code itself.
unit Ucalc;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Num1: TButton;
Num2: TButton;
Num3: TButton;
Num4: TButton;
Num5: TButton;
Num6: TButton;
Num7: TButton;
Num8: TButton;
Num9: TButton;
Num0: TButton;
Decimal: TButton;
Cancel: TButton;
Operator1: TButton;
Operator3: TButton;
Operator5: TButton;
CancelEntry: TButton;
Operator2: TButton;
Operator4: TButton;
Percent: TButton;
Label1: TLabel;
procedure NumberClick(Sender: TObject);
procedure DecimalClick(Sender: TObject);
procedure CancelClick(Sender: TObject);
procedure Operator1Click(Sender: TObject);
procedure Operator5Click(Sender: TObject);
procedure CancelEntryClick(Sender: TObject);
procedure PercentClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
var
op1, op2: Real;
Code, operator: Integer;
first, dec: Boolean;
s, number: string;
procedure TForm1.NumberClick(Sender: TObject);
begin
if first = False then
begin
Label1.Caption := '';
first := true
end;
if Sender = num9 then number := num9.Caption
else if Sender = num8 then number := num8.Caption
else if Sender = num7 then number := num7.Caption
else if Sender = num6 then number := num6.Caption
else if Sender = num5 then number := num5.Caption
else if Sender = num4 then number := num4.Caption
else if Sender = num3 then number := num3.Caption
else if Sender = num2 then number := num2.Caption
else if Sender = num1 then number := num1.Caption
else if Sender = num0 then number := num0.Caption;
Label1.Caption := Label1.Caption + number;
end;
procedure TForm1.DecimalClick(Sender: TObject);
begin
if first = False then
begin
Label1.Caption := '0.';
dec := True;
first := True
end
else if dec = False then
begin
Label1.Caption := Label1.Caption + '.';
dec := True
end;
end;
procedure TForm1.CancelClick(Sender: TObject);
begin
Label1.Caption := '0.';
op1 := 0; op2 := 0;
dec := False;
first := False;
end;
procedure TForm1.Operator1Click(Sender: TObject);
begin
if Sender = Operator1 then operator := 1
else if Sender = Operator2 then operator := 2
else if Sender = Operator3 then operator := 3
else operator := 4;
Val(Label1.Caption, op1, Code);
Label1.Caption := '';
dec := False;
first := False;
end;
procedure TForm1.Operator5Click(Sender: TObject);
begin
Val(Label1.Caption, op2, Code);
if operator = 1 then
op1 := op1 + op2
else if operator = 2 then
op1 := op1 - op2
else if operator = 3 then
op1 := op1 * op2
else if operator = 4 then
op1 := op1 / op2;
Str(op1:6:2, s);
Label1.Caption := s;
dec := False;
first := False;
end;
procedure TForm1.CancelEntryClick(Sender: TObject);
begin
Label1.Caption := '';
first := False;
dec := False
end;
procedure TForm1.PercentClick(Sender: TObject);
begin
Val(Label1.Caption, op2, Code);
op2 := op1 / 100 * op2;
Str(op2:6:2, s);
Label1.Caption := s;
end;
end.
The number of visitor to this page =