Lazarus For Delphi Users/fr

From Lazarus wiki
Jump to navigationJump to search

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) 한국어 (ko) português (pt) русский (ru) slovenčina (sk)

Cette description est pour les personnes qui sont intéressées par Lazarus et connaissent déjà Delphi. Il décrit les différences entre les deux .

Delphi -> Lazarus

Lazarus est un outil de développement rapide d'applications (rad) comme Delphi. Cela signifie qu'il vient avec une bibliothèque de composants visuels et un IDE. La bibliothèque de composant de Lazarus (LCL) est très semblable à la VCL de Delphi. La plupart des unités, classes et propriétés ont le mêmes noms et fonctionnalitées. Ceci rend le portage aisé . Mais Lazarus n'est *pas* un 'clone open source de Delphi'. Ainsi ne vous attendez pas à 100% de compatibilité.

Les plus grandes différences

Lazarus est complètement open source, est une plate-forme écrite indépendante et utilise le puissant compilateur Free Pascal (FPC). FPC s'exécute sur plus de 15 plate-formes. Mais pas tous les paquets et bibliothèques sont portés, ainsi Lazarus actuellement s'exécute sur Linux (i386, x86_64), FreeBSD (i386), MacOSX (powerpc, i386) et Windows (i386, x86_64).

Lazarus n'est pas complet et, à ce propos, ce texte non plus. Nous recherchons toujours de nouveaux developpeurs, créateurs de paquets, réalisateurs de portages, auteurs de documentation , ... .

La première chose à faire en convertissant un projet Delphi

Après avoir ouvert Lazarus, vous devriez aller à Outils et puis Convertir un projet Delphi en projet Lazarus... . Ceci ne fera pas tout pour vous, mais néanmoins vous permettra de faire une bonne partie du chemin.

Delphi IDE -> Lazarus IDE

Projets

Le fichier principal d'une application Delphi est le fichier .dpr. Le fichier principal d'un projet Lazarus est le fichier .lpi (Lazarus Project Information). Un fichier .dpr est la source principale du programme et l'IDE Delphi stocke quelques informations sur les options et les unités du compilateur. Une application Lazarus a aussi un fichier .lpr, ce qui est également le fichier source principal. Mais toute autre information est stockée dans le fichier .lpi. Ainsi, le fichier important est le fichier .lpi.

Par exemple :

Delphi stocke les chemins des unités dans le fichier .dpr . Par exemple : unit1 in 'path/Unit1.pas'. Ces chemins 'in' sont spécifiques à Delphi et ne sont pas lus par l'IDE Lazarus. Ne pas les employer. Utiliser à la place les chemins d'unité dans les options du compilateur.

Delphi stocke les options du compilateur dans le fichier .dpr. Par exemple {$APPTYPE CONSOLE}. Ceux-ci sont ignorés par l'IDE Lazarus. Ne pas les employer. Employer à la place les options de compilateur .


Une règle importante : Il y a toujours un projet . La seule manière de "fermer" un projet est de quitter lazarus ou ouvrir un autre projet . C'est parce qu'un projet Lazarus est également une "session". Ceci signifie que, les paramètres courant de l'éditeur sont également stockés dans le fichier .lpi et sont restaurés quand vous réouvrez le projet. Par exemple : vous deboggez une application, placez beaucoup de points d'arrêts et de signets . Vous pouvez enregistrer le projet à tout moment , fermer lazarus ou ouvrir un autre projet . Quand vous réouvrez le projet , même sur un autre ordinateur , tous vos points d'arrêts , signets , fichiers ouverts, positions de curseur , historique de sauts, ... sont restaurés .

Editeur de Sources

Presque toutes les clefs et les raccourcis peuvent être définis dans configuration->options de l'editeur->Assignation des touches

L'IDE Lazarus a beaucoup d'outils pour des sources. Bon nombre d'entre eux semblent et travaillent de façon similaire à Delphi. Mais il y a une différence importante : Lazarus n'emploie pas le compilateur pour obtenir de l'information sur le code . Il analyse les sources directement . Ceci a beaucoup d'avantages importants :

