Difference between revisions of "Lazarus For Delphi Users/fr"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting; deleted category included in page template)
 
(12 intermediate revisions by 3 users not shown)
Line 12: Line 12:
  
 
=== La première chose à faire en convertissant un projet Delphi  ===
 
=== La première chose à faire en convertissant un projet Delphi  ===
Après avoir lancé Lazarus, vous devriez aller dans '''Outils'''/'''Convertir un projet Delphi en projet Lazarus... '''.  Ceci ne fera pas tout à votre place, mais vous permettra néanmoins de faire une bonne partie du chemin.
+
Après avoir lancé Lazarus, vous devriez aller dans '''Outils'''→'''Convertir un projet Delphi en projet Lazarus... '''.  Ceci ne fera pas tout à votre place, mais vous permettra néanmoins de faire une bonne partie du chemin.
  
 
== Delphi IDE → Lazarus IDE ==
 
== Delphi IDE → Lazarus IDE ==
Line 20: Line 20:
 
Par exemple :
 
Par exemple :
  
Delphi stocke les chemins des unités dans le fichier .dpr (ex. : unit1 in 'path/Unit1.pas'). Ces chemins précédés de 'in' sont spécifiques à Delphi et ne sont pas lus par l'IDE de Lazarus. Il ne faut pas les utiliser. À la place, les chemins des unités sont à définir dans "Projet/Options du compilateur...".
+
Delphi stocke les chemins des unités dans le fichier .dpr (ex. : unit1 in 'path/Unit1.pas'). Ces chemins précédés de 'in' sont spécifiques à Delphi et ne sont pas lus par l'IDE de Lazarus. Il ne faut pas les utiliser. À la place, les chemins des unités sont à définir dans "Projet→Options du compilateur...".
  
Delphi stocke les options du compilateur dans le fichier .dpr. Par exemple  {$APPTYPE CONSOLE}. Les options définies de cette façon sont ignorées par l'IDE de Lazarus. Il ne faut pas les utiliser, et définir à la place les options dans "Projet/Options du compilateur...".
+
Delphi stocke les options du compilateur dans le fichier .dpr. Par exemple  {$APPTYPE CONSOLE}. Les options définies de cette façon sont ignorées par l'IDE de Lazarus. Il ne faut pas les utiliser, et définir à la place les options dans "Projet→Options du compilateur...".
  
  
 
Règle importante : il y a ''toujours '' un projet ouvert. Les seules façons de "fermer" un projet sont, soit de quitter Lazarus, soit d'ouvrir un autre projet. C'est parce qu'un projet Lazarus est également une "session". Ceci signifie que les paramètres courants de l'éditeur sont également stockés dans le fichier .lpi et sont restaurés quand vous réouvrez le projet. Par exemple : vous déboguez 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, historiques de sauts, etc. sont restaurés .
 
Règle importante : il y a ''toujours '' un projet ouvert. Les seules façons de "fermer" un projet sont, soit de quitter Lazarus, soit d'ouvrir un autre projet. C'est parce qu'un projet Lazarus est également une "session". Ceci signifie que les paramètres courants de l'éditeur sont également stockés dans le fichier .lpi et sont restaurés quand vous réouvrez le projet. Par exemple : vous déboguez 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, historiques de sauts, etc. sont restaurés .
  
