Delphi Tutorial – Lesson 1 12/29/98 Frank Fortino [email protected] Copyright 1999

Delphi Tutorial – Lesson 1 12/29/98
Frank Fortino [email protected] Copyright 1999

Main Topics:

* -Programming philosophy and structure
* -Improving the Delphi Environment (Options)
* -Naming conventions
* -Powerful Method (LoadFromFile)
* -Using F1 (Help)
* -The 3 main Delphi Files (.dpr .pas .dfm)
* -Right Mouse Clicking
* -Modify your Toolbar
* -Keeping project versions in separate folders
* -Using F12 key (Toggle Form/Unit)
* -Delphi Quirks
* -Making your own Help Library
* -Owner / Parent
* -Sender?
* -Variants
* -Multitasking
* -Pointers (oh god)
* -Place to Initialize your vars

Throughout these Lessons, I will express my opinion on what I think is important and how to write good readable, maintainable programs. I am not saying that this is the best way to do things, I only know what has helped me.

There are so many choices. That’s part of the Problem with Delphi, and the Power of Delphi.

So, to keep this a learning experience and to the point, we can discuss the advantages of different programming styles later.

The Style of these Lessons will be somewhat Rambling, I will change topics inside topics.

This is done to conserve time, and to explain things as they come up.

Look at the power of HTML, you can go anywhere, in different ways; lots of choices.

When you program using Delphi you

– Should setup the most powerful environment that you can
– Customize your Tools
– Set up a Library system to save the stuff you learn
– Learn good habits

There are some little tricks that you can do with Delphi e.g. Hold the Ctrl Key down while grouping Objects(On Form)
Selects ALL Objects touched – you can then change the Properties of the entire group with ONE blow.

There are also some consistent ways that Delphi works. Right Click to: usually PopsUpMenu

Double Click to: usually Selects OnClickEvent etc.

TURN OFF THE CODE OPTIMIZATION

-Project
-Options
-Compiler
-Optimization TURN OFF
-Check Default(CheckBox)
-OK

The Code Optimizer is TOO Smart sometimes, and does not let you set Breakpoints (to stop your code).

I will have a Lesson on Breakpoints and Debugging your Code later.

You can learn a lot from using the Debugger

– You can see the sequence that Delphi executes code
– You can Watch your Data
– In a Watch Window
– or In a Memo on your Form

Delphi has some very powerful Methods and Properties for different Components.

For example:
ListBox1.Items.LoadFromFile(‘c:autoexec.bak’);

Items is a TStrings type (So what!) – What you say…
Well TStrings has a Method LoadFromFile that: – Assigns, Opens, Reads and Closes a Text file all in 1 Command

ListBox1.Items.LoadFromFile(‘c:autoexec.bak’); ListBox1 now contains all the text in the file ‘autoexec.bak’

WOWWWW!!!!

So any Component that has a TStrings Property

Memo Memo1.Lines.LoadFromFile(‘ .Lines ListBox ListBox1.Items.LoadFromFile(‘ .Items ComboBox ComboBox1.Items.LoadFromFile(‘ .Items can use LoadFromFile.

There is also SaveToFile.
Look these up in Help:

-Put ListBox on Form
-Hit F1
-Properties
-Items
-TStrings
-Methods
-LoadFromFile
-Example

This is a very useful way of getting help.

Click on a Component, F1, Properties,…

You can also Click on a Component’s Property:
-Put ListBox on Form
-Click on ListBox
-In Object Inspector
-Click on ‘Sorted’ property (on the left side)
-Example
—-

Or you could Search for ‘TStrings’
-Help
-Keyword Search
-enter ‘TStrings’
-LoadFromFile
-…
Getting started.

The Delphi environment:
Delphi programs consist of 3 main files (.dpr .pas .dfm)

.dpr your project file
– a small program (text file)

– defines Units in Project

uses
Forms,
Unit1 in ‘Unit1.pas’ {Form1};
1) Initializes Data
2) Builds (creates) the Forms
3) Runs the Application (program)
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

———————————–

.pas 1 or more Units (pascal code)

