This page is a quick reference to syntax for the Delphi commands we have covered so far in our course. It will simply be in order of when we cover it, rather than any kind of order at all… : )
Before we begin… Variable Declaration
In Delphi, we must declare any variables (placeholders for a changing value) that are going to be used in a procedure. Other programming languages are not so strict, but it's good programming practice to do so. We use the keyword var to declare a variable. Remember, you must declare your variable at the beginning of your procedure - before your first begin statement (and after the procedure statement).
procedure TGetArea.CalculateButtonClick(Sender: TObject);
_ var radius : real; //declares a single variable called radius as type real
_ var area, circumference : real; //declares two variables called area and circumference, both as type real
_ {the following code demonstrates that you only need one var statement to declare as many variables as you need in your procedure}
_ var volume : real ;
_ _ _ message : string ;
_ _ _ validity : boolean ;
_ begin
.
.
.
Note that the above code sample uses two different comment styles - // and {}. Also note the indentation (I've used underscores _ as the site won't let me have that many spaces in a row). These are all examples of making use of internal documentation to make the program more readable.
You can declare constants (placeholders for a non-changing value) in exactly the same way, using the const keyword. This is useful if you have a value that you use many times within your program, such as pi or taxrate. It's another example of making use of internal documentation to make the program more readable.
Data types
The data type you choose to use for a variable or constant should be appropriate for the type of data you are storing. When you declare a variable you are setting aside some memory space for it. For example, if you want to store a Yes/No value, you wouldn't use the type string as this would be overkill. In a simliar way, you wouldn't build a seven car garage if you're only going to use three of the bays. Not only that, your program can crash if it tries to store a value in a variable that has been declared as a different type (eg, trying to store a string value in an integer variable). And of course, using appropriate variable types is another example of (surprise, surprise) using internal documentation to make the program more readable.
Here is a short list of the data types you may have used so far:
- boolean : used for storing True or False (yes/no, 1/0 on/off can convert into true/false)
- byte : an integer value between 0 and 255 (inclusive)
- integer : used for storing whole number values
- real : used for storing decimal number values (ie real numbers)
- string : usef for storing text, or combinations of text, symbols and numbers
- char : used for storing single characters (like a string, but only one character long)
There are heaps more, and you can even make up your own! Use Delphi's internal help to discover more.
Reading from or writing to an object's property at runtime
If you think about it for long enough, you'll realise that the properties of an object are simply placeholders for data - in other words, they are variables! The good news is, you don't need to declare these variables. But there are a few things you need to be aware of.
Firstly, you can't name a variable the same as an object's property. Say you have a button. Of course, this button has many properties including caption, left, top, anchors, visible…. So in any of this button's procedures, you cannot name any of your variables 'caption', 'left', 'top' etc.
Secondly, you need to read from and write to these variables using the following format: ((objectname.property}}. For example CalculateButton.Caption := area or area := CalculateButton.Caption. So you can't just say caption := area, as the program does not know to which object you are referring. Similarly, you can't just say CalculateButton := area, as the program does not know which property of CalculateButton you want to assign the value to.
if … then … else
Using if… then… else is similar to the logic gate theory we studied. It's simple boolean logic - IF the condition is TRUE then execute action 1 ELSE execute action 2. The condition can be a single condition or a combination of many conditions using ORs, ANDs or NOTs. It's to your benefit to find the simplest condition expression that you can, this helps with your internal documentation, making the program more readable.
Here is the syntax:
IF condition THEN actions to execute if true ELSE actions to execute if false ;
Let's look at some examples of how to implement IF THEN ELSE statements.
- Executing multiple statements as one of the actions:
if x = 1
then begin
_ _ _ statement 1;
_ _ _ statement 2;
_ _ _ statement n;
_ _ _end
else statement 1;
end;
- Having no alternate action (ie if condition returns FALSE then do nothing):
if x = 1
_ then action 1;
- Using an IF on a boolean variable (eg a property such as visible that has the value of either TRUE or FALSE)
if label1.visible
then action 1
else action 2;
Notice you don't need to specify any condition for a boolean variable - which kind of makes sense because each condition is a TRUE/FALSE anyway - that is, if label1.visible is the same as if label1.visible = TRUE.
- Using an IF with a NOT
Sometimes it's more efficient to use a NOT to reverse the outcome of the condition:
if not x = 1
then begin
_ _ _ statement 1;
_ _ _ statement 2;
_ _ _ statement n;
_ _ _end
else begin
_ _ _ statement 1;
_ _ _ statement 2;
_ _ _ statement n;
_ _ _end; {if}
Note that in this case because the else action has multiple statements, it's good programming practice to indent the end at the end of the if, and also a good idea to indicate what is ending with a comment.
Also notice that the first end (part of the then action) has no semicolon (;), but the second end does have a semicolon, because it designates the end of the if statement as a whole.
- Multiple conditions - AND and OR
Just like logic gates, you can use AND and OR to test more than one condition at a time.
if (x = 1) or (x = 2) or (x = 3)
then action 1
else action 2 ;
if (x > 1) and (x < 10) and (x <> 3)
then action 1
else action 2 ;
You can even test more than one variable in the one statement.
if (x = 1) or (y = 1) or (z = 1)
then action 1
else action 2 ;
if (x >= 1) and (x < 10) and (Checkbox1.Checked)
then action 1
else action 2 ;
case … of
You might use case … of to avoid using too many IFs… to make your program more readable (all part of internal documentation ; ) ).
case x of
_ 0: begin
_ _ _ statement 1;
_ _ _ statement 2;
_ _ end;
_ 1: action 2;
_ 2..4 : action 3;
_ else action 4 ;
end;
Converting between variable types
The StrToFloat() function converts a string value (parsed into the function by putting it inside the parentheses) into a floating point decimal number, enabling us to perform a calculation on it:
area := StrToFloat(AreaEditBox.Text);
converts the contents of the AreaEditBox.Text property to a floating point decimal number, enabling us to calculate with it.
The FloatToStr() function converts a numeric value (parsed into the function by putting it inside the parentheses) into a string value, enabling us to put it into a caption or text property (or perform other cool string operations such as concatenation).
DisplayLabel.Caption := FloatToStr(area);
assigns the value of the variable area to the caption in the DisplayLabel.
AreaString := FloatToStr(area);
DisplayLabel.Caption := AreaString;
does the same thing, it just assigns it to the AreaString variable first. Which method you choose depends on the permanance of the AreaString variable - eg if you are going to use it again for another purpose (eg putting the value into a different caption, or join it together with another string) you might choose the second method.
Similarly, you can use the StrToInt() and IntToStr() functions to convert between String and Integer. DateToStr(), StrToDate(), TimeToStr(), StrToTime() are pretty obvious… there are heaps of others to work with.
How the Delphi unit is structured
When you look at the code for your units, you will see that each Delphi unit is made up of three basic sections, in this order:
The name section
consisting simply of the word unit, followed by its name.
unit whatever_you_name_it;
The interface section
where the unit is basically set up, ready to be used. It specifies the other units that it will use, as well as the forms (and each form's controls) and procedures within this unit. Think of it this way: if you're cooking a 3 course meal, this section tells you which other recipes you will need (eg for spaghetti bolognese, custard), as well as the tools/utensils you will be using (eg saucepan, mixing bowl).
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
_ TForm1 = class(TForm)
_ _ Edit1: TEdit;
_ _ Label1: TLabel;
_ _ Label2: TLabel;
_ _ Edit2: TEdit;
_ _ _ procedure Edit1Click(Sender: TObject);
_ private
_ _ { Private declarations }
_ public
_ _ { Public declarations }
_ end;
var
_ Form1: TForm1;}}
Let's look at this section bit by bit.
interface
denotes the beginning of the interface section.
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
identifies all of the other units that this unit draws upon so that it can work. Eg, if Controls wasn't included, you couldn't use the controls on your form. What happens if you add to the list above? What message do you get when you run the program? What does this tell you about what is happening?
type
_ TForm1 = class(TForm)
Specifies the types that the unit creates. A type is a category of variable, such as boolean, real, string. Here you are actually creating a new type of variable.
_ _ Edit1: TEdit;
_ _ Label1: TLabel;
_ _ Label2: TLabel;
_ _ Edit2: TEdit;
These lines all represent the names of the objects that exist on TForm1. There's two editboxes (named Edit1 and Edit2, of type TEdit) and two labels (Label1 and Label2, of type TLabel).
_ _ _ procedure Edit1Click(Sender: TObject);
This line declares that within TForm1 there is a procedure called Edit1Click. Within the parentheses are the arguments that are passed into the procedure from the calling procedure. Don't worry about what's in the parentheses at this stage.
_ private
_ _ { Private declarations }
Declare any procedures used by this unit but must not be used by other units in the private declarations section. Just like you don't want your private information known by everyone, your unit doesn't want these procedures used by other units.
_ public
_ _ { Public declarations }
Declare any procedures that can be used by other units in the public declarations section. You might want some parts of your life made public. Your unit might too (its procedures, that is).
end;
var
Form1: TForm1;}}
Form1 is the name of a form used within this unit. You are actually declaring here that you are going to use an object named Form1, of the class TForm. Just like declaring a variable! In fact, here is where you will declare any variables that are not specific to one procedure. For example, you might want to make use of the same variable within a ButtonClick procedure as well as an EditBoxChange procedure. If so, declare that variable here.
The implementation section
is where the event procedures (event handlers) are written.
implementation
denotes the beginning of the implementation section.
{$R *.dfm}
is a comment. Honestly, I have no idea why it's here.
procedure TForm1.Edit1Click(Sender: TObject);
.
.
.
end;
This is an event procedure. Any procedures that are in your unit are in the implementation section. You implement your algorithms using procedures.
Each procedure that exists in your implementation section must be declared in your interface section. Likewise, each procedure that is declared in your interface section must exist in your implementation section, otherwise you will get either an 'undeclared identifier' or an 'unsatisfied forward or external declaration' error message.
end.
All units must end with the above statement. The period after the end indicates that it's the end of the unit.
Now that you know exactly how your unit is structured, you can use this knowledge to check your own coding.
Setting a form's properties at design time without the Object Inspector
You know how to set a form's properties at design time (using the Object Inspector). There is another way. Right click on your form and select 'View as Text'. You see something like the below:
object Form1: TForm1
Left = 266
Top = 189
Width = 870
Height = 640
Caption = 'Form1'
Color = clOlive
object Label1: TLabel
Left = 400
Top = 312
Width = 32
Height = 13
Caption = 'Label1'
end
object Edit1: TEdit
Left = 344
Top = 264
Width = 121
Height = 21
TabOrder = 0
Text = 'Edit1'
end
end
This simply allows you to set the properties with much more difficulty. Why would you do it this way? No idea. Right click on the text window and choose 'View as Form' to go back.
Still to come…
properties for some components and what the properties do
loops - for to do, repeat until and do wha diddy diddy dum diddy do