Sign in Join
Wiki copytemporary

Howdy World (Hello World on steroids): what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
1-This Wiki article is a tutorial for [[Lazarus]]. It explains the first steps to get a working piece of software and explains some best practices along the way. The end result is twofold (hopefully): the reader understands the basic concepts of how to build software with Lazarus and she has an actual piece of working software that can be embedded in other [[Program|programs]]: a calculator. A calculator is fairly easy to implement and everyone understands its concepts. So no need to describe a lengthy business case beforehand. The calculator is limited to [[Integer|integer]] calculations, but can easily be extended.
2-
3-This tutorial does not describe the [[Installing Lazarus|Lazarus installation process]]. It is assumed that Lazarus is installed and ready for use (preferably the latest, stable version which is currently Lazarus 2.0.12 with Free Pascal v3.2.0). This tutorial is more or less platform independent (but targeted at thick clients). All screenshots were made on a Windows XP PC; hence the blue/red/grayish color scheme.
4-
5-Recommended reading before starting here: a comprehensive introduction to the [[Lazarus Tutorial|Lazarus IDE]].
6-
7-
1+This Wiki article is a tutorial for [[Lazarus]]. It explains the first steps to get a working piece of software and explains some best practices along the way. The end result is twofold (hopefully): the reader understands the basic concepts of how to build software with Lazarus and she has an actual piece of working software that can be embedded in other [[Program|programs]]: a calculator. A calculator is fairly easy to implement and everyone understands its concepts. So no need to describe a lengthy business case beforehand. The calculator is limited to [[Integer|integer]] calculations, but can easily be extended.
82
9-## Contents
3+This tutorial does not describe the [[Installing Lazarus|Lazarus installation process]]. It is assumed that Lazarus is installed and ready for use (preferably the latest, stable version which is currently Lazarus 2.0.12 with Free Pascal v3.2.0). This tutorial is more or less platform independent (but targeted at thick clients). All screenshots were made on a Windows XP PC; hence the blue/red/grayish color scheme.
104
11- * 1 Let’s get started
12- * 2 The first component
13- * 3 Buttons
14- * 4 Responding to events
15- * 5 Tuning
16- * 5.1 Removing leading zeroes
17- * 5.2 Limit the number of digits
18- * 6 Operations
19- * 6.1 What was the operation?
20- * 6.2 What was the first number?
21- * 6.3 What was the second number?
22- * 7 What's on your mind
23- * 8 Doing the math
24- * 9 Intermezzo
25- * 10 Loose ends
26- * 10.1 The +/- button
27- * 10.2 The Clear button
28- * 10.3 Divide by zero
29- * 10.4 Overflows
30- * 11 Final tweaks
5+Recommended reading before starting here: a comprehensive introduction to the [[Lazarus Tutorial|Lazarus IDE]].
316
327## Let’s get started
338
34-It’s best to create a separate directory for every new project. So before getting our feet wet, let’s create a directory to save our Calculator project in (do this with your [[operating system|OS]] application of choice). This directory will be the root for all files created for the project.
9+It’s best to create a separate directory for every new project. So before getting our feet wet, let’s create a directory to save our Calculator project in (do this with your [[operating system|OS]] application of choice). This directory will be the root for all files created for the project.
3510
36- * Create a new directory for the demo project (let’s call it $HOME/CalculatorDemo).
11+- Create a new directory for the demo project (let’s call it \$HOME/CalculatorDemo).
3712
38-(_Text that describes actions that must be executed is bulleted like the previous line._)
13+(*Text that describes actions that must be executed is bulleted like the previous line.*)
3914
40-With this out of the way it’s time to start a new Lazarus project.
15+With this out of the way it’s time to start a new Lazarus project.
4116
42- * Start Lazarus.
43- * From the menu choose Project/New Project…
44- * In the dialog that is presented select Application and press OK (if the [[IDE]] complains about unsaved changes, press No).
17+- Start Lazarus.
18+- From the menu choose Project/New Project…
19+- In the dialog that is presented select Application and press OK (if the [[IDE]] complains about unsaved changes, press No).
4520
46-To make sure that all files of our new project end up in the right directory the project must be saved first.
21+To make sure that all files of our new project end up in the right directory the project must be saved first.
4722
48- * From the menu choose File/Save All.
49- * Select the directory that was created previously ($HOME/CalculatorDemo).
50- * Enter a new project name: CalculatorDemo
51- * Press Save (or whatever is the Save button in your own language)
52- * The IDE wants to save the main [[TForm|form]] as well: enter ’’ufrmMain’’ as the form's [[Unit|`unit`]] name.
53- * The IDE asks if the filename should be changed to a lowercase name. Confirm this by pressing the button ‘Rename to lowercase’.
23+- From the menu choose File/Save All.
24+- Select the directory that was created previously (\$HOME/CalculatorDemo).
25+- Enter a new project name: CalculatorDemo
26+- Press Save (or whatever is the Save button in your own language)
27+- The IDE wants to save the main [[TForm|form]] as well: enter ’’ufrmMain’’ as the form's [[Unit|unit]] name.
28+- The IDE asks if the filename should be changed to a lowercase name. Confirm this by pressing the button ‘Rename to lowercase’.
5429
55-In theory the program that is thus created is a piece of valid software that can be executed. Before compiling it for the first time, two changes are recommended: assigning new locations (directories) for the compiled units and target filename.
30+In theory the program that is thus created is a piece of valid software that can be executed. Before compiling it for the first time, two changes are recommended: assigning new locations (directories) for the compiled units and target filename.
5631
57- * From the menu choose Project/Project Options…
58- * Select Compiler Options/Paths (click on the node in the treeview)
59- * Put the text ‘‘bin\’‘ before the target filename (or ‘‘bin/’‘ for a *nix environment)
60- * Also note the ‘‘lib’‘ prefix for the ‘unit output directory’ (don’t change it).
61- * Press OK
32+- From the menu choose Project/Project Options…
33+- Select Compiler Options/Paths (click on the node in the treeview)
34+- Put the text ‘‘bin\\’‘ before the target filename (or ‘‘bin/’‘ for a *nix environment)
35+- Also note the ‘‘lib’‘ prefix for the ‘unit output directory’ (don’t change it).
36+- Press OK
6237
63-The image below is how this would look like on a Windows machine. [![tutcal project options.png](/wiki-images/b/bf/tutcal_project_options.png)](</File:tutcal_project_options.png>)
38+The image below is how this would look like on a Windows machine. ![](/wiki-images/e/eb/Tutcal_project_options.png)
6439
65-By doing this the project folder will not be cluttered with output that is generated by the [[Compiler|compiler]]. The files in the project folder are required to (re-) build the program. Everything in the ’’lib’’ and ’’bin’’ directories can be deleted when archiving the project.
40+By doing this the project folder will not be cluttered with output that is generated by the [[Compiler|compiler]]. The files in the project folder are required to (re-) build the program. Everything in the ’’lib’’ and ’’bin’’ directories can be deleted when archiving the project.
6641
67-Now as a first test the project can be compiled and run.
42+Now as a first test the project can be compiled and run.
6843
69- * Press `F9` (the shortcut for compile, build and run the program)
44+- Press `F9` (the shortcut for compile, build and run the program)
7045
71-If all went well a blank window is displayed. Now we know that a solid basis is created on which we can start building the program.
46+If all went well a blank window is displayed. Now we know that a solid basis is created on which we can start building the program.
7247
73- * End the running program by clicking on the Close icon (this depends on the OS).
48+- End the running program by clicking on the Close icon (this depends on the OS).
7449
7550## The first component
7651
77-Lazarus has a so called [[Component Palette|‘component palette’]]:
52+Lazarus has a so called [[Component Palette|‘component palette’]]:
7853
79-[![tutcal component palette.png](/wiki-images/6/65/tutcal_component_palette.png)](</File:tutcal_component_palette.png>)
54+![](/wiki-images/d/d4/Tutcal_component_palette.png)
8055
81-All components that are available to build a user interface are logically grouped on the component tabs. The actual number of tabs depends on the installed packages. But the basic palette looks something like the above image. The first tab is [[Standard tab|Standard]], followed by [[Additional tab|Additional]], [[Common Controls tab|Common Controls]] etc.
56+All components that are available to build a user interface are logically grouped on the component tabs. The actual number of tabs depends on the installed packages. But the basic palette looks something like the above image. The first tab is [[Standard tab|Standard]], followed by [[Additional tab|Additional]], [[Common Controls tab|Common Controls]] etc.
8257
83-To retrieve the type name of a component, hover with the mouse pointer above the component icon and a hint is displayed that gives the type name (to be more precise: the [[Class|class]] type of the component is displayed). For an explanation of all controls look at this [[Lazarus_Tutorial|Lazarus introduction].
58+To retrieve the type name of a component, hover with the mouse pointer above the component icon and a hint is displayed that gives the type name (to be more precise: the [[Class|class]] type of the component is displayed). For an explanation of all controls look at this \[\[Lazarus_Tutorial\|Lazarus introduction\].
8459
85-The first thing that needs to be done for the Calculator program is to create a display area where the entered numbers are, well, displayed. For this a [[TEdit]] control is used.
60+The first thing that needs to be done for the Calculator program is to create a display area where the entered numbers are, well, displayed. For this a [[TEdit]] control is used.
8661
87-![Light bulb](https://upload.wikimedia.org/wikipedia/commons/d/d8/Nuvola_apps_ktip.png) **Note:** the visual components are referred to as Controls. For now the difference between a 'component' and a 'control' is not that relevant.
62+> **Note:** the visual components are referred to as Controls. For now the difference between a 'component' and a 'control' is not that relevant.
8863
89-To place a control on the form, the form must have the focus. Pressing `F12` on the keyboard changes the focus from the form editor to the source code editor and vice versa.
64+To place a control on the form, the form must have the focus. Pressing `F12` on the keyboard changes the focus from the form editor to the source code editor and vice versa.
9065
91- * Press `F12` once or twice to get the form window on top (see image below).
66+- Press `F12` once or twice to get the form window on top (see image below).
9267
93-[![tutcal form on top.png](/wiki-images/7/7f/tutcal_form_on_top.png)](</File:tutcal_form_on_top.png>)
68+![](/wiki-images/e/ed/Tutcal_form_on_top.png)
9469
95- * Select the Standard tab on the component palette. This is the tab that is selected by default.
96- * Click on the TEdit component (hover above the component icons to get the class type names).
97- * Click somewhere in the middle of the form. This places a TEdit control on the form that has a name that is the same as the control’s type without the capital 'T' and with a number at the end (e.g. Edit1). When a second TEdit control were to be placed on the form it would be named Edit2. And so forth. This applies to all components.
70+- Select the Standard tab on the component palette. This is the tab that is selected by default.
71+- Click on the TEdit component (hover above the component icons to get the class type names).
72+- Click somewhere in the middle of the form. This places a TEdit control on the form that has a name that is the same as the control’s type without the capital 'T' and with a number at the end (e.g. Edit1). When a second TEdit control were to be placed on the form it would be named Edit2. And so forth. This applies to all components.
9873
99-Now that the control is placed on the form it can be customized to our needs. This customization takes place in the Object Inspector. That is the window at the left side of the screen with the list of properties for the TEdit control that are customizable. [![tutcal object inspector.png](/wiki-images/e/e4/tutcal_object_inspector.png)](</File:tutcal_object_inspector.png>)
74+Now that the control is placed on the form it can be customized to our needs. This customization takes place in the Object Inspector. That is the window at the left side of the screen with the list of properties for the TEdit control that are customizable. ![](/wiki-images/5/59/Tutcal_object_inspector.png)
10075
101-Properties determine the look and feel and behavior of a control. It’s easy to change a property: just click on one of them, enter a new value and press `↵ Enter`. The effects on the control are instantly visible. The properties in the Object Inspector are all the properties for _one_ control. In particular the control that has the focus/is selected. The control that is selected can be recognized by the small black squares that surround the control. So the way to change properties of a control is by first selecting it and then make the changes in the Object Inspector. If no control is selected, the form properties are displayed.
76+Properties determine the look and feel and behavior of a control. It’s easy to change a property: just click on one of them, enter a new value and press `Enter`. The effects on the control are instantly visible. The properties in the Object Inspector are all the properties for *one* control. In particular the control that has the focus/is selected. The control that is selected can be recognized by the small black squares that surround the control. So the way to change properties of a control is by first selecting it and then make the changes in the Object Inspector. If no control is selected, the form properties are displayed.
10277
103-Make the following changes to the properties of Edit1.
78+Make the following changes to the properties of Edit1.
10479
105- * change Name to _edDisplay_.
106- * change Align to _alTop_ (change Align, not Alignment!).
107- * change Alignment to _alRightJustify_ (change Alignment, not Align).
108- * change BorderSpacing.Around to _6_.
109- * change Text to _0_ (the number zero, not the letter oh).
80+- change Name to *edDisplay*.
81+- change Align to *alTop* (change Align, not Alignment!).
82+- change Alignment to *alRightJustify* (change Alignment, not Align).
83+- change BorderSpacing.Around to *6*.
84+- change Text to *0* (the number zero, not the letter oh).
11085
111-These properties are pretty self-explanatory. Especially when the above changes are made and the effect is monitored on the form.
86+These properties are pretty self-explanatory. Especially when the above changes are made and the effect is monitored on the form.
11287
113-As a finishing touch the Font that is used to display texts on all controls will be changed. The font can be changed in two places: the font property of edDisplay or the form’s font property. Changing the font for the form itself has the benefit that all newly placed controls on the form will 'inherit' the new font. So that is where we are going to make the change.
88+As a finishing touch the Font that is used to display texts on all controls will be changed. The font can be changed in two places: the font property of edDisplay or the form’s font property. Changing the font for the form itself has the benefit that all newly placed controls on the form will 'inherit' the new font. So that is where we are going to make the change.
11489
115- * Click somewhere in the middle of the form. This deselects the edDisplay control and selects the form itself. The form’s properties are now displayed in the Object Inspector.
116- * In the Object Inspector click on the Font property. The Font line is now highlighted and a button with three dots is displayed.
117- * Click on the button with the three dots. This opens the Font dialog.
118- * Select Verdana, Bold, Size 10.
119- * Press OK.
90+- Click somewhere in the middle of the form. This deselects the edDisplay control and selects the form itself. The form’s properties are now displayed in the Object Inspector.
91+- In the Object Inspector click on the Font property. The Font line is now highlighted and a button with three dots is displayed.
92+- Click on the button with the three dots. This opens the Font dialog.
93+- Select Verdana, Bold, Size 10.
94+- Press OK.
12095
121-The Form’s title is not very meaningful. The default text 'Form1' is displayed.
96+The Form’s title is not very meaningful. The default text 'Form1' is displayed.
12297
123- * In the Object Inspector click on the Caption property.
124- * Change the caption text to _Calculator Demo_.
98+- In the Object Inspector click on the Caption property.
99+- Change the caption text to *Calculator Demo*.
125100
126-The result of all these actions is a form that looks something like this: [![tutcal form with tedit.png](/wiki-images/3/32/tutcal_form_with_tedit.png)](</File:tutcal_form_with_tedit.png>)
101+The result of all these actions is a form that looks something like this: ![](/wiki-images/e/e0/Tutcal_form_with_tedit.png)
127102
128-Now is a good time to save the form.
103+Now is a good time to save the form.
129104
130- * Select from the menu File/Save or press the key combination `Ctrl``S`.
105+- Select from the menu File/Save or press the key combination `Ctrl``S`.
131106
132-Remember to save and save often!
107+Remember to save and save often!
133108
134109## Buttons
135110
136-What use is a calculator if numbers cannot be entered? So the next step is adding buttons for the digits 0..9. Before placing the buttons for the digits, a so called container is placed on the form. A container defines an area on a form where controls can be grouped together. The form is a container. A [[TPanel]] is another container that can be placed on a form. Containers can be placed inside other containers, but that’s for another tutorial.
111+What use is a calculator if numbers cannot be entered? So the next step is adding buttons for the digits 0..9. Before placing the buttons for the digits, a so called container is placed on the form. A container defines an area on a form where controls can be grouped together. The form is a container. A [[TPanel]] is another container that can be placed on a form. Containers can be placed inside other containers, but that’s for another tutorial.
137112
138- * On the component palette, select the TPanel control.
139- * Click on the form to place the panel.
113+- On the component palette, select the TPanel control.
114+- Click on the form to place the panel.
140115
141-A new panel is now visible on the form with a default width, height and caption. Note that the font for the panel caption is inherited from the form. This panel will be used to group all buttons, so a number of properties must be changed.
116+A new panel is now visible on the form with a default width, height and caption. Note that the font for the panel caption is inherited from the form. This panel will be used to group all buttons, so a number of properties must be changed.
142117
143- * Remove the text _Panel1_ from the caption property.
144- * Change Align to _alClient_.
145- * change Borderspacing.Around to _6_.
146- * increase the form’s Width to _300_ (first click on Form1 in the Object Inspector treeview).
147- * increase the form’s Height to _350_.
118+- Remove the text *Panel1* from the caption property.
119+- Change Align to *alClient*.
120+- change Borderspacing.Around to *6*.
121+- increase the form’s Width to *300* (first click on Form1 in the Object Inspector treeview).
122+- increase the form’s Height to *350*.
148123
149-(Increasing the size of the form gives us some space to move controls around.)
124+(Increasing the size of the form gives us some space to move controls around.)
150125
151-Now the digit buttons will be added.
126+Now the digit buttons will be added.
152127
153- * On the component palette, select the [[TButton]] control.
154- * Click on the form, somewhere in the middle, to place the button. The button is placed on the panel. this is visible in the Object Inspector treeview: Button1 is a so called _child_ of Panel1. This effectively means that when Panel1 is moved, all child controls move with it. And when Panel1 is deleted, all child controls are deleted as well.
155- * In the Object Inspector change Caption to _0_
156- * Change Width to _32_.
157- * Change Height to _30_.
158- * Change Name to _btnDigit0_.
128+- On the component palette, select the [[TButton]] control.
129+- Click on the form, somewhere in the middle, to place the button. The button is placed on the panel. this is visible in the Object Inspector treeview: Button1 is a so called *child* of Panel1. This effectively means that when Panel1 is moved, all child controls move with it. And when Panel1 is deleted, all child controls are deleted as well.
130+- In the Object Inspector change Caption to *0*
131+- Change Width to *32*.
132+- Change Height to *30*.
133+- Change Name to *btnDigit0*.
159134
160-This must be repeated for the digits 1..9. The quickest way to do this is by copy/pasting the 0-button.
135+This must be repeated for the digits 1..9. The quickest way to do this is by copy/pasting the 0-button.
161136
162- * Right click on the button created above and select Copy from the pop up menu.
163- * Right click somewhere else on Panel1 and select Paste; a second button is added to the panel. The only difference with the first button is the name _btnDigit1_.
164- * change the Caption property in the Object Inspector to _1_
165- * repeat the Paste action 8 more times for the remaining buttons.
166- * Move the buttons around on the form to get a lay out that looks like a calculator:
137+- Right click on the button created above and select Copy from the pop up menu.
138+- Right click somewhere else on Panel1 and select Paste; a second button is added to the panel. The only difference with the first button is the name *btnDigit1*.
139+- change the Caption property in the Object Inspector to *1*
140+- repeat the Paste action 8 more times for the remaining buttons.
141+- Move the buttons around on the form to get a lay out that looks like a calculator:
167142
168-[![tutcal calculator digits.png](/wiki-images/4/47/tutcal_calculator_digits.png)](</File:tutcal_calculator_digits.png>)
143+![](/wiki-images/c/cd/Tutcal_calculator_digits.png)
169144
170-Next are the four buttons for the mathematical functions (add, subtract etc.).
145+Next are the four buttons for the mathematical functions (add, subtract etc.).
171146
172- * Drop a new TButton on the panel.
173- * Change Width to _32_.
174- * Change Height to _30_.
175- * Change Caption to _+_
176- * Change Name to _btnFunction_.
177- * Copy/paste this button 3 more times, changing the caption to _-_ , _*_ and _/_.
178- * Align the buttons vertically, right next to the digit buttons
147+- Drop a new TButton on the panel.
148+- Change Width to *32*.
149+- Change Height to *30*.
150+- Change Caption to *+*
151+- Change Name to *btnFunction*.
152+- Copy/paste this button 3 more times, changing the caption to *-*, *** and */*.
153+- Align the buttons vertically, right next to the digit buttons
179154
180-And the 'special' buttons:
155+And the 'special' buttons:
181156
182- * Copy/Paste the _+_ button.
183- * Change Caption to _+/-_.
184- * Change Name to _btnPlusMinus_.
185- * Position the button just below button _3_.
186- * Copy/Paste the _+_ button.
187- * Change Caption to _C_.
188- * Change Name to btnClear.
189- * Position the button to the right of button _+_.
190- * Copy/Paste the _+_ button.
191- * Change Caption to _=_.
192- * Change Name to _btnCalculate_.
193- * Position the button to the right of button _/_
157+- Copy/Paste the *+* button.
158+- Change Caption to *+/-*.
159+- Change Name to *btnPlusMinus*.
160+- Position the button just below button *3*.
161+- Copy/Paste the *+* button.
162+- Change Caption to *C*.
163+- Change Name to btnClear.
164+- Position the button to the right of button *+*.
165+- Copy/Paste the *+* button.
166+- Change Caption to *=*.
167+- Change Name to *btnCalculate*.
168+- Position the button to the right of button */*
194169
195-Not what all buttons are placed, resize the form to fit the buttons tightly.
170+Not what all buttons are placed, resize the form to fit the buttons tightly.
196171
197-It should look something like this:
172+It should look something like this:
198173
199-[![tutcal calculator gui ready.png](/wiki-images/8/82/tutcal_calculator_gui_ready.png)](</File:tutcal_calculator_gui_ready.png>)
174+![](/wiki-images/c/c2/Tutcal_calculator_gui_ready.png)
200175
201-Remember to save and save often!
176+Remember to save and save often!
202177
203178## Responding to events
204179
205-A Graphical User Interface (GUI) application is often an event-based application. This means that the application does nothing until we tell it to do something. For example by entering data via the keyboard, pressing buttons etc. One of the things the calculator needs to do is respond to mouse clicks on the buttons 0..9. This is where the Lazarus IDE helps us. Adding a so called _event handler_ for a button is easy.
180+A Graphical User Interface (GUI) application is often an event-based application. This means that the application does nothing until we tell it to do something. For example by entering data via the keyboard, pressing buttons etc. One of the things the calculator needs to do is respond to mouse clicks on the buttons 0..9. This is where the Lazarus IDE helps us. Adding a so called *event handler* for a button is easy.
206181
207- * Make sure the form with all buttons is visible (if necessary press `F12` once or twice).
208- * Double click on the button with caption _0_ : the IDE automatically creates a [[Procedure|`procedure`]] that will handle mouse clicks: procedure TForm1.btnDigit0Click(Sender: TObject);
209- * type the following code between [[Begin|`begin`]] and [[End|`end`]]:
182+- Make sure the form with all buttons is visible (if necessary press `F12` once or twice).
183+- Double click on the button with caption *0*: the IDE automatically creates a [[Procedure|procedure]] that will handle mouse clicks: procedure TForm1.btnDigit0Click(Sender: TObject);
184+- type the following code between [[Begin|begin]] and [[End|end]]:
210185
211-`edDisplay.Text := edDisplay.Text + '0'` edDisplay is an edit box. The way to change the contents of the edit box is by modifying the Text property. The above [[statement]] adds the number '0' to the text in the edit box and this is visible on screen immediately.
186+`edDisplay.Text := edDisplay.Text + '0'` edDisplay is an edit box. The way to change the contents of the edit box is by modifying the Text property. The above [[statement]] adds the number '0' to the text in the edit box and this is visible on screen immediately.
212187
213- * Double click on the button with caption _1_.
214- * type the following code between begin and end:
188+- Double click on the button with caption *1*.
189+- type the following code between begin and end:
215190
216191`edDisplay.Text := edDisplay.Text + '1'`
217192
218-It's a good idea to compile the code from time to time to check for syntax errors ([[compile-time error|Compile time error]]).
193+It's a good idea to compile the code from time to time to check for syntax errors ([[compile-time error|Compile time error]]).
219194
220- * Select from the menu: Run/Run (or press `F9`); the project is compiled and the application starts.
221- * Click the digits 0 and 1 a couple of times and see what happens on screen. The other buttons do nothing obviously because the event handlers have not yet been added.
222- * Stop the Calculator Demo program.
195+- Select from the menu: Run/Run (or press `F9`); the project is compiled and the application starts.
196+- Click the digits 0 and 1 a couple of times and see what happens on screen. The other buttons do nothing obviously because the event handlers have not yet been added.
197+- Stop the Calculator Demo program.
223198
224-Of course it's now easy to add event handlers for the digits 2..9, but this will result in a lot of redundant code. Every event handler does exactly the same, only the digit is different. The way to remove this redundancy is by creating a procedure that does the processing, and add the variable data (the digits 0..9) as a parameter.
199+Of course it's now easy to add event handlers for the digits 2..9, but this will result in a lot of redundant code. Every event handler does exactly the same, only the digit is different. The way to remove this redundancy is by creating a procedure that does the processing, and add the variable data (the digits 0..9) as a parameter.
225200
226- * In the editor locate the lines where class TForm1 is declared. It will look something like this:
201+- In the editor locate the lines where class TForm1 is declared. It will look something like this:
227202
228-```
229-{ TForm1 }
230-
231- TForm1 = class(TForm)
232- btnDigit0: TButton;
233- btnDigit1: TButton;
234- btnDigit2: TButton;
235- btnDigit3: TButton;
236- btnDigit4: TButton;
237- btnDigit5: TButton;
238- btnDigit6: TButton;
239- btnDigit7: TButton;
240- btnDigit8: TButton;
241- btnDigit9: TButton;
242- btnFunction: TButton;
243- btnFunction1: TButton;
244- btnFunction2: TButton;
245- btnFunction3: TButton;
246- btnCalculate: TButton;
247- btnPlusMinus: TButton;
248- btnClear: TButton;
249- edDisplay: TEdit;
250- Panel1: TPanel;
251- procedure btnDigit0Click(Sender: TObject);
252- procedure btnDigit1Click(Sender: TObject);
253- private
254- { private declarations }
255- public
256- { public declarations }
257- end;
203+``` pascal
204+
205+ { TForm1 }
206+
207+ TForm1 = class(TForm)
208+ btnDigit0: TButton;
209+ btnDigit1: TButton;
210+ btnDigit2: TButton;
211+ btnDigit3: TButton;
212+ btnDigit4: TButton;
213+ btnDigit5: TButton;
214+ btnDigit6: TButton;
215+ btnDigit7: TButton;
216+ btnDigit8: TButton;
217+ btnDigit9: TButton;
218+ btnFunction: TButton;
219+ btnFunction1: TButton;
220+ btnFunction2: TButton;
221+ btnFunction3: TButton;
222+ btnCalculate: TButton;
223+ btnPlusMinus: TButton;
224+ btnClear: TButton;
225+ edDisplay: TEdit;
226+ Panel1: TPanel;
227+ procedure btnDigit0Click(Sender: TObject);
228+ procedure btnDigit1Click(Sender: TObject);
229+ private
230+ { private declarations }
231+ public
232+ { public declarations }
233+ end;
258234```
259235
260-Note that in the above class definition all controls and procedures are declared that we added to the form via 'pointing-and-clicking'. _**Do not make any manual changes in there!!**_ The IDE will get nervous when you do. The place to add custom [[Variable|variables]], procedures and [[Function|functions]] is in the [[Private|`private`]] or [[Public|`public`]] sections. As a general rule all custom variables are added to the the `private` section. Procedures and functions are added to the `private` section as well, except when other forms need to call these procedures or functions (which shouldn't happen too often).
236+Note that in the above class definition all controls and procedures are declared that we added to the form via 'pointing-and-clicking'. ***Do not make any manual changes in there!!*** The IDE will get nervous when you do. The place to add custom [[Variable|variables]], procedures and [[Function|functions]] is in the [[Private|private]] or [[Public|public]] sections. As a general rule all custom variables are added to the the `private` section. Procedures and functions are added to the `private` section as well, except when other forms need to call these procedures or functions (which shouldn't happen too often).
261237
262-Back to our digits problem: we need a procedure that adds digits to the display, where the digits themselves can vary.
238+Back to our digits problem: we need a procedure that adds digits to the display, where the digits themselves can vary.
263239
264- * Add procedure AddDigit to the `private` section of the form.
240+- Add procedure AddDigit to the `private` section of the form.
265241
266-```
267-private
268- { private declarations }
269- procedure AddDigit(const pDigit: byte);
270- public
271- { public declarations }
272- end;
242+``` pascal
243+ private
244+ { private declarations }
245+ procedure AddDigit(const pDigit: byte);
246+ public
247+ { public declarations }
248+ end;
273249```
274250
275-Next the actual code of the AddDigit procedure must be entered. Again the IDE comes to the rescue:
251+Next the actual code of the AddDigit procedure must be entered. Again the IDE comes to the rescue:
276252
277- * Place the blinking text cursor on the AddDigit line.
278- * Press key combination `Ctrl``⇧ Shift``C`.
253+- Place the blinking text cursor on the AddDigit line.
254+- Press key combination `Ctrl``Shift``C`.
279255
280-The IDE generates the definition of this new [[Method|method]] and places the text cursor inside the empty body. We can immediately start typing.
256+The IDE generates the definition of this new [[Method|method]] and places the text cursor inside the empty body. We can immediately start typing.
281257
282- * Add the following code to the AddDigit procedure body:
258+- Add the following code to the AddDigit procedure body:
283259
284-`edDisplay.Text := edDisplay.Text + IntToStr(pDigit)` Note that function _IntToStr()_ translates a numerical value, the digit, to a string value so it can be added to the display text.
260+`edDisplay.Text := edDisplay.Text + IntToStr(pDigit)` Note that function *IntToStr()* translates a numerical value, the digit, to a string value so it can be added to the display text.
285261
286-Now to use this procedure for all digits 0..9:
262+Now to use this procedure for all digits 0..9:
287263
288- * Open the form (if necessary press `F12` once or twice).
289- * Double click on digit button 0: this will open the editor in the event handler for button 0.
290- * Replace the code in the event handler with: AddDigit(0). The procedure will look like this:
264+- Open the form (if necessary press `F12` once or twice).
265+- Double click on digit button 0: this will open the editor in the event handler for button 0.
266+- Replace the code in the event handler with: AddDigit(0). The procedure will look like this:
291267
292-```
268+``` pascal
293269procedure TForm1.btnDigit0Click(Sender: TObject);
294- begin
295- AddDigit(0)
296- end;
270+begin
271+ AddDigit(0)
272+end;
297273```
298274
299- * Do the same for digit button 1:
275+- Do the same for digit button 1:
300276
301-```
277+``` pascal
302278procedure TForm1.btnDigit1Click(Sender: TObject);
303- begin
304- AddDigit(1)
305- end;
279+begin
280+ AddDigit(1)
281+end;
306282```
307283
308-Before completing this sequence for all other digit buttons, make sure that this actually does what we want.
284+Before completing this sequence for all other digit buttons, make sure that this actually does what we want.
309285
310- * Run the program (press `F9`).
311- * Click buttons 0 and 1 a couple of times and see that it actually works.
312- * End the program.
286+- Run the program (press `F9`).
287+- Click buttons 0 and 1 a couple of times and see that it actually works.
288+- End the program.
313289
314-_A good programmer is a lazy programmer_
290+*A good programmer is a lazy programmer*
315291
316-Now we can add event handlers to digit buttons 2..9. But then again we have the same problem of creating a lot of redundant code: AddDigit(2), AddDigit(3) etc. What if there were a way to tell the buttons apart? Luckily there is.
292+Now we can add event handlers to digit buttons 2..9. But then again we have the same problem of creating a lot of redundant code: AddDigit(2), AddDigit(3) etc. What if there were a way to tell the buttons apart? Luckily there is.
317293
318-All components have an integer property called _Tag_ (remember: a control is just a special kind of component that inherits this Tag property). It is a property that has no actual function. It is there for us to use as we see fit. Now what if each button would have its digit value stored in the Tag property…
294+All components have an integer property called *Tag* (remember: a control is just a special kind of component that inherits this Tag property). It is a property that has no actual function. It is there for us to use as we see fit. Now what if each button would have its digit value stored in the Tag property…
319295
320- * Open the form (if necessary press `F12` once or twice).
321- * Select digit button 1 (click on it once).
322- * In the Object Inspector locate the Tag property and change it's value to _1_.
323- * Select digit button 2 (click on it once).
324- * In the Object Inspector locate the Tag property and change it's value to _2_.
325- * Repeat this for digit buttons 3..9.
296+- Open the form (if necessary press `F12` once or twice).
297+- Select digit button 1 (click on it once).
298+- In the Object Inspector locate the Tag property and change it's value to *1*.
299+- Select digit button 2 (click on it once).
300+- In the Object Inspector locate the Tag property and change it's value to *2*.
301+- Repeat this for digit buttons 3..9.
326302
327-Now all digit buttons have a unique Tag value. We didn't change digit button 0 because the default Tag value already is 0.
303+Now all digit buttons have a unique Tag value. We didn't change digit button 0 because the default Tag value already is 0.
328304
329-Now to make use if this Tag value:
305+Now to make use if this Tag value:
330306
331- * Open the form.
332- * Double click on digit button 0 (this will open the editor in the event handler of digit button 0).
333- * Note that procedure _btnDigit0Click_ has a parameter _Sender_ of type _TObject_.
307+- Open the form.
308+- Double click on digit button 0 (this will open the editor in the event handler of digit button 0).
309+- Note that procedure *btnDigit0Click* has a parameter *Sender* of type *TObject*.
334310
335-`procedure TForm1.btnDigit0Click(Sender: TObject);` The _Sender_ parameter is actually a reference to the button that was pressed. Via typecasting we can use the parameter as if it was a TButton.
311+`procedure TForm1.btnDigit0Click(Sender: TObject);` The *Sender* parameter is actually a reference to the button that was pressed. Via typecasting we can use the parameter as if it was a TButton.
336312
337- * Change the code like this:
313+- Change the code like this:
338314
339-```
315+``` pascal
340316procedure TForm1.btnDigit0Click(Sender: TObject);
341- begin
342- AddDigit(TButton(Sender).Tag)
343- end;
317+begin
318+ AddDigit(TButton(Sender).Tag)
319+end;
344320```
345321
346-It doesn't look like we have accomplished much, replacing one line of code with another. However if we were to add the code for the other digits (1..9) it would look _exactly_ the same. So all other digits can reuse this particular method!
322+It doesn't look like we have accomplished much, replacing one line of code with another. However if we were to add the code for the other digits (1..9) it would look *exactly* the same. So all other digits can reuse this particular method!
347323
348-Let's have a closer look at the [IDE Window: Object Inspector|Object Inspector]].
324+Let's have a closer look at the \[IDE Window: Object Inspector\|Object Inspector\]\].
349325
350- * Open the form.
351- * Select digit button 0 (btnDigit0).
352- * In the Object Inspector select tab Events (see below).
326+- Open the form.
327+- Select digit button 0 (btnDigit0).
328+- In the Object Inspector select tab Events (see below).
353329
354-[![tutcal oi events.png](/wiki-images/4/49/tutcal_oi_events.png)](</File:tutcal_oi_events.png>)
330+![](/wiki-images/1/12/Tutcal_oi_events.png)
355331
356-In the object inspector we can not only change the properties of a control but also the event handlers. In the Object Inspector we can see that as soon as digit button 0 is clicked, method _btnDigit0Click_ is called (this is the _OnClick_ event handler).
332+In the object inspector we can not only change the properties of a control but also the event handlers. In the Object Inspector we can see that as soon as digit button 0 is clicked, method *btnDigit0Click* is called (this is the *OnClick* event handler).
357333
358- * On the form: select digit button 2. In the Object Inspector we can now see that there is no OnClick event handler for button 2.
359- * Open the drop down list for the OnClick event and select _btnDigit0Click_.
360- * Do this for all other digit buttons 3..9.
334+- On the form: select digit button 2. In the Object Inspector we can now see that there is no OnClick event handler for button 2.
335+- Open the drop down list for the OnClick event and select *btnDigit0Click*.
336+- Do this for all other digit buttons 3..9.
361337
362-Now all buttons share one common procedure that does exactly what we want except for digit button 1. Remember that for digit button 1 we created an event handler _btnDigit1Click_ that we don't really need anymore.
338+Now all buttons share one common procedure that does exactly what we want except for digit button 1. Remember that for digit button 1 we created an event handler *btnDigit1Click* that we don't really need anymore.
363339
364- * On the form: select digit button 1. In the Object Inspector we can now see that the event handler indeed is _btnDigit1Click_.
365- * Open the drop down list for the OnClick event and select btnDigit0Click.
340+- On the form: select digit button 1. In the Object Inspector we can now see that the event handler indeed is *btnDigit1Click*.
341+- Open the drop down list for the OnClick event and select btnDigit0Click.
366342
367-Now all buttons share the same event handler to add digits to the display box.
343+Now all buttons share the same event handler to add digits to the display box.
368344
369- * Run the program (press `F9`).
370- * Click all buttons 0..9 a couple of times and see that it actually works.
371- * End the program.
345+- Run the program (press `F9`).
346+- Click all buttons 0..9 a couple of times and see that it actually works.
347+- End the program.
372348
373-For the digit buttons one final thing needs to be done: event handler _btnDigit1Click_ still exists but is not used anymore and should be deleted. The safest way to do this (for now) is to let the IDE handle it. For this to work the option _Auto remove empty methods_ must be enabled.
349+For the digit buttons one final thing needs to be done: event handler *btnDigit1Click* still exists but is not used anymore and should be deleted. The safest way to do this (for now) is to let the IDE handle it. For this to work the option *Auto remove empty methods* must be enabled.
374350
375- * In the menu select Environment/Options.
376- * Click on Editor/Completion and Hints.
377- * Enable the option 'Auto remove empty methods' (see image below).
378- * Press OK.
351+- In the menu select Environment/Options.
352+- Click on Editor/Completion and Hints.
353+- Enable the option 'Auto remove empty methods' (see image below).
354+- Press OK.
379355
380-[![tutcal auto remove.png](/wiki-images/1/11/tutcal_auto_remove.png)](</File:tutcal_auto_remove.png>)
356+![](/wiki-images/4/4c/Tutcal_auto_remove.png)
381357
382-From now on all empty methods are automatically deleted as soon as the source file is saved.
358+From now on all empty methods are automatically deleted as soon as the source file is saved.
383359
384- * Locate method `procedure TForm1.btnDigit1Click(Sender: TObject)`
385- * Delete the line 'AddDigit(1)'
386- * Save the file (press `Ctrl``S` or select from the menu File/Save). The now empty procedure is automatically deleted.
360+- Locate method `procedure TForm1.btnDigit1Click(Sender: TObject)`
361+- Delete the line 'AddDigit(1)'
362+- Save the file (press `Ctrl``S` or select from the menu File/Save). The now empty procedure is automatically deleted.
387363
388364## Tuning
389365
390-So far so good: the calculator program compiles, runs and responds to clicks on digit buttons 0..9. But it doesn't behave exactly as we want: there's always this annoying zero at the beginning of the number and the number of allowed digits is too large.
366+So far so good: the calculator program compiles, runs and responds to clicks on digit buttons 0..9. But it doesn't behave exactly as we want: there's always this annoying zero at the beginning of the number and the number of allowed digits is too large.
391367
392368### Removing leading zeroes
393369
394-Normally an integer number that's bigger (or smaller) than zero does not start with a leading zero. So our calculator should compensate for this. Luckily this is easy to implement. Remember that we have one and only one method that handles the addition of digits: AddDigit. This is the place to add logic to suppress the leading zero.
370+Normally an integer number that's bigger (or smaller) than zero does not start with a leading zero. So our calculator should compensate for this. Luckily this is easy to implement. Remember that we have one and only one method that handles the addition of digits: AddDigit. This is the place to add logic to suppress the leading zero.
395371
396- * Locate method _procedure TForm1.AddDigit(const pDigit: byte)_
397- * Change the code to:
372+- Locate method *procedure TForm1.AddDigit(const pDigit: byte)*
373+- Change the code to:
398374
399-```
375+``` pascal
400376procedure TForm1.AddDigit(const pDigit: byte);
401- begin
402- // Suppress leading zeroes when adding digits
403- if edDisplay.Text = '0' then
404- edDisplay.Text := IntToStr(pDigit)
405- else
406- edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
407- end;
377+begin
378+ // Suppress leading zeroes when adding digits
379+ if edDisplay.Text = '0' then
380+ edDisplay.Text := IntToStr(pDigit)
381+ else
382+ edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
383+end;
408384```
409385
410386### Limit the number of digits
411387
412-This demo calculator cannot handle numbers that are too large. So we need to limit the number of digits that can be entered. Again the logical place to do this is the AddDigit method:
388+This demo calculator cannot handle numbers that are too large. So we need to limit the number of digits that can be entered. Again the logical place to do this is the AddDigit method:
413389
414- * Locate method _procedure TForm1.AddDigit(const pDigit: byte)_
415- * Change the code to:
390+- Locate method *procedure TForm1.AddDigit(const pDigit: byte)*
391+- Change the code to:
416392
417-```
393+``` pascal
418394procedure TForm1.AddDigit(const pDigit: byte);
419- begin
420- // Limit the number of digits
421- if length(edDisplay.Text) < 8 then
422- begin
423- // Suppress leading zeroes when adding digits
424- if edDisplay.Text = '0' then
425- edDisplay.Text := IntToStr(pDigit)
426- else
427- edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
428- end;
429- end;
395+begin
396+ // Limit the number of digits
397+ if length(edDisplay.Text) < 8 then
398+ begin
399+ // Suppress leading zeroes when adding digits
400+ if edDisplay.Text = '0' then
401+ edDisplay.Text := IntToStr(pDigit)
402+ else
403+ edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
404+ end;
405+end;
430406```
431407
432408## Operations
433409
434-Now it's time to look at the actual operations we want to implement: adding, subtracting, multiplying and dividing. The way the user is going to use the calculator goes something like this:
410+Now it's time to look at the actual operations we want to implement: adding, subtracting, multiplying and dividing. The way the user is going to use the calculator goes something like this:
435411
436- 1. The user enters a number
437- 2. The user presses a function button (e.g. '+')
438- 3. The user enters a second number
439- 4. The user presses '='
440- 5. The program responds with the addition of the first and second number
412+1. The user enters a number
413+2. The user presses a function button (e.g. '+')
414+3. The user enters a second number
415+4. The user presses '='
416+5. The program responds with the addition of the first and second number
441417
442-As soon as the user presses the '=' button the program has to know three things:
418+As soon as the user presses the '=' button the program has to know three things:
443419
444- 1. What was the operation?
445- 2. What was the first number?
446- 3. What was the second number?
420+1. What was the operation?
421+2. What was the first number?
422+3. What was the second number?
447423
448424### What was the operation?
449425
450-Somehow we need to register that a certain operation type was selected. And for that we need to know what operation types are available. One way to implement this is to create an enumeration type (or user defined scalar type) that contains all valid operations.
426+Somehow we need to register that a certain operation type was selected. And for that we need to know what operation types are available. One way to implement this is to create an enumeration type (or user defined scalar type) that contains all valid operations.
451427
452- * In the Source Editor, find the location where the form is declared.
453- * Just above the form add the type declaration _TOperationType_ for all supported operations:
428+- In the Source Editor, find the location where the form is declared.
429+- Just above the form add the type declaration *TOperationType* for all supported operations:
454430
455-```
456-{ All supported operations for our calculator }
457- TOperationType = (otNone, otPlus, otMinus, otMultiply, otDivide);
458-
459- { TForm1 }
460-
461- TForm1 = class(TForm)
462-```
431+``` pascal
432+ { All supported operations for our calculator }
433+ TOperationType = (otNone, otPlus, otMinus, otMultiply, otDivide);
463434
464- * To temporarily store the operation, a variable is added to the `private` section of the form's class declaration.
435+ { TForm1 }
465436
437+ TForm1 = class(TForm)
466438```
467-private
468- { private declarations }
469- SelectedOperation: TOperationType;
470- procedure AddDigit(const pDigit: byte);
439+
440+- To temporarily store the operation, a variable is added to the `private` section of the form's class declaration.
441+
442+``` pascal
443+ private
444+ { private declarations }
445+ SelectedOperation: TOperationType;
446+ procedure AddDigit(const pDigit: byte);
471447```
472448
473449### What was the first number?
474450
475-To temporarily store the first number that was entered we need a variable.
451+To temporarily store the first number that was entered we need a variable.
476452
477- * Add a variable to the form's `private` section.
453+- Add a variable to the form's `private` section.
478454
479-```
480-private
481- { private declarations }
482- SelectedOperation: TOperationType;
483- FirstNumber: longint;
484- procedure AddDigit(const pDigit: byte);
455+``` pascal
456+ private
457+ { private declarations }
458+ SelectedOperation: TOperationType;
459+ FirstNumber: longint;
460+ procedure AddDigit(const pDigit: byte);
485461```
486462
487463### What was the second number?
488464
489- * Add variable SecondNumber to the form's `private` section (the same as FirstNumber) and make it a [[Longint|longint]] as well.
465+- Add variable SecondNumber to the form's `private` section (the same as FirstNumber) and make it a [[Longint|longint]] as well.
490466
491467## What's on your mind
492468
493-Now it's time to implement the actions for the function buttons: add, subtract, multiply and divide. Let's start with the '+' button. As mentioned in one of the previous sections: when the '+' button is pressed, we need to store the first number and the operation type. So that's what we are going to do.
469+Now it's time to implement the actions for the function buttons: add, subtract, multiply and divide. Let's start with the '+' button. As mentioned in one of the previous sections: when the '+' button is pressed, we need to store the first number and the operation type. So that's what we are going to do.
494470
495- * Open the form.
496- * Double click on button '+'. The IDE creates an event handler and the text cursor is placed inside the empty begin/end block.
471+- Open the form.
472+- Double click on button '+'. The IDE creates an event handler and the text cursor is placed inside the empty begin/end block.
497473
498-Hold on! Before adding all the code here and doing the same for the three other operation buttons, remember what was said when the digit buttons 0..9 were added: do not add redundant code! It's reasonable to assume that the code for the other three operation buttons will be the same as for the '+' button, except for the operation itself. So let's save ourselves some work.
474+Hold on! Before adding all the code here and doing the same for the three other operation buttons, remember what was said when the digit buttons 0..9 were added: do not add redundant code! It's reasonable to assume that the code for the other three operation buttons will be the same as for the '+' button, except for the operation itself. So let's save ourselves some work.
499475
500- * Locate the form's `private` section and add a new procedure: StoreOperation.
476+- Locate the form's `private` section and add a new procedure: StoreOperation.
501477
502-```
503-private
504- { private declarations }
505- SelectedOperation: TOperationType;
506- FirstNumber: longint;
507- SecondNumber: longint;
508- procedure AddDigit(const pDigit: byte);
509- procedure StoreOperation(const pOperation: TOperationType);
478+``` pascal
479+ private
480+ { private declarations }
481+ SelectedOperation: TOperationType;
482+ FirstNumber: longint;
483+ SecondNumber: longint;
484+ procedure AddDigit(const pDigit: byte);
485+ procedure StoreOperation(const pOperation: TOperationType);
510486```
511487
512- * Place the blinking text cursor on the newly inserted line.
513- * Press `Ctrl``⇧ Shift``C` (you know the drill by now…).
488+- Place the blinking text cursor on the newly inserted line.
489+- Press `Ctrl``Shift``C` (you know the drill by now…).
514490
515-The StoreOperation procedure must do two things: store the operation and store the number that was entered in the display, so it can be used afterwards.
491+The StoreOperation procedure must do two things: store the operation and store the number that was entered in the display, so it can be used afterwards.
516492
517- * Add the following code to the newly created procedure:
493+- Add the following code to the newly created procedure:
518494
519-```
495+``` pascal
520496procedure TForm1.StoreOperation(const pOperation: TOperationType);
521- begin
522- // Store the operation so it can be used later
523- SelectedOperation := pOperation;
524-
525- // Store the number that was entered by the user
526- FirstNumber := StrToInt(edDisplay.Text);
527- end;
497+begin
498+ // Store the operation so it can be used later
499+ SelectedOperation := pOperation;
500+
501+ // Store the number that was entered by the user
502+ FirstNumber := StrToInt(edDisplay.Text);
503+end;
528504```
529505
530-Ok, now back to the '+' button:
506+Ok, now back to the '+' button:
531507
532- * Open the form.
533- * Double click on button '+'.
534- * Add the following code: StoreOperation(otPlus);
535- * Open the form.
536- * Double click on button '-'.
537- * Add the following code: StoreOperation(otMinus);
538- * Open the form.
539- * Double click on button '*'.
540- * Add the following code: StoreOperation(otMultiply);
541- * Open the form.
542- * Double click on button '/'.
543- * Add the following code: StoreOperation(otDivide);
508+- Open the form.
509+- Double click on button '+'.
510+- Add the following code: StoreOperation(otPlus);
511+- Open the form.
512+- Double click on button '-'.
513+- Add the following code: StoreOperation(otMinus);
514+- Open the form.
515+- Double click on button '*'.
516+- Add the following code: StoreOperation(otMultiply);
517+- Open the form.
518+- Double click on button '/'.
519+- Add the following code: StoreOperation(otDivide);
544520
545-Now test the program and see what happens:
521+Now test the program and see what happens:
546522
547- * Run the program (press `F9`)
548- * Enter a number (e.g. 21267)
549- * Press the '+' button
550- * Enter the second number (e.g. 31170)
523+- Run the program (press `F9`)
524+- Enter a number (e.g. 21267)
525+- Press the '+' button
526+- Enter the second number (e.g. 31170)
551527
552-What happens is that after pressing the '+' button, or any other operation button for that matter, the display is not cleared. We must find a way to make sure that the display is cleared, as soon as an operation button is pressed. Because we have used procedures to group similar actions, this again is an easy change.
528+What happens is that after pressing the '+' button, or any other operation button for that matter, the display is not cleared. We must find a way to make sure that the display is cleared, as soon as an operation button is pressed. Because we have used procedures to group similar actions, this again is an easy change.
553529
554- * Locate the form's `private` section and add a new variable: doClearDisplay. This variable will be the trigger for erasing the display.
530+- Locate the form's `private` section and add a new variable: doClearDisplay. This variable will be the trigger for erasing the display.
555531
556-```
557-private
558- { private declarations }
559- SelectedOperation: TOperationType;
560- FirstNumber: longint;
561- SecondNumber: longint;
562- doClearDisplay: boolean;
563- procedure AddDigit(const pDigit: byte);
564- procedure StoreOperation(const pOperation: TOperationType);
532+``` pascal
533+ private
534+ { private declarations }
535+ SelectedOperation: TOperationType;
536+ FirstNumber: longint;
537+ SecondNumber: longint;
538+ doClearDisplay: boolean;
539+ procedure AddDigit(const pDigit: byte);
540+ procedure StoreOperation(const pOperation: TOperationType);
565541```
566542
567- * Position the blinking text cursor on the line StoreOperation.
568- * Press `Ctrl`+`⇧ Shift`+`↓`: this moves the cursor to the body of the StoreOperation procedure.
569- * In the StoreOperation procedure we must update the doClearDisplay variable, so we know that the display must be cleared as soon as a new number is entered. Change the code to this:
543+- Position the blinking text cursor on the line StoreOperation.
544+- Press `Ctrl`+`Shift`+`Down`: this moves the cursor to the body of the StoreOperation procedure.
545+- In the StoreOperation procedure we must update the doClearDisplay variable, so we know that the display must be cleared as soon as a new number is entered. Change the code to this:
570546
571-```
547+``` pascal
572548procedure TForm1.StoreOperation(const pOperation: TOperationType);
573- begin
574- // Store the operation so it can be used later
575- SelectedOperation := pOperation;
576-
577- // Store the number that was entered by the user
578- FirstNumber := StrToInt(edDisplay.Text);
579-
580- // The display must start with a new number
581- doClearDisplay := true;
582- end;
583-```
549+begin
550+ // Store the operation so it can be used later
551+ SelectedOperation := pOperation;
584552
585- * And where better to clear the display than in the AddDigit procedure? Change the code to:
553+ // Store the number that was entered by the user
554+ FirstNumber := StrToInt(edDisplay.Text);
586555
556+ // The display must start with a new number
557+ doClearDisplay := true;
558+end;
587559```
560+
561+- And where better to clear the display than in the AddDigit procedure? Change the code to:
562+
563+``` pascal
588564procedure TForm1.AddDigit(const pDigit: byte);
589- begin
590- // Must the display be cleared first?
591- if doClearDisplay then
592- begin
593- edDisplay.Text := '0'; // Reset the display to zero
594- doClearDisplay := false; // Once is enough...
595- end;
596-
597- // Limit the number of digits
598- if length(edDisplay.Text) < 8 then
599- begin
600- // Suppress leading zeroes when adding digits
601- if edDisplay.Text = '0' then
602- edDisplay.Text := IntToStr(pDigit)
603- else
604- edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
605- end;
606- end;
565+begin
566+ // Must the display be cleared first?
567+ if doClearDisplay then
568+ begin
569+ edDisplay.Text := '0'; // Reset the display to zero
570+ doClearDisplay := false; // Once is enough...
571+ end;
572+
573+ // Limit the number of digits
574+ if length(edDisplay.Text) < 8 then
575+ begin
576+ // Suppress leading zeroes when adding digits
577+ if edDisplay.Text = '0' then
578+ edDisplay.Text := IntToStr(pDigit)
579+ else
580+ edDisplay.Text := edDisplay.Text + IntToStr(pDigit)
581+ end;
582+end;
607583```
608584
609-Now let's see what happens:
585+Now let's see what happens:
610586
611- * Run the program (press `F9`).
612- * Enter a number.
613- * Press an operation button.
614- * Enter another number.
615- * End the program.
587+- Run the program (press `F9`).
588+- Enter a number.
589+- Press an operation button.
590+- Enter another number.
591+- End the program.
616592
617-We're almost there: we can enter numbers and select an operation. Now it's time to do the actual calculations.
593+We're almost there: we can enter numbers and select an operation. Now it's time to do the actual calculations.
618594
619595## Doing the math
620596
621-Now that we have stored a number and an operation, it's time to do the actual calculations. Let's start easy with additions.
597+Now that we have stored a number and an operation, it's time to do the actual calculations. Let's start easy with additions.
622598
623- * Open the form.
624- * Double click on button '=' (the event handler is created).
625- * Change the procedure:
599+- Open the form.
600+- Double click on button '=' (the event handler is created).
601+- Change the procedure:
626602
627-```
603+``` pascal
628604procedure TForm1.btnCalculateClick(Sender: TObject);
629- var result: longint;
630- begin
631- case SelectedOperation of
632- otPlus: begin
633- // Retrieve the second number
634- SecondNumber := StrToInt(edDisplay.Text);
635- // Do the math
636- result := FirstNumber + SecondNumber;
637- // Display the resulting value
638- edDisplay.Text := IntToStr(result);
639- end;
640- end;
641- end;
605+var result: longint;
606+begin
607+ case SelectedOperation of
608+ otPlus: begin
609+ // Retrieve the second number
610+ SecondNumber := StrToInt(edDisplay.Text);
611+ // Do the math
612+ result := FirstNumber + SecondNumber;
613+ // Display the resulting value
614+ edDisplay.Text := IntToStr(result);
615+ end;
616+ end;
617+end;
642618```
643619
644-The above code is pretty straightforward: if the user presses the '+' button, the first and second number are added up and the result is stored in the edit control on screen. It's good to note that the code uses the [[Case|`case`]] [[Of|`of`]] switch control structure.
620+The above code is pretty straightforward: if the user presses the '+' button, the first and second number are added up and the result is stored in the edit control on screen. It's good to note that the code uses the [[Case|case]] [[Of|of]] switch control structure.
645621
646-
647-We now have a working calculator (that can only add two numbers):
622+We now have a working calculator (that can only add two numbers):
648623
649- * Run the program (press `F9`).
650- * Enter a number.
651- * Press '+'
652- * Enter another number.
653- * Press '=' : the sum of the two numbers is displayed.
654- * End the program.
624+- Run the program (press `F9`).
625+- Enter a number.
626+- Press '+'
627+- Enter another number.
628+- Press '=' : the sum of the two numbers is displayed.
629+- End the program.
655630
656-We now could add the 3 missing operations ('-', '*' and '/'). But hold on, there is room for improvement. Let's have a look at the following statement: `SecondNumber := StrToInt(edDisplay.Text);` We have seen such a statement before: the StoreOperation procedure contains something similar: `FirstNumber := StrToInt(edDisplay.Text);` Calculating the number the user entered now happens in two different locations. We do not want to repeat ourselves so it's a good idea to create a new function that does the calculation.
631+We now could add the 3 missing operations ('-', '*' and '/'). But hold on, there is room for improvement. Let's have a look at the following statement: `SecondNumber := StrToInt(edDisplay.Text);` We have seen such a statement before: the StoreOperation procedure contains something similar: `FirstNumber := StrToInt(edDisplay.Text);` Calculating the number the user entered now happens in two different locations. We do not want to repeat ourselves so it's a good idea to create a new function that does the calculation.
657632
658- * Locate the form's `private` section and add a new function: GetDisplayValue.
633+- Locate the form's `private` section and add a new function: GetDisplayValue.
659634
660-```
661-private
662- { private declarations }
663- SelectedOperation: TOperationType;
664- FirstNumber: longint;
665- SecondNumber: longint;
666- doClearDisplay: boolean;
667- procedure AddDigit(const pDigit: byte);
668- procedure StoreOperation(const pOperation: TOperationType);
669- function GetDisplayValue: longint;
635+``` pascal
636+ private
637+ { private declarations }
638+ SelectedOperation: TOperationType;
639+ FirstNumber: longint;
640+ SecondNumber: longint;
641+ doClearDisplay: boolean;
642+ procedure AddDigit(const pDigit: byte);
643+ procedure StoreOperation(const pOperation: TOperationType);
644+ function GetDisplayValue: longint;
670645```
671646
672- * Position the blinking text cursor on the line GetDisplayValue.
673- * Press `Ctrl`-`⇧ Shift`-`C`.
674- * Add this code to extract the value that is in the display field:
647+- Position the blinking text cursor on the line GetDisplayValue.
648+- Press `Ctrl`-`Shift`-`C`.
649+- Add this code to extract the value that is in the display field:
675650
676-```
651+``` pascal
677652function TForm1.GetDisplayValue: longint;
678- begin
679- result := StrToInt(edDisplay.Text);
680- end;
653+begin
654+ result := StrToInt(edDisplay.Text);
655+end;
681656```
682657
683- * Locate the statement: FirstNumber := StrToInt(edDisplay.Text);
684- * Change it to: FirstNumber := GetDisplayValue;
658+- Locate the statement: FirstNumber := StrToInt(edDisplay.Text);
659+- Change it to: FirstNumber := GetDisplayValue;
685660
686-So much for refactoring, back to the calculations.
661+So much for refactoring, back to the calculations.
687662
688- * Locate the statement: SecondNumber := StrToInt(edDisplay.Text);
689- * Change it to: SecondNumber := GetDisplayValue;
663+- Locate the statement: SecondNumber := StrToInt(edDisplay.Text);
664+- Change it to: SecondNumber := GetDisplayValue;
690665
691-Now look at the following statements:
692-```
693-// Retrieve the second number
694- SecondNumber := GetDisplayValue;
695- // Do the math
696- result := FirstNumber + SecondNumber;
697-```
666+Now look at the following statements:
698667
699-Variable _SecondNumber_ is used to store the value in the display box. However it is not really necessary. The above code can be simplified:
700-```
701-// Do the math
702- result := FirstNumber + GetDisplayValue;
668+``` pascal
669+ // Retrieve the second number
670+ SecondNumber := GetDisplayValue;
671+ // Do the math
672+ result := FirstNumber + SecondNumber;
703673```
704674
705-Now look at the following statements:
706-```
707-// Do the math
708- result := FirstNumber + GetDisplayValue;
709- // Display the resulting value
710- edDisplay.Text := IntToStr(result);
675+Variable *SecondNumber* is used to store the value in the display box. However it is not really necessary. The above code can be simplified:
676+
677+``` pascal
678+ // Do the math
679+ result := FirstNumber + GetDisplayValue;
711680```
712681
713-The same now applies to the _result_ variable. The above code can be simplified to:
682+Now look at the following statements:
683+
684+``` pascal
685+ // Do the math
686+ result := FirstNumber + GetDisplayValue;
687+ // Display the resulting value
688+ edDisplay.Text := IntToStr(result);
714689```
715-// Display the resulting value
716- edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
690+
691+The same now applies to the *result* variable. The above code can be simplified to:
692+
693+``` pascal
694+ // Display the resulting value
695+ edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
717696```
718697
719-Now we can add the 3 remaining operations.
698+Now we can add the 3 remaining operations.
720699
721- * Open the form.
722- * Double click on button '=' (the event handler is created).
723- * Change the code:
700+- Open the form.
701+- Double click on button '=' (the event handler is created).
702+- Change the code:
724703
725-```
704+``` pascal
726705procedure TForm1.btnCalculateClick(Sender: TObject);
727- begin
728- case SelectedOperation of
729- otPlus : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
730- otMinus : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
731- otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
732- otDivide : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
733- end;
734- end;
706+begin
707+ case SelectedOperation of
708+ otPlus : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
709+ otMinus : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
710+ otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
711+ otDivide : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
712+ end;
713+end;
735714```
736715
737-We now have a working calculator for all 4 operations:
716+We now have a working calculator for all 4 operations:
738717
739- * Run the program (press `F9`).
740- * Enter a number.
741- * Press an operation button.
742- * Enter another number.
743- * Press '=' : the result is displayed.
744- * End the program.
718+- Run the program (press `F9`).
719+- Enter a number.
720+- Press an operation button.
721+- Enter another number.
722+- Press '=' : the result is displayed.
723+- End the program.
745724
746725## Intermezzo
747726
748-After all this work we now have a useable calculator. But some things are not quite right. The obvious thing to try is dividing a number by zero. And the buttons 'C' and '+/-' don't work yet. These things will be addressed in the next section.
727+After all this work we now have a useable calculator. But some things are not quite right. The obvious thing to try is dividing a number by zero. And the buttons 'C' and '+/-' don't work yet. These things will be addressed in the next section.
749728
750-First let's add another procedure, just for the fun of it (well, there's more to it of course:-)):
729+First let's add another procedure, just for the fun of it (well, there's more to it of course:-)):
751730
752- * Locate the form's `private` section and add a new procedure: SetDisplayValue.
731+- Locate the form's `private` section and add a new procedure: SetDisplayValue.
753732
754-```
755-private
756- { private declarations }
757- SelectedOperation: TOperationType;
758- FirstNumber: longint;
759- SecondNumber: longint;
760- doClearDisplay: boolean;
761- procedure AddDigit(const pDigit: byte);
762- procedure StoreOperation(const pOperation: TOperationType);
763- function GetDisplayValue: longint;
764- procedure SetDisplayValue(const pValue: longint);
733+``` pascal
734+ private
735+ { private declarations }
736+ SelectedOperation: TOperationType;
737+ FirstNumber: longint;
738+ SecondNumber: longint;
739+ doClearDisplay: boolean;
740+ procedure AddDigit(const pDigit: byte);
741+ procedure StoreOperation(const pOperation: TOperationType);
742+ function GetDisplayValue: longint;
743+ procedure SetDisplayValue(const pValue: longint);
765744```
766745
767- * Position the blinking text cursor on the line SetDisplayValue.
768- * Press `Ctrl`-`⇧ Shift`-`C`.
769- * Add the code below to give the display a new value, as the procedure name suggests:
746+- Position the blinking text cursor on the line SetDisplayValue.
747+- Press `Ctrl`-`Shift`-`C`.
748+- Add the code below to give the display a new value, as the procedure name suggests:
770749
771-```
750+``` pascal
772751procedure TForm1.SetDisplayValue(const pValue: longint);
773- begin
774- edDisplay.Text := IntToStr(pValue);
775- end;
752+begin
753+ edDisplay.Text := IntToStr(pValue);
754+end;
776755```
777756
778-The above code should look pretty familiar. Have a look at the procedure that does all calculations:
779-```
757+The above code should look pretty familiar. Have a look at the procedure that does all calculations:
758+
759+``` pascal
780760procedure TForm1.btnCalculateClick(Sender: TObject);
781- begin
782- case SelectedOperation of
783- otPlus : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
784- otMinus : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
785- otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
786- otDivide : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
787- end;
788- end;
761+begin
762+ case SelectedOperation of
763+ otPlus : edDisplay.Text := IntToStr(FirstNumber + GetDisplayValue);
764+ otMinus : edDisplay.Text := IntToStr(FirstNumber - GetDisplayValue);
765+ otMultiply : edDisplay.Text := IntToStr(FirstNumber * GetDisplayValue);
766+ otDivide : edDisplay.Text := IntToStr(FirstNumber div GetDisplayValue);
767+ end;
768+end;
789769```
790770
791-This procedure can now be simplified.
771+This procedure can now be simplified.
792772
793- * Change the code to:
773+- Change the code to:
794774
795-```
775+``` pascal
796776procedure TForm1.btnCalculateClick(Sender: TObject);
797- begin
798- case SelectedOperation of
799- otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
800- otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
801- otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
802- otDivide : SetDisplayValue(FirstNumber div GetDisplayValue);
803- end;
804- end;
777+begin
778+ case SelectedOperation of
779+ otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
780+ otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
781+ otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
782+ otDivide : SetDisplayValue(FirstNumber div GetDisplayValue);
783+ end;
784+end;
805785```
806786
807787## Loose ends
808788
809-There's a couple of things that need to be done: implement the two loose buttons and make the calculator a bit more robust.
789+There's a couple of things that need to be done: implement the two loose buttons and make the calculator a bit more robust.
810790
811791### The +/- button
812792
813- * Open the form.
814- * Double click on button '+/-' (the event handler is created).
815- * Add the following code:
793+- Open the form.
794+- Double click on button '+/-' (the event handler is created).
795+- Add the following code:
816796
817-```
797+``` pascal
818798procedure TForm1.btnPlusMinusClick(Sender: TObject);
819- begin
820- SetDisplayValue(0 - GetDisplayValue);
821- end;
799+begin
800+ SetDisplayValue(0 - GetDisplayValue);
801+end;
822802```
823803
824-See here the fruits of our labor. We have reused the procedure SetDisplayValue and GetDisplayValue to implement the negate function.
804+See here the fruits of our labor. We have reused the procedure SetDisplayValue and GetDisplayValue to implement the negate function.
825805
826-Try it by running the program and press the '+/-' button.
806+Try it by running the program and press the '+/-' button.
827807
828808### The Clear button
829809
830- * Open the form.
831- * Double click on button 'C' (the event handler is created).
832- * Add the following code:
810+- Open the form.
811+- Double click on button 'C' (the event handler is created).
812+- Add the following code:
833813
834-```
814+``` pascal
835815procedure TForm1.btnClearClick(Sender: TObject);
836- begin
837- SetDisplayValue(0); // Start from scratch
838- SelectedOperation := otNone; // No operation selected yet
839- doClearDisplay := false; // The display is already cleared
840- end;
816+begin
817+ SetDisplayValue(0); // Start from scratch
818+ SelectedOperation := otNone; // No operation selected yet
819+ doClearDisplay := false; // The display is already cleared
820+end;
841821```
842822
843-The above code is pretty self-explanatory: the display is cleared (the first line), we 'forget' about any pending operation by clearing the SelectedOperation variable and there is no need to clear the display when adding new digits, because it was already cleared by the first statement.
823+The above code is pretty self-explanatory: the display is cleared (the first line), we 'forget' about any pending operation by clearing the SelectedOperation variable and there is no need to clear the display when adding new digits, because it was already cleared by the first statement.
844824
845825### Divide by zero
846826
847-Let's go crazy: run the application and try to divide 10 by 0. This will make the application crash horribly. We have to make sure that this will not happen. The place to check this of course is the place where all calculations are performed (TForm1.btnCalculateClick).
827+Let's go crazy: run the application and try to divide 10 by 0. This will make the application crash horribly. We have to make sure that this will not happen. The place to check this of course is the place where all calculations are performed (TForm1.btnCalculateClick).
848828
849- * Open the form.
850- * Double click on button '='.
851- * Update the otDivide section:
829+- Open the form.
830+- Double click on button '='.
831+- Update the otDivide section:
852832
853-```
833+``` pascal
854834procedure TForm1.btnCalculateClick(Sender: TObject);
855- begin
856- case SelectedOperation of
857- otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
858- otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
859- otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
860- otDivide : begin
861- if GetDisplayValue <> 0 then
862- SetDisplayValue(FirstNumber div GetDisplayValue)
863- else
864- begin
865- // Display an error message to the user
866- MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
867- // Reset the calculator to start with a clean slate
868- btnClearClick(nil);
869- end
835+begin
836+ case SelectedOperation of
837+ otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
838+ otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
839+ otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
840+ otDivide : begin
841+ if GetDisplayValue <> 0 then
842+ SetDisplayValue(FirstNumber div GetDisplayValue)
843+ else
844+ begin
845+ // Display an error message to the user
846+ MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
847+ // Reset the calculator to start with a clean slate
848+ btnClearClick(nil);
870849 end
871- end;
872- end;
850+ end
851+ end;
852+end;
873853```
874854
875-Things to note:
855+Things to note:
876856
877- 1. _MessageDlg_ is a function for displaying a short warning/error/informative message to the user. _ShowMessage_ can also be used. It is a bit easier to use but cannot display warning/error icons.
878- 2. _btnClearClick(nil)_ : as soon as an error condition occurs we must reset the calculator. That's basically the same as pressing the 'C' button. We simulate pressing the 'C' button by directly calling the event handler.
857+1. *MessageDlg* is a function for displaying a short warning/error/informative message to the user. *ShowMessage* can also be used. It is a bit easier to use but cannot display warning/error icons.
858+2. *btnClearClick(nil)*: as soon as an error condition occurs we must reset the calculator. That's basically the same as pressing the 'C' button. We simulate pressing the 'C' button by directly calling the event handler.
879859
880860### Overflows
881861
882- * Start the calculator
883- * Enter 99999999 as the first number (8 digits)
884- * Press button '*'
885- * Enter 99999999 as the second number
886- * Press button '='
862+- Start the calculator
863+- Enter 99999999 as the first number (8 digits)
864+- Press button '*'
865+- Enter 99999999 as the second number
866+- Press button '='
887867
888-Now two things could have happened:
868+Now two things could have happened:
889869
890- 1. The application gives an incorrect result (something like 1674919425).
891- 2. The application raises an error.
870+1. The application gives an incorrect result (something like 1674919425).
871+2. The application raises an error.
892872
893-If it's the first option then overflow errors have been disabled for the project. Enable them by ticking the Overflow option box:
873+If it's the first option then overflow errors have been disabled for the project. Enable them by ticking the Overflow option box:
894874
895- * Select from the menu Project/Project Options…
896- * Select in the treeview Compiler Options/Code Generation.
897- * Tick the box _Overflow (-Co)_ (see image below).
898- * Click OK.
875+- Select from the menu Project/Project Options…
876+- Select in the treeview Compiler Options/Code Generation.
877+- Tick the box *Overflow (-Co)* (see image below).
878+- Click OK.
899879
900-[![tutcal compiler overflow.png](/wiki-images/a/ae/tutcal_compiler_overflow.png)](</File:tutcal_compiler_overflow.png>)
880+![](/wiki-images/3/34/Tutcal_compiler_overflow.png)
901881
902-Now run the program again and see what happens with overflows.
882+Now run the program again and see what happens with overflows.
903883
904-
905-If it was the second (and expected) option then this means we have to add [[Exceptions|exception]] handling to our little calculator. Exception handling is used to prevent an application from crashing when errors occur. In our case we want to handle the arithmetic overflow error that might occur. Because all calculations are done in one place, it's easy to catch any overflow errors.
884+If it was the second (and expected) option then this means we have to add [[Exceptions|exception]] handling to our little calculator. Exception handling is used to prevent an application from crashing when errors occur. In our case we want to handle the arithmetic overflow error that might occur. Because all calculations are done in one place, it's easy to catch any overflow errors.
906885
907- * Open the form.
908- * Double click on button '='.
909- * Change the code in the procedure to this:
886+- Open the form.
887+- Double click on button '='.
888+- Change the code in the procedure to this:
910889
911-```
890+``` pascal
912891procedure TForm1.btnCalculateClick(Sender: TObject);
913- begin
914- // Catch any overflow errors
915- try
916- case SelectedOperation of
917- otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
918- otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
919- otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
920- otDivide : begin
921- if GetDisplayValue <> 0 then
922- SetDisplayValue(FirstNumber div GetDisplayValue)
923- else
924- begin
925- // Display an error message to the user
926- MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
927- // Reset the calculator to start with a clean slate
928- btnClearClick(nil);
929- end
892+begin
893+ // Catch any overflow errors
894+ try
895+ case SelectedOperation of
896+ otPlus : SetDisplayValue(FirstNumber + GetDisplayValue);
897+ otMinus : SetDisplayValue(FirstNumber - GetDisplayValue);
898+ otMultiply : SetDisplayValue(FirstNumber * GetDisplayValue);
899+ otDivide : begin
900+ if GetDisplayValue <> 0 then
901+ SetDisplayValue(FirstNumber div GetDisplayValue)
902+ else
903+ begin
904+ // Display an error message to the user
905+ MessageDlg('It is not possible to divide a number by 0!', mtWarning, [mbCancel],0);
906+ // Reset the calculator to start with a clean slate
907+ btnClearClick(nil);
930908 end
931- end;
932- except
933- on E: EIntOverflow do
934- begin
935- // Display an error message
936- MessageDlg('The result of the calculation was too big for the calculator to process!', mtWarning, [mbCancel], 0);
937- // Reset the calculator
938- btnClearClick(nil);
939- end
940- end
909+ end
941910 end;
911+ except
912+ on E: EIntOverflow do
913+ begin
914+ // Display an error message
915+ MessageDlg('The result of the calculation was too big for the calculator to process!', mtWarning, [mbCancel], 0);
916+ // Reset the calculator
917+ btnClearClick(nil);
918+ end
919+ end
920+end;
942921```
943922
944-Note that even with the exception handling in place, the application will still halt when run from inside the IDE. However the application is only paused and still active. Press `F9` to continue. This will display another pop up window, a debugger notification window. Press Continue. Now our own exception handler will kick in with the expected message.If you were to run the application stand alone (i.e. outside the IDE) then you would only see the message box that we added to the exception handler.
923+Note that even with the exception handling in place, the application will still halt when run from inside the IDE. However the application is only paused and still active. Press `F9` to continue. This will display another pop up window, a debugger notification window. Press Continue. Now our own exception handler will kick in with the expected message.If you were to run the application stand alone (i.e. outside the IDE) then you would only see the message box that we added to the exception handler.
945924
946925## Final tweaks
947926
948-Remember that at a certain point a variable called _SecondNumber_ was introduced. If you choose Run/Build All from the menu, then after building the application the compiler will display a message in the Messages window that this particular variable is never used. If you click on the message text the IDE opens the exact location in the editor where the variable is declared.
927+Remember that at a certain point a variable called *SecondNumber* was introduced. If you choose Run/Build All from the menu, then after building the application the compiler will display a message in the Messages window that this particular variable is never used. If you click on the message text the IDE opens the exact location in the editor where the variable is declared.
949928
950- * Click on message _Note: Private field "TForm1.SecondNumber" is never used_.
951- * Delete longint variable _SecondNumber_.
929+- Click on message *Note: Private field "TForm1.SecondNumber" is never used*.
930+- Delete longint variable *SecondNumber*.
952931
953-
954-As soon as our demo Calculator is started we see that the number 0 in the display has the focus (see image below).
932+As soon as our demo Calculator is started we see that the number 0 in the display has the focus (see image below).
955933
956-[![tutcal calculator focus.png](/wiki-images/7/77/tutcal_calculator_focus.png)](</File:tutcal_calculator_focus.png>)
934+![](/wiki-images/4/46/Tutcal_calculator_focus.png)
957935
958-This is counter intuitive because a user should not be able to enter anything in that box. Even worse as soon as she would type something in there that is not a number, our calculator would crash! So it's better not to give access to the that control at all. We are going to fix that.
936+This is counter intuitive because a user should not be able to enter anything in that box. Even worse as soon as she would type something in there that is not a number, our calculator would crash! So it's better not to give access to the that control at all. We are going to fix that.
959937
960- * Open the form.
961- * Select the display control (click on edDisplay).
962- * In the Object Inspector change ReadOnly to _True_ (if the Events tab is still visible, select the Properties tab first to gain access to all properties). From now on it's impossible to enter any data manually.
963- * Change TabStop to _False_. Now it's impossible to get to the display field via the keyboard and the display field will not be highlighted anymore.
938+- Open the form.
939+- Select the display control (click on edDisplay).
940+- In the Object Inspector change ReadOnly to *True* (if the Events tab is still visible, select the Properties tab first to gain access to all properties). From now on it's impossible to enter any data manually.
941+- Change TabStop to *False*. Now it's impossible to get to the display field via the keyboard and the display field will not be highlighted anymore.
964942
965-Run the program to see the result of these changes.
943+Run the program to see the result of these changes.
966944
967-
968945(Under construction: OO-ify the program)
969946
970947---
971-*From the Free Pascal wiki, page "Howdy World (Hello World on steroids)", as the Internet Archive kept it on 2024-09-20. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
948+*From the Free Pascal wiki, page "Howdy World (Hello World on steroids)", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history