L'éditeur de sources travaille avec des "commentaires ". Pour Delphi les commentaires dans la source sont juste des espaces entre le code . Aucune fonctionnalité du code ne fonctionne là et quand du nouveau code est automatiquement insérée, vos commentaires vont bouger. Sous Lazarus vous pouvez faire une recherche de déclaration même sur du code dans des commentaires. Bien que ce ne soit pas complètement fiable , ça marche souvent. Et quand du nouveau code est inséré, l'IDE emploie de l'heuristique pour garder le commentaire et pour le code ensemble . Par exemple : Il ne dédoublera pas la ligne "c: char; // comment".

"La complétion de code" de Delphi (Ctrl+Space) est appelée "Complétion d'identificateur" sous Lazarus. Le terme Lazarus de "Completion de code" est une fonctionnalité, combinant "Completion de classe automatique" (mêmes que sous Delphi), "Completion de variable locale" et "Completion d'affectation d'évènement". Tous sont invoqués par Ctrl+Shift+C et l'IDE détermine par la position du curseur, ce que cela signifie.

Exemple de completion de variable locale

Supposer que vous avez juste créé une nouvelle méthode et avez écrit l'instruction "i:=3;" <delphi>procedure TForm1.FaireQuelqueChose;

begin
 i := 3;
end;</delphi>

Placer le curseur au-dessus de l'identificateur "i" et appuyez sur Ctrl+Shift+C pour obtenir: <delphi>TForm1.FaireQuelqueChose;

var
  i: Integer;
begin
 i := 3;
end;</delphi>

Exemple de completion d'assignation d'évènement

Un fonctionnalité interessante de l'inspecteur d'objet est de créer automatiquement des méthodes. La même que vous pouvez obtenir dans l'éditeur de sources.
Par exemple : <delphi> Button1.OnClick :=</delphi> Placer le curseur derrière l'opérateur d'assignation ":=" et appuyez sur Ctrl+Shift+C.

"Complétion de mot" Ctrl+W

Cela fonctionne de façon semblable à la "Complétion d'identificateur", mais il ne fonctionne pas avec les identificateurs Pascal, mais sur tous les mots. Il vous laisse choisir de tous les mots dans tout les fichiers ouverts ceux commencant par les mêmes lettres.

Supporte les fichiers Include

Delphi ne les supportait pas, et ainsi vous n'avez probablement pas encore créé beaucoup de fichiers include. Mais les fichiers include ont un grand avantage: Ils rendent possible l'écriture de code indépendant de la plate-forme sans salir votre code avec des IFDEF. Par exemple : Saut de méthode , Completion de Classes, recherche de déclaration, .. tout fonctionne avec des fichiers include.

Il y a beaucoup d'options pour les fonctionnalités du code.

Concepteur

- Directives

Inspecteur d'objet

In the Delphi and Lazarus IDE's the Object Inspector is used to edit component properties and assign events etc. The following are a few minor differences to note in use :

  1. Starting in Delphi 5 there is an Object Treeview which can be used to navigate and select objects according to hierarchy in addition to the traditional drop down list in the Object Inspector. In Lazarus this is part of the Object Inspector and is used in place of the default drop-down, you can select to use/not use it from the right click menu with "Show Component Tree"
  2. In Delphi double clicking on a blank event will auto create one and open the Source Editor to that position, in Lazarus there is a button to the right of the selected drop-down which performs this action instead.
  3. In Delphi you must manually delete the name of an event in the edit to remove the attatchement, in Lazarus you can drop down and select "(None)".
  4. Similarly to Events, double clicking regular properties such as boolean will not change the value, you must select it from a drop down. And to open those with an assigned editor form, you must click the '...' button to the right of the edit/drop-down

Packages

Can Lazarus install and use Delphi Packages?