=== Editeur de Sources ===
+
=== Éditeur de Sources ===
Presque toutes les clefs  et les raccourcis peuvent être définis  dans '''configuration->options de l'editeur->Assignation des touches'''
+
Presque toutes les touches et raccourcis peuvent être définis  dans '''Configuration→Options de l'éditeur→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'IDE de Lazarus incorpore de nombreux outils de manipulation des sources. Bon nombre d'entre eux sont similaires à ceux de Delphi, et travaillent de façon semblable. Mais il y a une différence importante : Lazarus n'utilise pas le compilateur pour obtenir de l'information sur le code. Il analyse les sources directement, et 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".
+
L'éditeur de sources travaille avec des "commentaires". Delphi traite les commentaires dans le code source comme des espaces entre les instructions. Ces commentaires ne contiennent aucune fonctionnalité du code, et quand du nouveau code est automatiquement inséré, les commentaires se déplacent. Sous Lazarus, vous pouvez faire une recherche de déclaration même sur du code contenu dans des commentaires. Bien que ce ne soit pas parfaitement fiable, cela fonctionne souvent. Et quand du nouveau code est inséré, l'IDE emploie des méthodes heuristiques afin de conserver les liaisons entre le commentaire et le code. 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.
+
"La complétion de code" de Delphi (Ctrl+Space) est appelée "complétion d'identificateur" sous Lazarus. Le terme Lazarus de "complétion de code" est une fonctionnalité pouvant signifier "complétion de classe automatique" (la même que sous Delphi), "complétion de variable locale" ou "complétion d'affectation d'évènement". Toutes sont invoquées par  Ctrl+Shift+C et c'est en fonction de la position du curseur que l'IDE détermine l'opération à effectuer.
 
    
 
    
==== Exemple de completion de variable locale ====
+
==== Exemple de complétion de variable locale ====
Supposer que vous avez juste créé une nouvelle méthode et avez écrit l'instruction  "i:=3;"
+
Supposons que vous veniez de créer une nouvelle méthode contenant l'instruction  "i := 3;"
<delphi>procedure TForm1.FaireQuelqueChose;
+
<syntaxhighlight lang=pascal>procedure TForm1.FaireQuelqueChose;
 
  begin
 
  begin
 
   i := 3;
 
   i := 3;
  end;</delphi>
+
  end;</syntaxhighlight>
  
Placer le curseur au-dessus de l'identificateur "i" et appuyez sur Ctrl+Shift+C pour obtenir:
+
Placez le curseur au-dessus de l'identificateur "i" et appuyez sur Ctrl+Shift+C pour obtenir :
<delphi>TForm1.FaireQuelqueChose;
+
<syntaxhighlight lang=pascal>TForm1.FaireQuelqueChose;
 
  var
 
  var
 
   i: Integer;
 
   i: Integer;
 
  begin
 
  begin
 
   i := 3;
 
   i := 3;
  end;</delphi>
+
  end;</syntaxhighlight>
  
==== Exemple de completion d'assignation d'évènement ====
+
==== Exemple de complétion 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.<br>
+
Une des fonctionnalités intéressantes de l'inspecteur d'objets est la création automatique de méthodes. Vous pouvez obtenir la même chose dans l'éditeur de sources. Par exemple :
Par exemple :
+
<syntaxhighlight lang=pascal> Button1.OnClick :=</syntaxhighlight>
<delphi> Button1.OnClick :=</delphi>
+
Placez le curseur derrière l'opérateur d'assignation ":=" et appuyez sur Ctrl+Shift+C.
Placer le curseur derrière l'opérateur d'assignation ":=" et appuyez sur Ctrl+Shift+C.
 
  
==== "Complétion de mot" Ctrl+W ====
+
==== 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.
+
Elle fonctionne de façon semblable à la "complétion d'identificateur", sauf qu'au lieu d'opérer sur les identificateurs Pascal, elle opère sur tous les mots. Vous choisissez dans une liste contenant tous les mots commençant par les mêmes lettres et contenus dans tous les fichiers ouverts.
  
==== Supporte les fichiers Include ====
+
==== Support des 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.
+
Delphi ne les acceptait pas (NDT : faux, directive {$I <fichier>}), et vous n'avez donc 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 le "polluer" avec des $IFDEF.
Par exemple : Saut de méthode , Completion de Classes, recherche de déclaration, .. tout fonctionne avec des fichiers include.
+
Par exemple : saut de méthode, complétion de classes, recherche de déclaration, etc. tout fonctionne avec des fichiers "include".
  
Il y a beaucoup d'options pour les fonctionnalités du code.
+
De nombreuses options de manipulation du code sont disponibles.
  
 
=== Concepteur  ===
 
=== Concepteur  ===
Line 85: Line 84:
  
 
=== VCL &rarr; LCL ===
 
=== VCL &rarr; 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/fr|Free Pascal]] .
+
Bien que la VCL et la LCL aient le même objectif, c'est-à-dire d'être des hiérarchies de composants orientés objet spécifiquement conçues pour le développement rapide d'applications, elle ne sont pas identiques. Par exemple, alors que la VCL fournit un certain nombre de composants non visuels, la LCL ne fournit dans la mesure du possible que des composants visuels, les composants non-visuels (tels que ceux destinés aux manipulations de bases de données) étant fournis par la FCL de [[Free Pascal/fr|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.
+
En outre, certains composants de la VCL n'existent pas dans la LCL, et réciproquement, ou bien lorsqu'ils existent dans les deux, ne sont pas des &laquo;clones&raquo;, et nécessitent des adaptations lors du portage d'applications, de composants ou de contrôles.
  
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.
+
Nous allons tenter de fournir une description suffisamment complète des différences ou incompatibilités majeures entre les deux, destinée au développeur Delphi. Ceci concerne en premier lieu les différences entre la VCL de Delphi 4 (mais par voie de conséquence également celles de Delphi 5, 6 ou 7...) et la LCL dans sa dernière version (CVS). Il se pourrait donc que ces explications ne soient pas exactement adaptées à votre version de Delphi, ni ne corresponde parfaitement à la LCL que vous utilisez actuellement. Si vous constatez des inexactitudes entre ce qui suit et la LCL dans sa dernière version (CVS), ou votre version de Delphi, n'hésitez pas à compléter ou modifier l'article de sorte qu'il reste compréhensible pour tout le monde.
  
 
==== TControl.Font/TControl.ParentFont ====
 
==== 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.  
+
Dans la VCL, il est courant et normal d'utiliser le nom d'une police de caractères particulière, ou des propriétés de police telles que le gras ou l'italique pour les contrôles, et de s'attendre à ce que ces valeurs s'affichent correctement. En outre, on dispose de la propriété TControl.ParentFont qui permet de faire en sorte qu'un contrôle utilise la police de son parent, toujours en supposant implicitement que ces valeurs seront respectées, indépendamment des propriétés d'affichage de Windows.
  
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.  
+
Ceci n'est pas toujours vrai, ni toujours possible, dans la LCL. Celle-ci, étant par nature multi-plate-forme et multi-interface, utilise une approche plus mesurée et essaiera plutôt, dans toutes les circonstances, d'utiliser les paramètres natifs du bureau, de la couche graphique, ou du thème sélectionné, quelle que soit l'interface utilisée (&laquo;widgets&raquo;). Par exemple, si vous utilisez l'interface GTK, et que le thème GTK impose une police spécifique pour les boutons, la LCL utilisera toujours cette police.
  
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.
+
En conséquence de quoi, les contrôles de la LCL n'offrent en général pas les mêmes degrés de liberté à la conception que ceux qu'on attend souvent de la VCL. Seuls les contrôles personnalisés se dessinant eux-même dans un canevas, au lieu d'être de simples interfaces, peuvent logiquement être modifiés de cette manière, indépendamment de l'interface graphique utilisée.
  
==== Control Dragging/Docking ====
+
==== Glisser/déplacer ====
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.  
+
Dans la VCL, la plupart des (Win)Controls implémentent des méthodes et des fonctions &laquo;callback&raquo; pour gérer le "glisser/déplacer" de contrôles, par exemple faire glisser un composant depuis un TPanel, et le déplacer dans un autre à l'exécution.
  
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.  
+
Ces fonctionnalités sont actuellement non implémentées ou non terminées dans la LCL, bien qu'elles soient sur la feuille de route, et devraient sans doute bientôt fournir un certain degré de compatibilité pour ce type de fonctionnalité, si ce n'est une compatibilité totale.
  
This currently means that no Control will inherit/use the following TControl functions, procedures, properties, or events 
+
Ceci signifie qu'actuellement aucun contrôle n'hérite ni ne permet l'usage des fonctions, procédures, propriétés ou évènements suivants...
  
<delphi>Protected  
+
<syntaxhighlight lang=pascal>Protected  
 
  function  GetDockEdge(MousePos: TPoint): TAlign;
 
  function  GetDockEdge(MousePos: TPoint): TAlign;
 
  function  GetDragImages: TDragImageList;
 
  function  GetDragImages: TDragImageList;
Line 149: Line 148:
 
  property  TBDockHeight: Integer;
 
  property  TBDockHeight: Integer;
 
  property  UndockHeight: Integer;
 
  property  UndockHeight: Integer;
  property  UndockWidth: Integer;</delphi>
+
  property  UndockWidth: Integer;</syntaxhighlight>
  
that the following classes do not exist/are unuseable -
+
que les classes suivantes n'existent pas ou sont inutilisables...
  
<delphi> TDragImageList = class(TCustomImageList)  
+
<syntaxhighlight lang=pascal> TDragImageList = class(TCustomImageList)  
 
  TDockZone = class
 
  TDockZone = class
 
  TDockTree = class(TInterfacedObject, IDockManager)  
 
  TDockTree = class(TInterfacedObject, IDockManager)  
Line 159: Line 158:
 
  TBaseDragControlObject = class (TDragObject)  
 
  TBaseDragControlObject = class (TDragObject)  
 
  TDragControlObject = class (TBaseDragControlObject)  
 
  TDragControlObject = class (TBaseDragControlObject)  
  TDragDockObject = class(TBaseDragControlObject)</delphi>
+
  TDragDockObject = class(TBaseDragControlObject)</syntaxhighlight>
  
and that the following functions are also unuseable/incompatible -
+
et que les fonctions suivantes n'existent pas non plus, ou sont également inutilisables.
  
<delphi>function  FindDragTarget(const Pos: TPoint;AllowDisabled: Boolean) : TControl;
+
<syntaxhighlight lang=pascal>function  FindDragTarget(const Pos: TPoint;AllowDisabled: Boolean) : TControl;
 
procedure CancelDrag;
 
procedure CancelDrag;
function  IsDragObject(sender: TObject): Boolean;</delphi>
+
function  IsDragObject(sender: TObject): Boolean;</syntaxhighlight>
  
 
==== TEdit/TCustomEdit ====
 
==== 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 -
+
Les contrôles d'édition, bien que fonctionnant dans la LCL essentiellement de la même manière que dans la VCL, ont quelques particularités auxquelles il convient d'être attentif lors d'une conversion.
# 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.
+
# À cause des restrictions dues aux interfaces, TEdit.PasswordChar ne fonctionne pas sur toutes les implémentations (mais ''peut'' parfois fonctionner). À la place, on donnera la valeur emPassword à la propriété TCustomEdit.EchoMode, dans les cas où le texte devra être caché.
# On Drag/Dock Events are not yet implemented. For more information please see earlier section on [[#Control Dragging/Docking | Control Dragging/Docking]].
+
# Les évènements liés au glisser/déplacer ne sont pas encore implémentés. Pour plus d'information, se référer à la section précédente [[#Glisser/déplacer | Glisser/déplacer]].
# Font Properties are usually ignored for interface consistancy, for detailed explanation as too why please see [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]]
+
# Les propriétés de la police de caractères sont généralement ignorées pour des raisons de cohérence de l'interface. Pour des explications plus détaillées, voir [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]]
  
 
=== (optional) TSplitter &rarr; TPairSplitter ===
 
=== (optional) TSplitter &rarr; TPairSplitter ===
'''Please Improve Me'''
+
'''Améliorez-moi...'''
  
There is now a TSplitter control in the LCL, so no need to convert it.
+
La LCL possède aujourd'hui son composant TSplitter, il n'est donc pas nécessaire d'effectuer une quelconque conversion.
  
Nevertheless, if you want, here it is explained:
+
Néanmoins, si vous le désirez, voici quelques explications.
  
The following is loosely based on questions by [[User:Vincent | Vincent Snijders]] on the mailing list, and responses by [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson]:
+
Ce qui suit est librement inspiré des questions posées par [[User:Vincent | Vincent Snijders]] sur la liste de diffusion, et des réponses apportées par [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson 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.  
+
Dans la VCL, les contrôles de redimensionnement se présentent sous la forme de poignées que l'on peut faire glisser entre deux composants pour donner plus d'espace à l'un ou à l'autre, et qui s'obtiennent avec le contrôle TSplitter. On les rencontre fréquemment, y compris dans l'IDE de Delphi.
  
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.
+
La LCL fournit son propre contrôle, TPairSplitter, dont l'utilité est la même, mais qui n'est pas compatible. Il sera ainsi nécessaire de "réparer" les codes VCL ou les DFM Delphi devenus incorrects dans le cadre d'une adaptation, malgré le fait que beaucoup de choses soient communes entre les deux versions.
  
;So what exactly are the differences?
+
;Alors quelles sont exactement les différences ?
  
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.
+
Hé bien, les plus grandes différences sont que le TSplitter de la VCL n'a pas d'enfant, qu'il est placé entre deux contrôles alignés d'une certaine façon, et qu'il permet le redimensionnement indépendamment de sa propre taille. Il doit avoir deux contrôles alignés de chaque côté pour pouvoir fonctionner. Un exemple simple serait une fiche contenant un TPanel aligné à gauche (alLeft), un TSplitter aligné à gauche, et enfin un TPanel aligné sur la zone client (alClient). À l'exécution, vous pouvez alors modifier les dimensions des deux TPanel en faisant glisser la poignée fournie par le contrôle TSplitter.
  
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.
+
Côté LCL, par contre, le TPairSplitter est un type spécial de contrôle, possédant déjà deux panneaux, qui n'a d'utilité que s'il y a des composants à séparer sur ces panneaux, mais qui séparera quand même ces derniers, qu'il y ait quelque chose ou pas dessus. Ainsi, l'exemple précédent devient une fiche contenant un TPairSplitter aligné sur la zone client, et deux TPanel alignés aussi sur la zone client, l'un sur le panneau gauche, l'autre sur le panneau droit de ce TPairSplitter.
  
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,
+
L'autre différence importante est que dans la VCL, étant donné que le TSplitter est son propre contrôle, sa position est conservée relativement aux contrôles en cas de redimensionnement. Ainsi, par exemple, un TPanel aligné sur la zone client (alClient) grossira tandis que les autres TPanel resteront tels quels, donc la position de séparation dépend de la propriété d'alignement des contrôles séparés.
  
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.
+
Dans la LCL, comme les deux panneaux de chaque côté sont indépendants, le TPairSplitter possède une propriété Position qui est absolue par rapport au bord supérieur ou au bord gauche. Donc, en cas de redimensionnement, la position de la poignée ne change pas et si cela est important, il faut appeler une méthode en retour pour s'assurer que le rapport est conservé.
  
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 :
+
(NDT: j'ai traduit ce qui suit conformément au texte original, mais à mon avis il y a une erreur, puisque le côté droit possède déjà un comportement de type alClient. En outre, le code d'exemple produit un résultat erratique, ce qui est normal puisque pour effectuer ce genre de redimensionnement, il faudrait avoir stocké quelque part l'''ancienne'' valeur de la propriété Position...)
PairSplitter.Position := PairSplitter.Width - PairSplitter.Position;  
+
Par exemple si le côté droit d'un séparateur vertical nécessite d'avoir un comportement de type alClient, vous devrez écrire une méthode de redimensionnement de fiche effectuant quelque chose comme :
 +