———————————–

.dfm 1 or more Form definition files

Note:
– Each Form (.dfm) MUST have a Unit (.pas)
-You can have Units without a Form (for code only)

The .dfm file is a special pseudo code file. It requires you to use a special program to read this file (Point to Form, Right Click, select VIEW AS TEXT) – now you can see your Form creation code:

Example .dfm file:
—————–

object Form1: TForm1
Left = 200
Top = 108
Width = 696
Height = 480
Caption = ‘Form1’
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = ‘MS Sans Serif’
Font.Style = []
PixelsPerInch = 96
TextHeight = 13
object Button1: TButton
Left = 176
Top = 116
Width = 75
Height = 25
Caption = ‘Button1’
TabOrder = 0
end
end

——

This is a file that you can edit (inside Delphi only) by using VIEW AS TEXT

Normally you do not edit the .dfm file (as text), you normally move Objects on the Form, and Delphi creates
the .dfm file for you.

To navigate back and forth from the Form(view) to the
.dfm(view) use:
VIEW AS TEXT
VIEW AS FORM

COMMENT:
——–
Try a Mouse Right Click on everything
Delphi uses this pop up menu a lot

use Right Click to:
– CLOSE the page your on (sometimes you have files open that are not part of your program; they are only there to let you easily Cut and Paste, code chucks, group of Components)
– VIEW AS FORM
– VIEW AS TEXT
————————————————–

Developing projects with Delphi
– I use version numbers starting at 1 e.g. Project Named ‘SysSetup’ file names SysSetup1P.dpr // I use a ‘P’ at the end, because Delphi will not let use the same name for .dpr and .pas files.

SysSetup1.pas
SysSetup1.dfm

– Use a separate Folder (directory) for each project
Always start with a NEW APPLICATION and immediately do:

-File
-PROJECT SAVE AS ‘SysSetup1P’
-NEW FOLDER c:Delphi3SysSet

-File
-SAVE AS ‘SysSetup1’
——————————————————-

Your Tool Bar
————–

I find these tools the best for me

NewApp OpenPrj Undo AddFToPrj ViewAllign
OpenFile SaveAll CloseAll Find SearchAgain Replace

ViewPrjMgr AddWatch Run
ViewPrjSrc ToggleForm BuildAll

Note:
Be sure to Right Click on Tool Bar(Top Left) and Select SHOW HINTS (ON)
To modify your Tool Bar setup:
Right Click on Tool Bar and Select PROPERTIES
Drag and drop Icons Off ToolBar
Drag and drop Icons from List onto ToolBar

Be sure to Right Click on Component Palette(Top Right) and Select SHOW HINTS (ON)

Good Programming Habits:

1) Capitalize the first letter of each new word (in a name) avoid underscores (they are redundant) New_Data
should be NewData

2) Indent 2 or 3 spaces Line up ALL begin ends

for x:=1 to 22 do
begin
if y>32 then ….
end;
—————-
if … then
begin

end
else if … then
begin

end;

Name all your Components when you first use them
Project1
SysSetup1P.dpr

Form1
SysFrm1 // put in a new folder

Unit1
SysSetup.pas
SysSetup.dfm

Button1
StartBtn

ListBox1
LB1
CustList

Change of Subject: Frank’s programming Style

– Small but informative names
SysSetup1P.dpr
XFileName (a Global variable)

– Project files end with *P.dpr
Because .dpr cannot have the same name as .pas

– Sometimes I like to have the same beginning name for Units:
FSysSetupP.dpr
FSysMain.pas
FSysCust.pas
FSysOrder.pas
– Sometimes I use numbers at the end of my Unit names
FSysRpt1.pas
FSysRpt2.pas

– Pick a way to name your components
My way (which varies)
T1 : TTable; // a generic Table that is locally on the Form
or is reused and changed
BrandTbl : TTable; // a better way

or TblBrand : TTable;
TblCost : TTable
—-

My abbreviations:

Form – Frm1
Table – Tbl
T1
Button – Btn1
DataSource – DS1
Query – Q1
ListBox – LB1
or NameBox1
Other Programming Hints:

Remember RENAME EVERYTHING AT THE START!

Keep Project versions separated in their own Folders:
c:FreedomSetup1228 date = 1228

Copy ONLY *.dpr *.pas *.dfm to the New Folder
Drop the .dpr File on Delphi 3 (Launch it)

PROJECT SAVE AS ‘SysSetup2P.dpr’

Now you have a perfect copy of your SysSetup1P.dpr, …
without any Hooks or Links to the Old program.

New Subject: Form Stuff

Form Events
OnCreate
OnShow
OnActivate

Form Properties
Visible

They all control when a Form is Created, Visible, Open, Closed, Active
What is the Difference between them, and How and When do you use them.

A Form is Created first.
It’s Only Created one time in the .dpr File

————
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1); // Right Here Form1 is Created
Application.Run;
end.
——–

Form1.Show; is a method that makes the Form Visible(Open);

Form1.Visible:=True; // Makes a Form Visible

Form1.Close; // Makes the Form not Visible (If Form1 is your Main Form, this will Close (Quit) your Project)

So don’t Close Form1, just set Form1.Visible:=False;
IMPORTANT KEYS

F1 = Help
F12 = Toggle Form / Unit

I use both these Keys a lot, you should too.
Delphi Quirks

Be careful, Delphi does a lot behind the scenes.
(this is not a complete example – it’s only trying to show you how a Problem can occur)

That’s why I say to name everything, Before you start coding or Linking other Components.

For Example:
Working with Tables and DBGrids
If you Right Click a Table
-Select FIELDS EDITOR
-Right Click
-Add Fields
– …
Then you Link a DBGrid to that Table. Then you edit or delete some Table Fields.

Watch out —
Delphi still thinks you have fields that you deleted.

You have to Remove the Table and DBGrid; and start over to break those Links.

Sometimes it’s hard to go backwards in Delphi.
COMMENT:
Programming with C++ is like programming with Sand.
You can build Bricks (in 3 days)
You can use Bricks to build Walls (after weeks)
You can use Walls to build Rooms (after months)

With Delphi you are programming with Rooms
You can use Rooms to Build Houses (in 15 minutes)
Keeping your own Help Library

You learn so much so fast in Delphi, that you should have a simple and quick way to save what you learned:
-In example programs
-In Text files

You learn so much, that you get lost. When you come back to a subject (say ListBoxes) you forget some the details of how to use a ListBox and how to use certain roperties.

You did it before, but how?
You will be in this position a lot if you don’t save things as you learn them.

Always have a text editor (like NotePad) open on your Tray, so that you can cut and paste code snippets from Help examples or your own code, into a text file and save it as (say: ‘ListBoxLoading.txt’)

Also, a way to learn about a new Component that you’ve not used before; is to create a new project with just that Component (say: ComboBox1) with a few Buttons that hange Properties of ComboBox1 or call Methods of ComboBox1.

Play with the program a while, then save the program
(.dpr .pas .dfm) files in its own folder (say: ‘c:D3 HelpComboBoxes’)

Believe me, these little help files that you create (text and programs), will accumulate and give you a nice Library of very useful stuff.

That’s what a Power Programmer is (He has lots of Stuff to copy, cut paste to create projects)

So get some good habits now, and you will not take any steps backward. It is very frustrating to have to look up something that you knew how to do.
Some OOP Basics

Parent
Owner
Sender

What is what?

Difference between Owner and Parent:
If you have a Form1
On Form1 you place a Panel1
On Panel1 you place Button1

Form1 is the Parent of Panel1
Panel1 is the Parent of Button1
Form1 is the Owner of both Panel1 and Button1

Form1 owns everything, Form1 is the Owner and Parent of Panel1

Form1 is the Owner of Button1, but Button1’s Parent is Panel1 (because Button1 is On (Held by) Panel1).

The Owner is important, because when Form1 is Created by the .dpr File:
Application.CreateForm(TForm1, Form1);

Form1 now exits in Memory (takes up space)
When Form1 is Created so is Panel1 and Button1 because Form1 is the Owner.