No, because they require Delphi compiler magic.

Do we need ones specially made for lazarus?

Yes. Create a new package, save it in the package source directory (normally same directory of the .dpk file), add the LCL as required package and finally add the .pas files. You can install it, or use it in your projects now. There are some differences between Lazarus and Delphi packages, so please read

- see docs/Packages.txt in the lazarus sources.

VCL -> LCL

While the VCL and the LCL both serve much of the same purpose - of an Object Oriented Component Hierarchy especially geared toward rapid application development, they are not identical. For instance while the VCL provides many non-visual components, the LCL tries to only provide visual, while most non-visual components (such as db access) are provided by the FCL, included with Free Pascal .

Additionally many controls may not exist in the LCL that are in the VCL, or vice versa, or even when controls do exist in both, they are not clones, and changes must be made in applications, components and controls if porting.

The following is an attempt to provide fairly complete descriptions of major differences or incompatiblities between the two for the Delphi user. It covers differences primarily with the VCL of D4 especially, though at times D5, D6, or D7 as well; and with the current LCL, as is in CVS. As such it may not always be accurate to the version of Delphi you are used to, or completely match the current LCL you have. If you see inacuracies between the following and the LCL as in CVS, or your Delphi feel free to append and modify so as to keep this as comprehensive as possible for all people.

TControl.Font/TControl.ParentFont

In the VCL it is quite common and normal to use a specific font name and font properties such as bold and italics for controls, and expect this value to always be followed. Further is provided the TControl.ParentFont property which ensures that a control will always follow its parent's font. Again the implicit assumption being that these values will always be followed, even regardless of Windows Apearance Settings.

This is not always true in the LCL, nor can it be. The LCL being cross-platform/cross-interface in nature prefers to take a balanced aproach, and instead will always try to use native Desktop/Toolkit Apearance or Theme settings on any widgets. For example if using a GTK interface, and the gtk theme supplies a specific font for buttons, then LCL buttons will always try to use this font.

This means that most LCL controls do not have the same level of design control that is often expected in the VCL, rather only those custom controls which are Canvas drawn instead of interface allocated can consistantly be modified in this manner regardless of the Interface used.

Control Dragging/Docking

In the VCL most (Win)Controls implement methods and callback functions for handling dragging and docking of controls, eg. dragging a control from one panel, and docking it onto another panel at run time.

This functionality is currently unimplimented/unfinished in the LCL, though it is currently in the initial stages of planning, and should eventually support some level of compatibility for this type of behaviour, if not in the exact same manner.

This currently means that no Control will inherit/use the following TControl functions, procedures, properties, or events

<delphi>Protected

function  GetDockEdge(MousePos: TPoint): TAlign;
function  GetDragImages: TDragImageList;
function  GetFloating: Boolean;
function  GetFloatingDockSiteClass: TWinControlClass;
procedure DoEndDrag(Target:TObject); X, Y: Integer);
procedure DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);
procedure DoEndDock(Target: TObject; X, Y: Integer);
procedure DoDock(NewDockSite: TWinControl;var ARect: TRect);
procedure DoStartDock(var DragObject: TDragObject);
procedure DragCanceled;
procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;var Accept: Boolean);
procedure DoEndDrag(Target: TObject; X, Y: Integer);
procedure DoStartDrag(var DragObject: TDragObject);
procedure DrawDragDockImage(DragDockObject: TDragDockObject);
procedure EraseDragDockImage(DragDockObject: TDragDockObject);
procedure PositionDockRect(DragDockObject: TDragDockObject);
procedure SetDragMode(Value: TDragMode);
property  DragKind: TDragKind;
property  DragCursor: TCursor;
property  DragMode: TDragMode;
property  OnDragDrop: TDragDropEvent;
property  OnDragOver: TDragOverEvent;
property  OnEndDock: TEndDragEvent;
property  OnEndDrag: TEndDragEvent;
property  OnStartDock: TStartDockEvent;
property  OnStartDrag: TStartDragEvent;