<syntaxhighlight lang=pascal> PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; </syntaxhighlight>
  
;So how can I convert existing code using TSplitter to the TPairSplitter?
+
;Alors, comment puis-je transformer un code existant pour utiliser TPairSplitter au lieu de TSplitter ?
  
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 -
+
Si les séparateurs et les contrôles sont créés dynamiquement (dans la méthode OnCreate de la fiche, par exemple), la conversion ne devrait pas poser trop de problèmes. Commencez par réorganiser la création des contrôles conformément à la nouvelle hiérarchie, en positionnant la propriété Parent des contrôles enfants aux deux panneaux, gauche et droite, ou haut et bas, du TPairSplitter. Voici un exemple de conversion.
  
 
{| class="wikitable"
 
{| class="wikitable"
Line 208: Line 208:
 
! LCL
 
! LCL
 
|-valign="top"
 
|-valign="top"
|<delphi>var
+
|<syntaxhighlight lang=pascal>var
 
  BottomPanel: TPanel;
 
  BottomPanel: TPanel;
 
  VerticalSplitter: TSplitter;
 
  VerticalSplitter: TSplitter;
Line 248: Line 248:
 
   Caption := 'Hello';
 
   Caption := 'Hello';
 
   end;
 
   end;
end;</delphi>
+
end;</syntaxhighlight>
|<delphi>var
+
|<syntaxhighlight lang=pascal>var
 
  BottomPanel: TPanel;
 
  BottomPanel: TPanel;
 
  VerticalSplitter: TPairSplitter;
 
  VerticalSplitter: TPairSplitter;
Line 297: Line 297:
 
   Align:= alClient;
 
   Align:= alClient;
 
   end;
 
   end;
  end;</delphi>
+
  end;</syntaxhighlight>
 
|}
 
|}
  
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.
+
Comme vous pouvez le voir, c'est assez substantiel pour la plupart des hiérarchies de contrôles. Et si vous êtes familiers des fichiers DFM, les modifications nécessaires dans le cadre d'une conversion DFM&rarr;LFM devraient être assez évidentes d'après l'exemple qui précède, puisqu'elles suivent le même schéma que les changement dans les propriétés Parent, Owner, etc.
  