When Form1 is Closed (you Exit your Project) the Memory used by Form1, Panel1 and Button1 is Freed (put back in the Heap).

Have you heard of a Memory Leak?
A Memory Leak is when Form1 Closes, but it does not Free the RAM used by Button1. This would be a BUG in Delphi (which is not the case).

So now every time you Create Form1 and Close it, it would use up and waste the RAM used to Create Button1.

Only a few Components can be Parents – They can contain other Components

A Button cannot contain another Button, so it cannot be a Parent

Only a few Components can hold other Components; the common ones are:
Form
Panel
GroupBox
NoteBook (Delphi 2)
PageControl
TabSheets

How is the Parent Property used?
Button1 has Panel1 as its Parent, so Button1 INHERITS some of its Properties from Panel1.

i.e. If you change the Font to Bold on the Panel what happens?
Yep the Font changes for Panel1 and Button1.
Wow, that’s what Inheritance is
Button1 Inherits its Font Property from its Parent Panel1.

If you look at a Button’s Properties in the ObjectInspector you will see a Property named ParentFont set to TRUE – If you change this to False, then Button1 will not Inherit its Font from Panel1.

I hope this helps a little.
One point to my readers.
Don’t worry if you don’t understand everything that I say here.
I am jumping around and not explaining(in detail) how and why.

After you work with Delphi a while you will start thinking differently, and you will see the same structures used over and over; then they will become easy and almost trivial.

For all of us MAINLINE (DOS, TP5, C++) programmers that are used to a mainline that loops. Delphi does not have a mainline; or let me say that there is no place for you to work with the mainline.
The mainline is controlled by Windows95 running in the background, processing key hits and mouse movements.

I really don’t miss a mainline; it was a pain anyway.

Delphi is Event driven; that means that nothing happens until something happens (good logic???) (e.g. a key is hit etc.)

New Topic: Delphi’s initial mainline sequence of events:
1) The .dpr program runs, and Creates Forms(and everything on the Forms) – (creating means – memory is allocated for each object)

In Delphi this is called INSTANTIATED (strange word), it just means that the Form is now allocated(uses) RAM memory space.

2) The following Events are called(run)
Form OnCreate => FormCreate( ) // remember they drop the ‘On’ ???
Form OnShow => FormShow( )

3) Then your program waits for the user to do something(Click the mouse,…)

If you want to Initialize some variables, only once, when the program first runs; where do you put the code?

You Initialize vars in the FormCreate( ) Event; since it happens before anything else; and it only happens once.

There are other places to Initialize vars, but FormCreate( ) is all you need for now.
Sender ????

Every Component has Events that are Triggered by the User Clicking the Mouse, Hitting Keys

If you Click on Button1, it calls its:
procedure TForm1.Button1Click(Sender: TObject);
| | | — OnClick Event(they always leave off the On?)
| |
| | — This procedure was called by Button1
|
|- TForm1 is the Parent of Button so it’s (TForm1.Button1)

The Sender(Caller) of this procedure is Button1

You can use the Sender(Parameter) which is of generic type TObject – Everything in Delphi is of type TObjest.

You could have another Component (say an Edit1 Component)use this same procedure for its OnClick Event (because you don’t want to write another procedure for Edit1).

Edit1 is of type TEdit and TObject
Button1 is of type TButton and TObject

So the Sender Parameter sent by Button1 or Edit1 when they are Clicked, can be either a TEdit(from Edit1) or a TButton(form Button1).

That’s why the Sender(param) is defined as a TObject, it can be anything a TButton, TEdit … Get it.

Inside the OnClick procedure you can then determine who called you:
————-

Shared OnClick Event Procedure (used by both Button1 and Edit1)

procedure TForm1.Button1Click(Sender: TObject);
begin
if (Sender is TButton) then Pane1.Color:=clRed \ Click came from Button
else if (Sender is TEdit) then Panel1.Color:=clLime \ Click came from Edit
end;

———————–

Separate OnClick Events