Public

function  Dragging: Boolean;
function  ManualDock(NewDockSite: TWinControl; DropControl: TControl;ControlSide: TAlign): Boolean;
function  ManualFloat(ScreenPos: TRect): Boolean;
function  ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;DropControl: TControl; ControlSide: TAlign): Boolean;
procedure BeginDrag(Immediate: Boolean; Threshold: Integer);
procedure Dock(NewDockSite: TWinControl; ARect: TRect);
procedure DragDrop(Source: TObject; X, Y: Integer);
procedure EndDrag(Drop: Boolean);
property  DockOrientation: TDockOrientation;
property  Floating: Boolean;
property  FloatingDockSiteClass: TWinControlClass;
property  HostDockSite: TWinControl;
property  LRDockWidth: Integer;
property  TBDockHeight: Integer;
property  UndockHeight: Integer;
property  UndockWidth: Integer;</delphi>

that the following classes do not exist/are unuseable -

<delphi> TDragImageList = class(TCustomImageList)

TDockZone = class
TDockTree = class(TInterfacedObject, IDockManager) 
TDragObject = class(TObject) 
TBaseDragControlObject = class (TDragObject) 
TDragControlObject = class (TBaseDragControlObject) 
TDragDockObject = class(TBaseDragControlObject)</delphi>

and that the following functions are also unuseable/incompatible -

<delphi>function FindDragTarget(const Pos: TPoint;AllowDisabled: Boolean) : TControl; procedure CancelDrag; function IsDragObject(sender: TObject): Boolean;</delphi>

TEdit/TCustomEdit

The Edit controls, while functioning essentialy the same in the LCL as the VCL, do have some issues to be aware of in converting -

  1. Due to restrictions in the Interfaces, TEdit.PasswordChar does not work in all interfaces yet(though in time it may), instead TCustomEdit.EchoMode emPassword should be used in the event text needs to be hidden.
  2. On Drag/Dock Events are not yet implemented. For more information please see earlier section on Control Dragging/Docking.
  3. Font Properties are usually ignored for interface consistancy, for detailed explanation as too why please see TControl.Font/TControl.ParentFont

(optional) TSplitter -> TPairSplitter

Please Improve Me

There is now a TSplitter control in the LCL, so no need to convert it.

Nevertheless, if you want, here it is explained:

The following is loosely based on questions by Vincent Snijders on the mailing list, and responses by Andrew Johnson:

In the VCL, "Splitting" controls, that is a handle which can be dragged between two components to give one more or less space then the other, is accomplished by a TSplitter. This is often seen, for instance in the Delphi IDE between the docked Code Explorer and Source Viewer.

The LCL provides its own Control called a TPairSplitter, which serves the same type of purpose, however it is not compatible, so "repairing" broken VCL code or Delphi DFM's will be necesary in the event of porting code, even though much is shared in common between the two.

So what exactly are the differences?

Well the biggest differences are a VCL TSplitter has no children, instead it is placed between two controls aligned properly, and allows resizing between them at runtime, regardless its own size. It must have two controls aligned on each size to do anything. A simple example would be form with a Left Aligned Panel, a left aligned Splitter, and a second client aligned panel. On run time you could then realign the size given each panel by dragging on the handle provided by this Splitter control.

On the LCL hand however, a TPairSplitter is a special kind of control, with two panels, and it can only be usefull if the controls to split are on these panels, but it will still perform a split between those panel whether or not anything is on them. So following the prior example, you would have a form with a TPairSplitter aligned client, and a panel aligned client on its left side, and a panel aligned client on its right side.

The other important difference is that in the VCl, since the TSplitter is its own TControl, then the position is kept relative to the other controls on resize, so for instance a client panel will grow while the other panels will not, thus the split position is relative to the alignment of the split controls,

In the LCL since the side panels are separate then the TPairSplitter has a Position property which is absolute relative to top or left. so on resize the actual position does not change according to contents, so a callback must be set to ensure the ratio is kept on resize if this is important.

