For Pascal programmers, who never created GUI applications, in particular all those, who in their young years developed Turbo Pascal command line programs, starting
to work with a RAD tool like Lazarus may be confusing. When working with Turbo Pascal, you normally had a main source file (extension .pas), and possibly one or more
units (also with extension .pas, or maybe .pp). Building the program consisted in running the compiler using the main Pascal source file as input, the result being
an executable (.exe on Windows).
|
Working with Lazarus is all different. You do not compile individual Free Pascal source files, but you build a Lazarus/Free Pascal project.
Thus, whatever kind of application you want to create (GUI application, command line program, DLL), it always start with creating a new project, what is done by
choosing File > New... from the menu bar. This opens a new window, where you can select what kind of project you want to build.
|
|
A project normally groups all files relative to a given task. Mostly this will be one single Free Pascal GUI application. In any case, you should always
create a separate directory for each project (this is called the project directory) and keep
all files being part of this project in this directory. This is not mandatory, but first, it's just logical to keep together what belongs together, and second,
having files of a given project in several directories may quickly become messy.
|
Note: If you have forms or code-only units, that you use in different projects, I would highly recommend to save them in every
project directory, where they are used. Even though this requires to change several files, if you change the form or unit, having all together in one same directory
helps to avoid problems such as files not found, or files with duplicate names. For help, how to use an existing project as template for a new project, how to use an
existing form (as such, or as template) in a new project, and how to add an existing unit to a new project, please, have a look at my tutorial
Creating a Lazarus project using existing resources.
|
The first time that you save your project (by clicking either the "Save", or the "Save All" icon in the Lazarus icon bar, you'll be asked for two filenames:
- The project filename, creating a Lazarus Project Information (.lpi) file.
- The main unit filename, creating a Free Pascal Source (.pas) file.
|
You should use "real" file names (not the defaults), and it is mandatory that the two names are different. I normally give my project the same name as the project
directory, and mostly use a suffix, such "_u1", or "_main" to name the unit. Consider a GUI application that we want to be called "Test". First, we create a new
subdirectory, called "Test" in the Lazarus development directory (or your Documents folder, or where ever). Then, we create a new Lazarus application project, and
save the project as "Test.lpi" and the main unit (the unit that opens in the Lazarus editor, and where we enter the program logic source code) as "test_main.pas",
for example. Note, that when building the project, we will create an executable, that on Windows will be called "Test.exe" (the name of the executable, created by
the build, will be identical to the project name, not to the main unit name).
|
If, after having saved the project and the main unit, you have a look at the project directory, you'll find not only these two files, but several others.
|
|
The Lazarus Information file (.lpi) (in our case: Test.lpi) may be called a project file, because it contains project-specific settings
like the compiler settings, the needed packages, and the units that are part of the project. This file, in XML format, should not be
modified by the programmer!
|
The Lazarus Project Main Source file (.lpr) contains the Free Pascal source code of the main program. It has the same name as the Lazarus
Information File (in our case: Test.lpr), and may be loaded into the Lazarus editor, using the menu command Project > View project source.
It's the compilation of this file that will constitute the main program part of the executable (thus, the executable will be called Test.exe). Its primary program
logic consists in creating the forms, that are part of the application, and starting the application (i.e. displaying the main form). Normally, you have not to care
about this file (I just edit it, adding some comment describing the application). On the screenshot below, note the inclusion of the unit
"test_main", the main unit of our project.
|
|
The Lazarus Project Session file (.lps) contains the session data, i.e. it stores what you did during the last time you opened the project
(the personal data stored includes, for example, cursor positions, source editor files, and personal build modes). This file, with the same name as the project
(in our case: Test.lps) and in XML format, is not needed to build the project (thus, no need to be included in Version Control System); its only purpose is for
programmer convenience during development.
|
The Lazarus resource file (.res) is generated by Lazarus and contains the instructions to the program for building the form. This is a
binary file, with the same name as the project (in our case: Test.res). The content of this file is loaded by the main program; look at the content of Test.lpr,
where you find the line
{$R *.res}
|
The icon file (.ico) is the icon graphics file, that is used as icon for the application executable. It has the same name as the project
(in our case: Test.ico).
|
The Free Pascal source code file (.pas) contains the Free Pascal source code of the main unit, i.e. the source code of our program logic.
As we saw above, this file is named by the programmer, when saving the project for the first time (in our case: test_main.pas). This file is always opened in the
Lazarus editor. The screenshot shows the content of test_main.pas, after the creation of the project (automatically generated code; no custom code yet added).
|
|
The Lazarus Form file (.lfm) contains the form configuration information for all objects on the main form. The information is stored in a
Lazarus-specific textual format. This file has the same name as the Free Pascal source code file (in our case: test_main.lfm). The form components and their properties
are part of test_main.lfm; the form events (and all actions taken by the program) are part of test_main.pas. If you have a look at the content of test_main.pas,
you'll find the line
{$R *.lfm}
that loads the form configuration information. The Lazarus Form file is created by Lazarus when the programmer creates form components or sets the components'
properties. The programmer should not manually change this file!
|
Adding a second form.
|
To add another form to the project, choose File > New form from the menu bar. When saving the project, we are asked for the name of the
new Free Pascal unit associated with the new form. The name must, of course, be different from the name of the main unit, as well as from
the name of the project. Example: test_u2.pas.
|
If, after having saved the project, we have a look at the project directory, we'll find two new files: a Free Pascal source code file (test_u2.pas) and a Lazarus
Form file (test_u2.lfm).
|
|
Adding a second form automatically modifies the content of the Lazarus Project Main Source File (Test.lpr). You can see on the screenshot that test_u2.pas has been
added to the units to be included. And in the code part, the instruction to create the second form has been added.
|
|
Adding a code-only unit.
|
To add a code-only unit (unit that is not associated with a form), choose File > New unit from the menu bar. When you save the project,
you will be asked for the file name, that has, of course to be different from the names of the existing file; examples: u3.pas, common.pas. The Lazarus Project
Main Source file is automatically updated, the name of the unit added to the uses clause.
|
Form component, subroutine and variable names.
|
The default name of the main form (the component) is "Form1", and the form is declared as an instance of the class "TForm1", based on
"TForm" (cf. screenshot showing the code of the "test_main" unit. It's not mandatory to give the from another name, but I should suggest to do so. You do it by
setting the "Name" property of the form component to a new value. I guess that you see that the component name has nothing to do with the name of the .lfm file,
and that you cannot use the filename as new name for the component (because a unit with that name already exists). Neither can you use the project name (because
this identifier is already used as program name in Test.lpr). And globally, you can't use a name that is already in use: unit name, variable name, subroutine name,
component name, component property name. I normally use the name of the project with the prefix "f" (for "form"). So, I would call the main form "fTest". Doing
so, automatically changes the class name to "TfTest" (as name for the second form, I would choose something in relationship with what the form does; ex: "fHelp",
if the form is used to display the application help). The screenshot below shows the code of test_main.pas, after having changed the name of the form.
|
|
The form components are created by the user if form design view, i.e. by drag-and-drop of the component icon from the components bar to the form. Default names are
automatically assigned to the components, normally the component name plus an integer, incremented with each same component created. Thus, labels will be named
Label1, Label2, etc, edit fields will be named Edit1, Edit2, etc. There is no reason to change the default names for components that are not used in the program
logic of the source code. On the other hand, you should always rename the components that are used within the code. Two important points when renaming form
components:
- Always rename the form components by changing their "Name" property in the
Properties sheet, not by changing the source code (this will be automatically done).
- Make sure that the names, that you use, are unique.
|
Unique component names means that the name that you give to the component isn't already used to name some other identifier. Obvious, that you can't use a name that
is already used for another component. Neither can you use it if it is already used for a variable. A point that you may perhaps not immediately be aware of:
when naming a component, you cannot use a name that is used to designate a property of this component!
|
The screenshot below shows the build failure due to duplicate identifier names. I had created an edit filed on the second form of our example
project, and named it "Name" (just think that we want the user to enter their name in this field). The edit field will be created with this name, but when compiling,
the error Duplicate identifier "Name" will result in the abortion of the build. The reason is given with the error message: "Identifier"
already defined in unit CLASSES". In fact, our TfTest object fTest has a property called "Name", and now we try to name the edit field (that is a component of fTest),
using an already existing identifier name. This cannot work, of course!
|
|
The same error occurs if you try to give a component a name, that you already have used in a variable declaration. Ex: If you have declared a private variable
"Firstname" (as a string, for example), you cannot name the edit field, where the user should enter their first name, "Firstname"...
|
A good practice consists in prefixing form component names. This not only makes the code easier to understand, but also helps to avoid
dulpicate names. Thus, all my edit fields start with "ed", all buttons with "bt", etc. Naming the edit fields in the above examples "edName" resp. "edFirstname" will
prevent the compilation error due to duplicate names.
|
As you can prefix components names, you can also prefix variable names. For example, start all integer variables with "i", all string
variables with "s" ("sFirstname" for our string variable). Again, this makes the code easier to read, and helps to avoid duplicate identifier errors.
|
Note that, on a second form, you can use component names that you have already used on the main form. Thus there is no problem to have an edit field called
"edFirstname" on both the main and the second form. It's even possible to access the edit field on the second form from the main unit. Supposing that the second
form is named "fForm2", use the notation fForm2.edFirstname. Note that this is also necessary if you want to access a form component
or variable in a function or procedure, declared "outside the form class". And finally, this notation makes it possible to call a given function or procedure,
if your program includes 2 units, with subroutines with the same name in both units.
|