procedure TForm1.Button1Click(Sender: TObject);
begin
Pane1.Color:=clRed
end;
procedure TForm1.Edit1Click(Sender: TObject);
begin
Pane1.Color:=clLime
end;

——

Sender can be a little tricky to use, because it can be multiple things(TButton, TEdit,…).
Later we will get into Databases, then things really get to be fun.
Learning Delphi on your own:

Books with CD’s are a great resource to search for examples of code, for a new component or property that you want to use.

In Win95 Hit START
-Find
-File and Folders
-File Name *.pas
-Containing Text .LOCATE(

This will search all *.pas files for examples that use .LOCATE – Then drop each one of the found files on your editor (WordPad) and search for .LOCATE( and see if it helps you).

It’s a great resource – The Delphi 3 CD also has some good examples that it gives you.

DELPHI NOTE:

Watch out, Delphi is different, your code can fool you.

Say, you want to hit a Button that turns a Panel Red for 3 seconds then turns it to Green

So you write the OnClick event for the Button:

procedure TForm1.Button1Click(Sender: TObject);
begin
Panel1.Color:=clRed;
sleep(3000); // delays 3000 msec
Panel1.Color:=clGreen;
end;

—–

You Run the program, Click the Button; What happens?

Nothing happens for 3 seconds then the Panel turns Green.
What happened to Red.

Hah, I say.

Well guess what, when you are in the Button1Click procedure you do not repaint the Form UNTIL YOU EXIT the procedure.

While you are in the procedure, you see nothing changing on your Form; unless you say the magic words!

Application.ProcessMessages;

procedure TForm1.Button1Click(Sender: TObject);
begin
Panel1.Color:=clRed;
Application.ProcessMessages; // this will repaint your Form
sleep(3000);
Panel1.Color:=clGreen;
end;

—–

Now you hit the Button, the Panel turns Red for 3 seconds, then turns Green.

So, what have we learned form this.

If you are inside a procedure and you want things to change on your Form, so that the user can see them; you have to put: Application.ProcessMessages;

At all the places where you want the Form to change.

This gives you a simple way of doing MULTITASKING in Delphi.
Another way to do simple MULTITASKING (with a Timer):

By the way Delphi can use Threads to do multitasking, but they are a little tricky; and most beginning programmers can use the
-Application.ProcessMessages; technique
-and the Timer technique (that I am about to explain)

A Timer Component, has an INTERVAL Property (with a default setting of 1000 (1 sec)), and an OnTimer Event that is triggered (every 1 second)

Start with a New Application
– Put a Panel1 on your Form
– Put a Timer1 on the Form (it looks like a clock)
– Double Click the (right side of) OnTimer Event in the ObjectInspector

and write the following:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
if Panel1.Color=clRed then Panel1.Color:=clGreen
else Panel1.Color:=clRed;
end;

Run the program. The Panel turns Red then Green every 1 second. So, now you have a mini-mainline that loops every 1 second.

WOWWW!!!
DELPHI NOTE:

You might not know this but ALMOST EVERYTHING in Delphi is a pointer; but you never see the word pointer used anywhere.

It’s all done behind the scenes.

It’s not like C++ or TP with **char @data ^xyz or whatever.

Delphi is beautiful, Delphi is grand

Delphi even has a variable type called a VARIANT that is everything; a char, word, string[3000], real, double, currency, boolean It casts itself into whatever form you need.

e.g.
XVar : variant;

This is all legal:
begin
XVar:=’Frank’; // a string
XVar:=True; // boolean
XVar:=244.34567; // float,real
end;

I might discuss variants later; but I don’t use them or recommend them.

One comment: Database Fields (Table Fields) are variants, that you can cast into other vars:
Table1.FieldByName(‘Cost’).AsCurrency:=125.99; // AsCurrency
Table1.FieldByName(‘Cost’).AsString:=’465.88′; // AsString

We will be discussing Databases in great length.
Change of Topic:

Delphi uses multiple names for floats depending on where you are:
float
real
double
currency
number
money
– and probably more
Power Programming Techniques:

Delphi lets you do Cutting and Pasting of Components, Groups of Components, Forms …
Ctrl X CUT
Ctrl C COPY
Ctrl V PASTE

This can really improve the speed that you program, and saves a lot of busy work.

So, experiment with Cutting and Pasting and learn how to use it. What it does and doesn’t do.
Put a Button on a Form, and copy it(^C, ^V)

Also, try adding another Unit to your Project.
-Project Mgr (on Toolbar)
– Add
– Select Folder/File Name
-Open

Then link the 2 Units together by adding:
in Unit1 (after Implementation)
uses Unit2;

in Unit2(after Implementation)
uses Unit1;

Now in Unit1, you can call procedures in Unit2:
Form2.Panel1.Color:=clRed;

What is going on?

I told Unit1 to use Unit2; why don’t I call stuff in Unit2 as:
Unit2.Panel1.Color:=clRed; // WRONG

You DON’T, you call stuff in Unit2 by referencing Unit2’s Form (Form2). That’s Delphi.
Form2.Panel1.Color:=clRed; // CORRECT
Note: WATCH OUT

When you Add Unit2 to your project, Delphi DOES NOT make a copy of Unit2.

Delphi has a path to the original Unit2 and any changes you make to Unit2 will change the original. OOOPs GOT YA!! (that’s why its called OOP programming! Aha)

How do I work with a copy of Unit2 and not the original?

2 ways:
1)-File (while viewing Unit2)
-Save As
-Change Folder and save Unit2 in your Project Folder.