For example if the Right side of a vertical split needs to have alClient like behaviour, you need to add a form resize callback which does something like :

PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; 
So how can I convert existing code using TSplitter to the TPairSplitter?

If the splitter and controls are created within an actual function(like form oncreate), conversion shouldn't be too difficult, primarily reorganize the code to create the controls in order of new hierarchy and set the parents of the child controls to split to the left/top and right/bottom portions of the PairSplitter. An example of the changes being -

VCL LCL
var
BottomPanel: TPanel
;
VerticalSplitter: TSplitter
;
LeftPanel: TPanel
;
HorizontalSplitter: TSplitter
;
MainPanel: TPanel
;
begin
BottomPanel:= TPanel.Create(Self)
;
with
(BottomPanel)
do
begin
Parent:= Self
;
Height:=
75
;
Align:= alBottom
;
end
;
VerticalSplitter:= TSplitter.Create(Self)
;
with
(VerticalSplitter)
do
begin
Parent:= Self
;
Align:= alBottom
;
end
;
HorizontalSplitter:= TSplitter.Create(Self)
;
with
(HorizontalSplitter)
do
begin
Parent:= Self
;
align:= alLeft
;
end
;
LeftPanel:= TPanel.Create(Self)
;
with
(LeftPanel)
do
begin
Parent:= Self
;
Width:=
125
;
Align:= alLeft
;
end
;
MainPanel:= TPanel.Create(Self)
;
with
(MainPanel)
do
begin
Parent:= Self
;
Align:= alClient
;
Caption:=
'Hello'
;
end
;
end
;
var
BottomPanel: TPanel
;
VerticalSplitter: TPairSplitter
;
LeftPanel: TPanel
;
HorizontalSplitter: TPairSplitter
;
MainPanel: TPanel
;
begin
VerticalSplitter:= TPairSplitter.Create(Self)
;
with
(VerticalSplitter)
do
begin
Parent:= Self
;
Align:= alClient
;
Width:= Self.Width
;
Height:= Self.Height
;
SplitterType:= pstVertical
;
Position:= Height -
75
;
Sides[
0
].Width:= Width
;
Sides[
0
].Height:= Position
;
end
;
HorizontalSplitter:= TPairSplitter.Create(Self)
;
with
(HorizontalSplitter)
do
begin
Parent:= VerticalSplitter.Sides[
0
]
;
Width:= Self.Width
;
Height:= VerticalSplitter.Position
;
align:= alClient
;
SplitterType:= pstHorizontal
;
Position:=
125
;
end
;
LeftPanel:= TPanel.Create(Self)
;
with
(LeftPanel)
do
begin
Parent:= HorizontalSplitter.Sides[
0
]
;
Align:= alClient
;
end
;
MainPanel:= TPanel.Create(Self)
;
with
(MainPanel)
do
begin
Parent:= HorizontalSplitter.Sides[
1
]
;
Align:= alClient
;
Caption:=
'Hello'
;
end
;
BottomPanel:= TPanel.Create(Self)
;
with
(BottomPanel)
do
begin
Parent:= VerticalSplitter.Sides[
1
]
;
Align:= alClient
;
end
;
end
;

So as you can see, farely consistant with most control hierarchy. And if you are familiar with DFM's, the changes needed for DFM->LFM conversion should be farely obvious from the above, as they are the same sort of changes in Parent/Owner etc.

So the above example would be something like -