So the above example would be something like -
+
Ainsi l'exemple que nous avons vu donnerait quelque chose comme :
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-align="center"
 
|-align="center"
!Delphi DFM
+
!DFM Delphi
(extraneous values removed)
+
(valeurs pertinentes seulement)
!Lazarus LFM
+
!LFM Lazarus
(most width, height, etc. removed)
+
(plupart des propriétés Width, Height, etc. enlevées)
 
|-valign="top"
 
|-valign="top"
|<delphi>object VerticalSplitter: TSplitter  
+
|<syntaxhighlight lang=pascal>object VerticalSplitter: TSplitter  
 
   Height = 3
 
   Height = 3
 
   Cursor = crVSplit  
 
   Cursor = crVSplit  
Line 330: Line 330:
 
object MainPanel: TPanel  
 
object MainPanel: TPanel  
 
   Align = alClient
 
   Align = alClient
end</delphi>
+
end</syntaxhighlight>
|<delphi>object VerticalSplitter: TPairSplitter  
+
|<syntaxhighlight lang=pascal>object VerticalSplitter: TPairSplitter  
 
   Align = alClient
 
   Align = alClient
 
   SplitterType = pstVertical
 
   SplitterType = pstVertical
Line 361: Line 361:
 
     end
 
     end
 
   end
 
   end
end</delphi>
+
end</syntaxhighlight>
 
|}
 
|}
  
 
=== TCustomTreeView/TTreeView ===
 
=== 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 -
+
La VCL et la LCL fournissent toutes deux des composants TCustomTreeView / TTreeView utilisés pour des listes de données arborescentes avec des nœuds, des méthodes de sélection et des listes d’images. Bien que comparables leurs propriétés respectives ne sont pas toutes entièrement compatibles. Les principales différences sont :
  
 
'''Incomplete list, also update to include TCustomTreeView Mark functions and protected methods '''
 
'''Incomplete list, also update to include TCustomTreeView Mark functions and protected methods '''
  
# 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 :
+
# La LCL fournit un ensemble d’options au TCustomTreeView.afin de modifier et contrôler son comportement et son apparence. Ces options sont :  
#* tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL
+
 
#* tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand
+
#* tvoAllowMultiselect –permet la sélection multiple de nœuds ; Correspond au MultiSelect du TCustomTreeView. de la VCL D6.
#* tvoAutoInsertMark - Update the Drag preview on mouse move.
+
#* tvoAutoExpand –Développement automatique des noeuds; Correspond au AutoExpand du TCustomTreeView.  
#* tvoAutoItemHeight - Adjust the item heights automatically.
+
#* tvoAutoInsertMark – Met à jour (initialise) le Drag lors d’un mouvement de souris.  
#* tvoHideSelection - Do not mark the selected item.
+
#* tvoAutoItemHeight – Ajuste automatiquement les hauteurs d’items.  
#* tvoHotTrack - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack
+
#* tvoHideSelection – Ne met pas en évidence l’item sélectionné.
#* tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes
+
#* tvoHotTrack – active le Hot Tracking; Correspond au HotTrack du TcustomTreeview.
#* tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly
+
#* tvoKeepCollapsedNodes – Conserve les noeuds enfants lors du repli de noeuds.
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
+
#* tvoReadOnly – Place le Treeview en lecture seule; Correspond au ReadOnly  du TcustomTreeview.
#* tvoRowSelect  - allow selecting rows, equivalent to enabling TCustomTreeView.RowSelect
+
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect  
#* tvoShowButtons - show buttons, equivalent to enabling TCustomTreeView.ShowButtons
+
#* tvoRowSelect – Permet la sélection de lignes, correspond au RowSelect du TCustomTreeView.
#* tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
+
#* tvoShowButtons –Affiche les boutons , Correspond au ShowButtons du TCustomTreeView.  
#* tvoShowRoot  - show root note, equivalent to enabling TCustomTreeView.ShowRoot
+
#* tvoShowLines – Affiche les lignes des noeuds ; Correspond au ShowLines du TCustomTreeView.
#* tvoShowSeparators - show seperators
+
#* tvoShowRoot – Affiche la racine ; Correspond au ShowRoot du TcustomTreeView.
#* tvoToolTips - show tooltips for individual nodes
+
#* tvoShowSeparators – Affiche les séparateurs
# The LCL provides additional properties:
+
#* tvoToolTips - show tooltips for individual nodes  
#* TCustomTreeView.OnSelectionChange event
+
# La LCL fournit des propriétés supplémentaires:
#* TCustomTreeView.DefaultItems, for the default number of Items
+
#* TCustomTreeView.OnSelectionChange Evénement se déclenchant lors d’un changement de sélection
#* TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
+
#* TCustomTreeView.DefaultItems, Pour le nombre par défaut d’items.
# 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.
+
#* TCustomTreeView.ExpandSignType Pour déterminer le signe utilisé lors Développement/Pliage de nœuds.
 +
 
 +
Bien que la plupart des événements Drag/Dock (tirer/glisser) est disponible elle n’est pas fonctionnelle. Pour plus d’information voir le chapitre précédant sur le Control Dragging/Docking.
  
=== Messages / Events ===
+
=== Messages / Evenements ===
  
The order and frequency of messages and events (OnShow, OnActivate, OnEnter, ...) differ from the VCL and depend on the widgetset.
+
L’ordre, la fréquence des messages et des événements (OnShow, OnActivate, OnEnter, ...) diffèrent de la VCL et dépendent de l’ensemble des Widgets. La LCL fournit un sous ensemble de messages comparables aux API Windows afin de rendre le portage des composants Delphi plus simple. Cependant, la plupart des messages de la LCL fonctionne différemment. L’essentiel du code Delphi utilise les messages des API Windows car la VCL ne dispose pas de ces fonctionnalités, et pour une question de rapidité. Ceci sera rarement le cas dans la LCL , et nécessitera un contrôle manuel. C’est par exemple pour cette raison que les messages sont appelés LM_SIZE au lieu de WM_SIZE.
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 ==
 
== Original Contributors and changes ==

Latest revision as of 23:53, 18 February 2020

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) semblable à Delphi. Cela signifie qu'il incorpore une bibliothèque de composants visuels et un environnement de développement intégré (IDE). La bibliothèque de composants de Lazarus (LCL) est très semblable à la VCL de Delphi. La plupart des unités, classes et propriétés ont les mêmes noms et fonctionnalités. Ceci rend le portage aisé . Mais Lazarus n'est *pas* un "clone open source de Delphi". Ne vous attendez donc pas à 100% de compatibilité.

Différences les plus importantes

Lazarus est une plate-forme indépendante entièrement open source, utilisant le puissant compilateur Free Pascal (FPC). FPC s'exécute sur plus de 15 plates-formes. Mais les paquets et bibliothèques ne sont pas tous portés, ainsi Lazarus s'exécute actuellement 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 développeurs, créateurs de paquets, réalisateurs de portages, auteurs de documentation , ... .

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

Après avoir lancé Lazarus, vous devriez aller dans OutilsConvertir un projet Delphi en projet Lazarus... . Ceci ne fera pas tout à votre place, mais vous permettra néanmoins 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 contient le code source principal du programme, et l'IDE de Delphi y stocke quelques informations sur les options et les unités du compilateur. Une application Lazarus a aussi un fichier .lpr, qui contient également le code source principal. Mais toute les autres informations sont stockées dans le fichier .lpi. Le fichier important d'un projet est donc le fichier .lpi.

Par exemple :

Delphi stocke les chemins des unités dans le fichier .dpr (ex. : unit1 in 'path/Unit1.pas'). Ces chemins précédés de 'in' sont spécifiques à Delphi et ne sont pas lus par l'IDE de Lazarus. Il ne faut pas les utiliser. À la place, les chemins des unités sont à définir dans "Projet→Options du compilateur...".

Delphi stocke les options du compilateur dans le fichier .dpr. Par exemple {$APPTYPE CONSOLE}. Les options définies de cette façon sont ignorées par l'IDE de Lazarus. Il ne faut pas les utiliser, et définir à la place les options dans "Projet→Options du compilateur...".


Règle importante : il y a toujours un projet ouvert. Les seules façons de "fermer" un projet sont, soit de quitter Lazarus, soit d'ouvrir un autre projet. C'est parce qu'un projet Lazarus est également une "session". Ceci signifie que les paramètres courants de l'éditeur sont également stockés dans le fichier .lpi et sont restaurés quand vous réouvrez le projet. Par exemple : vous déboguez 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, historiques de sauts, etc. sont restaurés .