2) Before you start, you copy Unit2.pas and Unit2.dfm to your Project Folder.
(This is the BETTER WAY)
Also, you can create your own Components and put them on your Component Palette, without writing any code.

These are called COMPONENT TEMPLATES

THIS ONE IS GREAT
—————–

Blank Form
Add a Panel
Put some Buttons on the Panel
Point to the Panel
-Component(Menu)
-Create Component Template
-Change COMPONENT NAME to P1
-OK

Look at your Component Palette (Standard Tab)
You now have a NEW Component named P1
Click on P1 (on Palette)
Put P1 on Form
My God, it works!!!

One thing though:

When you create a COMPONENT TEMPLATE you only get the graphic Components copied.
If you had Buttons with OnClick Events (in code).

The OnClick Events(code) are NOT part of the New Component P1; only the Objects(Panel1,Button1,Button2) are part of P1.

Anyway, this is a great way to build up a Library of groups of Components, that you can easily reuse; its on your Palette.
COPYING A FORM TO THE REPOSITORY

Create a New Form, put on Buttons, Panels
Right Click on the Form
-Select ADD TO REPOSITORY
-Enter a TITLE (e.g. TEST1)
-OK

Now goto Menu
-File
-New
-Forms(Tab)

You will see a Selection TEST1
Double Click on it

WOW!!!

Now you have a simple way to save entire Forms, and reuse them.
Remember Delphi is complicated because there are so many choices.

What I want these Lessons to give you, is a way to simplify your choices; knowing which ones are important and which are not.

When you look at the ObjectInspector for a Button, you will see 24 Properties. You normally only use or change, 4 or 5 of these Properties. But Delphi shows you 24. So for the new programmer it’s a little overwhelming.

When you’re done with this course, you should get a feel for the core (or essence or flavor) of Delphi.

Now, when you look at the ObjectInspector, you only see the Properties that have any meaning for you.

Later on, if I have time; I will try and clean up my Library of code snippets, and sample programs and send them to you.

That’s it for now.

I hope these Ramblings have given you a better understanding of how to use Delphi’s power. This first Lesson is more about Delphi itself, so sample programs are not very useful yet.

The next Lesson (Lesson 2) will be More Delphi Stuff
Lesson 3 will be DATABASES,
Lesson 4 will be STRINGS and CONVERSION ROUTINES

Have fun, and keep reading your Delphi books.
Also, Please give me some feedback.
What you like and don’t like about my Rambling format?
What you learned, what you don’t understand?
All comments are appreciated.

Remember to EMAIL me back to receive more Lessons.

Frank Fortino

Reproduced with the kind permission of Frank Fortino.

Comments