Delphi DFM
(extraneous values removed)
Lazarus LFM
(most width, height, etc. removed)
object
VerticalSplitter: TSplitter Height
=
3
Cursor
=
crVSplit Align
=
alBottom
end
object
HorizontalSplitter: TSplitter Width
=
3
Align
=
alLeft
end
object
BottomPanel: TPanel Height
=
75
Align
=
alBottom
end
object
LeftPanel: TPanel Width
=
125
Align
=
alLeft
end
object
MainPanel: TPanel Align
=
alClient
end
object
VerticalSplitter: TPairSplitter Align
=
alClient SplitterType
=
pstVertical Position
=
225
Height
=
300
Width
=
400
object
Pairsplitterside1: TPairSplitterIde
object
HorizontalSplitter: TPairSplitter Align
=
alClient Position
=
125
object
Pairsplitterside3: TPairSplitterIde Width
=
125
object
LeftPanel: TPanel Align
=
alClient Width
=
125
end
end
object
Pairsplitterside4: TPairSplitterIde
object
MainPanel: TPanel Align
=
alClient
end
end
end
end
object
Pairsplitterside2: TPairSplitterIde
object
BottomPanel: TPanel Align
=
alClient Height
=
75
end
end
end

TCustomTreeView/TTreeView

Both VCL and the LCL provide a TCustomTreeView/TTreeView component, used for tree structured lists of data with multiple nodes and advanced selection and Image lists, and while actual features are comparable, not all properties are entirely compatible. Primary differences are as follows -

Incomplete list, also update to include TCustomTreeView Mark functions and protected methods

  1. The LCL provides a TCustomTreeView.Options, a set of options which can be set on the control to change its behaviour and apearance. These options are :
    • tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL
    • tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand
    • tvoAutoInsertMark - Update the Drag preview on mouse move.
    • tvoAutoItemHeight - Adjust the item heights automatically.
    • tvoHideSelection - Do not mark the selected item.
    • tvoHotTrack - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack
    • tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes
    • tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly
    • tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
    • tvoRowSelect - allow selecting rows, equivalent to enabling TCustomTreeView.RowSelect
    • tvoShowButtons - show buttons, equivalent to enabling TCustomTreeView.ShowButtons
    • tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
    • tvoShowRoot - show root note, equivalent to enabling TCustomTreeView.ShowRoot
    • tvoShowSeparators - show seperators
    • tvoToolTips - show tooltips for individual nodes
  2. The LCL provides additional properties:
    • TCustomTreeView.OnSelectionChange event
    • TCustomTreeView.DefaultItems, for the default number of Items
    • TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
  3. While most On Drag/Dock Events are available in the LCL they do not work. For more information please see earlier section on Control Dragging/Docking.

Messages / Events

The order and frequency of messages and events (OnShow, OnActivate, OnEnter, ...) differ from the VCL and depend on the widgetset. The LCL provides a subset of WinAPI like messages to make porting of Delphi components easier, but almost all LCL messages work a little bit different than the VCL/WinAPI counterpart. The biggest part of Delphi code using WinAPI messages uses them, because the VCL lacks a feature or for speed reasons. Such things will seldom work the same under the LCL, so they must be checked manually. That's why LCL messages are called for example LM_SIZE instead of WM_SIZE (unit lmessages).

Original Contributors and changes

This page has been converted from the epikwiki version.

  • Initial import and formatting - VlxAdmin 9/26/2003
  • Begin VCL -> LCL with a section on TSplitter -> TPairSplitter - Andrew Johnson 9/30/2003
  • Add TControl.Font/TControl.ParentFont to VCL -> LCL - Andrew Johnson 9/30/2003
  • Update TEdit/TCustomEdit section in VCL -> LCL - Andrew Johnson 10/1/2003
  • Add Control Dragging/Docking to VCL -> LCL - Andrew Johnson 10/1/2003
  • Added "Object Inspector" to Delphi IDE -> Lazarus IDE - Andrew Johnson 10/1/2003
  • Added initial "TCustomTreeView/TTreeView" to VCL -> LCL - Andrew Johnson 10/1/2003
  • Added introduction to VCL -> LCL - Andrew Johnson 10/1/2003
  • Fixed some typos - Vincent 10/2/2003
  • Fixed Typo User:Kirkpatc 20 May 2004

See Also

Code Conversion Guide (from Delphi & Kylix)

Compile With Delphi