Éditeur de Sources

Presque toutes les touches et raccourcis peuvent être définis dans Configuration→Options de l'éditeur→Assignation des touches

L'IDE de Lazarus incorpore de nombreux outils de manipulation des sources. Bon nombre d'entre eux sont similaires à ceux de Delphi, et travaillent de façon semblable. Mais il y a une différence importante : Lazarus n'utilise pas le compilateur pour obtenir de l'information sur le code. Il analyse les sources directement, et ceci a beaucoup d'avantages importants.

L'éditeur de sources travaille avec des "commentaires". Delphi traite les commentaires dans le code source comme des espaces entre les instructions. Ces commentaires ne contiennent aucune fonctionnalité du code, et quand du nouveau code est automatiquement inséré, les commentaires se déplacent. Sous Lazarus, vous pouvez faire une recherche de déclaration même sur du code contenu dans des commentaires. Bien que ce ne soit pas parfaitement fiable, cela fonctionne souvent. Et quand du nouveau code est inséré, l'IDE emploie des méthodes heuristiques afin de conserver les liaisons entre le commentaire et le code. 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 "complétion de code" est une fonctionnalité pouvant signifier "complétion de classe automatique" (la même que sous Delphi), "complétion de variable locale" ou "complétion d'affectation d'évènement". Toutes sont invoquées par Ctrl+Shift+C et c'est en fonction de la position du curseur que l'IDE détermine l'opération à effectuer.

Exemple de complétion de variable locale

Supposons que vous veniez de créer une nouvelle méthode contenant l'instruction "i := 3;"

procedure TForm1.FaireQuelqueChose;
 begin
  i := 3;
 end;

Placez le curseur au-dessus de l'identificateur "i" et appuyez sur Ctrl+Shift+C pour obtenir :

TForm1.FaireQuelqueChose;
 var
   i: Integer;
 begin
  i := 3;
 end;

Exemple de complétion d'assignation d'évènement

Une des fonctionnalités intéressantes de l'inspecteur d'objets est la création automatique de méthodes. Vous pouvez obtenir la même chose dans l'éditeur de sources. Par exemple :

 Button1.OnClick :=

Placez le curseur derrière l'opérateur d'assignation ":=" et appuyez sur Ctrl+Shift+C.

Complétion de mot Ctrl+W

Elle fonctionne de façon semblable à la "complétion d'identificateur", sauf qu'au lieu d'opérer sur les identificateurs Pascal, elle opère sur tous les mots. Vous choisissez dans une liste contenant tous les mots commençant par les mêmes lettres et contenus dans tous les fichiers ouverts.

Support des fichiers Include

Delphi ne les acceptait pas (NDT : faux, directive {$I <fichier>}), et vous n'avez donc 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 le "polluer" avec des $IFDEF. Par exemple : saut de méthode, complétion de classes, recherche de déclaration, etc. tout fonctionne avec des fichiers "include".

De nombreuses options de manipulation du code sont disponibles.

Concepteur

- Directives

Inspecteur d'objet

Dans les environnements de développement de Delphi et de Lazarus, l'inspecteur d'objets sert à éditer les propriétés des composants, à leur assigner des évènements, etc. Voici quelques différences mineures qu'il faut noter :

  1. Depuis Delphi 5, en complément de la traditionnelle liste déroulante, il existe une vue arborescente des composants de l'application, permettant de naviguer dans la hiérarchie et de sélectionner des objets. Dans Lazarus, cette vue arborescente fait partie intégrante de l'inspecteur d'objets et remplace la liste déroulante. Vous pouvez néanmoins choisir entre l'une ou l'autre par l'option "Afficher l'arbre du composant" du menu contextuel (clic droit).
  2. Dans Delphi, un double-clic sur un évènement vierge génère automatiquement un code associé à cet évènement, et ouvre l'éditeur de code source à la bonne position. Dans Lazarus, un petit bouton "..." situé à droite de la liste déroulante permet la même chose.
  3. Dans Delphi, on doit effacer manuellement le nom d'un évènement pour supprimer la liaison, dans Lazarus, on peut sélectionner "(Aucun)" dans la liste déroulante.
  4. De façon similaire, un double-clic sur une propriété de type simple ne change pas sa valeur, il faut sélectionner celle-ci dans la liste déroulante. Et pour les propriétés associées à un éditeur, il faut cliquer sur le petit bouton "..." situé à droite de cette propriété. (NDT : me semble obsolète pour les versions récentes de Lazarus...).

Paquets

Peut-on installer et utiliser des paquets Delphi sous Lazarus ?

  • Non, car ils nécessitent des fonctionnalités propres au compilateur de Delphi.

Doit-on en créer un spécialement pour Lazarus ?

  • Oui. Créer un nouveau paquet, le sauvegarder dans le répertoire source du paquet original (en principe le répertoire du fichier .dpk), ajouter la LCL comme paquet requis (si ce n'est déjà fait), puis finalement ajouter les fichiers .pas. On peut alors l'installer ou l'utiliser dans un projet. Il existe des différences entre les paquets Delphi et les paquets Lazarus, se référer au fichier docs/Packages.txt pour plus de précisions.

VCL → LCL

Bien que la VCL et la LCL aient le même objectif, c'est-à-dire d'être des hiérarchies de composants orientés objet spécifiquement conçues pour le développement rapide d'applications, elle ne sont pas identiques. Par exemple, alors que la VCL fournit un certain nombre de composants non visuels, la LCL ne fournit dans la mesure du possible que des composants visuels, les composants non-visuels (tels que ceux destinés aux manipulations de bases de données) étant fournis par la FCL de Free Pascal .

En outre, certains composants de la VCL n'existent pas dans la LCL, et réciproquement, ou bien lorsqu'ils existent dans les deux, ne sont pas des «clones», et nécessitent des adaptations lors du portage d'applications, de composants ou de contrôles.

Nous allons tenter de fournir une description suffisamment complète des différences ou incompatibilités majeures entre les deux, destinée au développeur Delphi. Ceci concerne en premier lieu les différences entre la VCL de Delphi 4 (mais par voie de conséquence également celles de Delphi 5, 6 ou 7...) et la LCL dans sa dernière version (CVS). Il se pourrait donc que ces explications ne soient pas exactement adaptées à votre version de Delphi, ni ne corresponde parfaitement à la LCL que vous utilisez actuellement. Si vous constatez des inexactitudes entre ce qui suit et la LCL dans sa dernière version (CVS), ou votre version de Delphi, n'hésitez pas à compléter ou modifier l'article de sorte qu'il reste compréhensible pour tout le monde.

TControl.Font/TControl.ParentFont

Dans la VCL, il est courant et normal d'utiliser le nom d'une police de caractères particulière, ou des propriétés de police telles que le gras ou l'italique pour les contrôles, et de s'attendre à ce que ces valeurs s'affichent correctement. En outre, on dispose de la propriété TControl.ParentFont qui permet de faire en sorte qu'un contrôle utilise la police de son parent, toujours en supposant implicitement que ces valeurs seront respectées, indépendamment des propriétés d'affichage de Windows.

Ceci n'est pas toujours vrai, ni toujours possible, dans la LCL. Celle-ci, étant par nature multi-plate-forme et multi-interface, utilise une approche plus mesurée et essaiera plutôt, dans toutes les circonstances, d'utiliser les paramètres natifs du bureau, de la couche graphique, ou du thème sélectionné, quelle que soit l'interface utilisée («widgets»). Par exemple, si vous utilisez l'interface GTK, et que le thème GTK impose une police spécifique pour les boutons, la LCL utilisera toujours cette police.

En conséquence de quoi, les contrôles de la LCL n'offrent en général pas les mêmes degrés de liberté à la conception que ceux qu'on attend souvent de la VCL. Seuls les contrôles personnalisés se dessinant eux-même dans un canevas, au lieu d'être de simples interfaces, peuvent logiquement être modifiés de cette manière, indépendamment de l'interface graphique utilisée.

Glisser/déplacer

Dans la VCL, la plupart des (Win)Controls implémentent des méthodes et des fonctions «callback» pour gérer le "glisser/déplacer" de contrôles, par exemple faire glisser un composant depuis un TPanel, et le déplacer dans un autre à l'exécution.

Ces fonctionnalités sont actuellement non implémentées ou non terminées dans la LCL, bien qu'elles soient sur la feuille de route, et devraient sans doute bientôt fournir un certain degré de compatibilité pour ce type de fonctionnalité, si ce n'est une compatibilité totale.

Ceci signifie qu'actuellement aucun contrôle n'hérite ni ne permet l'usage des fonctions, procédures, propriétés ou évènements suivants...

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;

que les classes suivantes n'existent pas ou sont inutilisables...

 TDragImageList = class(TCustomImageList) 
 TDockZone = class
 TDockTree = class(TInterfacedObject, IDockManager) 
 TDragObject = class(TObject) 
 TBaseDragControlObject = class (TDragObject) 
 TDragControlObject = class (TBaseDragControlObject) 
 TDragDockObject = class(TBaseDragControlObject)

et que les fonctions suivantes n'existent pas non plus, ou sont également inutilisables.

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

TEdit/TCustomEdit

Les contrôles d'édition, bien que fonctionnant dans la LCL essentiellement de la même manière que dans la VCL, ont quelques particularités auxquelles il convient d'être attentif lors d'une conversion.

  1. À cause des restrictions dues aux interfaces, TEdit.PasswordChar ne fonctionne pas sur toutes les implémentations (mais peut parfois fonctionner). À la place, on donnera la valeur emPassword à la propriété TCustomEdit.EchoMode, dans les cas où le texte devra être caché.
  2. Les évènements liés au glisser/déplacer ne sont pas encore implémentés. Pour plus d'information, se référer à la section précédente Glisser/déplacer.
  3. Les propriétés de la police de caractères sont généralement ignorées pour des raisons de cohérence de l'interface. Pour des explications plus détaillées, voir TControl.Font/TControl.ParentFont

(optional) TSplitter → TPairSplitter

Améliorez-moi...

La LCL possède aujourd'hui son composant TSplitter, il n'est donc pas nécessaire d'effectuer une quelconque conversion.

Néanmoins, si vous le désirez, voici quelques explications.

Ce qui suit est librement inspiré des questions posées par Vincent Snijders sur la liste de diffusion, et des réponses apportées par Andrew Johnson.

Dans la VCL, les contrôles de redimensionnement se présentent sous la forme de poignées que l'on peut faire glisser entre deux composants pour donner plus d'espace à l'un ou à l'autre, et qui s'obtiennent avec le contrôle TSplitter. On les rencontre fréquemment, y compris dans l'IDE de Delphi.

La LCL fournit son propre contrôle, TPairSplitter, dont l'utilité est la même, mais qui n'est pas compatible. Il sera ainsi nécessaire de "réparer" les codes VCL ou les DFM Delphi devenus incorrects dans le cadre d'une adaptation, malgré le fait que beaucoup de choses soient communes entre les deux versions.

Alors quelles sont exactement les différences ?

Hé bien, les plus grandes différences sont que le TSplitter de la VCL n'a pas d'enfant, qu'il est placé entre deux contrôles alignés d'une certaine façon, et qu'il permet le redimensionnement indépendamment de sa propre taille. Il doit avoir deux contrôles alignés de chaque côté pour pouvoir fonctionner. Un exemple simple serait une fiche contenant un TPanel aligné à gauche (alLeft), un TSplitter aligné à gauche, et enfin un TPanel aligné sur la zone client (alClient). À l'exécution, vous pouvez alors modifier les dimensions des deux TPanel en faisant glisser la poignée fournie par le contrôle TSplitter.

Côté LCL, par contre, le TPairSplitter est un type spécial de contrôle, possédant déjà deux panneaux, qui n'a d'utilité que s'il y a des composants à séparer sur ces panneaux, mais qui séparera quand même ces derniers, qu'il y ait quelque chose ou pas dessus. Ainsi, l'exemple précédent devient une fiche contenant un TPairSplitter aligné sur la zone client, et deux TPanel alignés aussi sur la zone client, l'un sur le panneau gauche, l'autre sur le panneau droit de ce TPairSplitter.

L'autre différence importante est que dans la VCL, étant donné que le TSplitter est son propre contrôle, sa position est conservée relativement aux contrôles en cas de redimensionnement. Ainsi, par exemple, un TPanel aligné sur la zone client (alClient) grossira tandis que les autres TPanel resteront tels quels, donc la position de séparation dépend de la propriété d'alignement des contrôles séparés.

Dans la LCL, comme les deux panneaux de chaque côté sont indépendants, le TPairSplitter possède une propriété Position qui est absolue par rapport au bord supérieur ou au bord gauche. Donc, en cas de redimensionnement, la position de la poignée ne change pas et si cela est important, il faut appeler une méthode en retour pour s'assurer que le rapport est conservé.

(NDT: j'ai traduit ce qui suit conformément au texte original, mais à mon avis il y a une erreur, puisque le côté droit possède déjà un comportement de type alClient. En outre, le code d'exemple produit un résultat erratique, ce qui est normal puisque pour effectuer ce genre de redimensionnement, il faudrait avoir stocké quelque part l'ancienne valeur de la propriété Position...) Par exemple si le côté droit d'un séparateur vertical nécessite d'avoir un comportement de type alClient, vous devrez écrire une méthode de redimensionnement de fiche effectuant quelque chose comme :

 PairSplitter.Position := PairSplitter.Width - PairSplitter.Position;
Alors, comment puis-je transformer un code existant pour utiliser TPairSplitter au lieu de TSplitter ?

Si les séparateurs et les contrôles sont créés dynamiquement (dans la méthode OnCreate de la fiche, par exemple), la conversion ne devrait pas poser trop de problèmes. Commencez par réorganiser la création des contrôles conformément à la nouvelle hiérarchie, en positionnant la propriété Parent des contrôles enfants aux deux panneaux, gauche et droite, ou haut et bas, du TPairSplitter. Voici un exemple de conversion.

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;

Comme vous pouvez le voir, c'est assez substantiel pour la plupart des hiérarchies de contrôles. Et si vous êtes familiers des fichiers DFM, les modifications nécessaires dans le cadre d'une conversion DFM→LFM devraient être assez évidentes d'après l'exemple qui précède, puisqu'elles suivent le même schéma que les changement dans les propriétés Parent, Owner, etc.

Ainsi l'exemple que nous avons vu donnerait quelque chose comme :

DFM Delphi

(valeurs pertinentes seulement)

LFM Lazarus

(plupart des propriétés Width, Height, etc. enlevées)

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

La VCL et la LCL fournissent toutes deux des composants TCustomTreeView / TTreeView utilisés pour des listes de données arborescentes avec des nœuds, des méthodes de sélection et des listes d’images. Bien que comparables leurs propriétés respectives ne sont pas toutes entièrement compatibles. Les principales différences sont :

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

  1. La LCL fournit un ensemble d’options au TCustomTreeView.afin de modifier et contrôler son comportement et son apparence. Ces options sont :
    • tvoAllowMultiselect –permet la sélection multiple de nœuds ; Correspond au MultiSelect du TCustomTreeView. de la VCL D6.
    • tvoAutoExpand –Développement automatique des noeuds; Correspond au AutoExpand du TCustomTreeView.
    • tvoAutoInsertMark – Met à jour (initialise) le Drag lors d’un mouvement de souris.
    • tvoAutoItemHeight – Ajuste automatiquement les hauteurs d’items.
    • tvoHideSelection – Ne met pas en évidence l’item sélectionné.
    • tvoHotTrack – active le Hot Tracking; Correspond au HotTrack du TcustomTreeview.
    • tvoKeepCollapsedNodes – Conserve les noeuds enfants lors du repli de noeuds.
    • tvoReadOnly – Place le Treeview en lecture seule; Correspond au ReadOnly du TcustomTreeview.
    • tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
    • tvoRowSelect – Permet la sélection de lignes, correspond au RowSelect du TCustomTreeView.
    • tvoShowButtons –Affiche les boutons , Correspond au ShowButtons du TCustomTreeView.
    • tvoShowLines – Affiche les lignes des noeuds ; Correspond au ShowLines du TCustomTreeView.
    • tvoShowRoot – Affiche la racine ; Correspond au ShowRoot du TcustomTreeView.
    • tvoShowSeparators – Affiche les séparateurs
    • tvoToolTips - show tooltips for individual nodes
  1. La LCL fournit des propriétés supplémentaires:
    • TCustomTreeView.OnSelectionChange Evénement se déclenchant lors d’un changement de sélection
    • TCustomTreeView.DefaultItems, Pour le nombre par défaut d’items.
    • TCustomTreeView.ExpandSignType Pour déterminer le signe utilisé lors Développement/Pliage de nœuds.

Bien que la plupart des événements Drag/Dock (tirer/glisser) est disponible elle n’est pas fonctionnelle. Pour plus d’information voir le chapitre précédant sur le Control Dragging/Docking.

Messages / Evenements

L’ordre, la fréquence des messages et des événements (OnShow, OnActivate, OnEnter, ...) diffèrent de la VCL et dépendent de l’ensemble des Widgets. La LCL fournit un sous ensemble de messages comparables aux API Windows afin de rendre le portage des composants Delphi plus simple. Cependant, la plupart des messages de la LCL fonctionne différemment. L’essentiel du code Delphi utilise les messages des API Windows car la VCL ne dispose pas de ces fonctionnalités, et pour une question de rapidité. Ceci sera rarement le cas dans la LCL , et nécessitera un contrôle manuel. C’est par exemple pour cette raison que les messages sont appelés LM_SIZE au lieu de WM_SIZE.

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