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

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting; deleted category included in page template)
 
(82 intermediate revisions by 16 users not shown)
Line 1: Line 1:
==Delphi -> Lazarus==
+
{{Lazarus For Delphi Users}}
Lazarus ist ein Rapid Application Development (RAD) Tool wie Delphi. Das bedeutet, es enthält eine visuelle Komponenten Bibliothek und eine IDE. Die Lazarus component library (LCL) ist sehr ähnlich zu Delphi's VCL. Die meisten Units, Klassen und Eigenschaften haben den selben Namen und Funktionalität. Dies macht eine Portierung (von Delphi zu Lazarus) einfach. Aber Lazarus ist kein 'Open Source Delphi Klon'. Erwarten sie daher keine 100%ige Kompatibilität.
+
<br>
 +
Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].<br>
 +
<br>
 +
Diese Beschreibung ist für Leute gedacht, die an Lazarus interessiert sind und Delphi bereits kennen. Sie beschreibt die Unterschiede zwischen den beiden.
  
===Die größten Unterschiede===
+
== Delphi -> Lazarus ==
Lazarus ist komplett Open Source, ist Plattform unabhängig geschrieben und benutzt den mächtigen [[Free Pascal]] Compiler (FPC). FPC läuft auf mehr als 15 Plattformen. Aber nicht alle Packages und Bibliotheken sind portiert, so daß Lazarus gegenwärtig unter Linux, Free/Open/NetBSD, MacOSX und Win32 läuft.
+
Lazarus ist ein Rapid Application Development (RAD) Tool wie Delphi. Das bedeutet, es enthält eine visuelle Komponentenbibliothek und eine IDE. Die Lazarus Component Library (LCL) ist sehr ähnlich zu Delphi's VCL. Die meisten Units, Klassen und Eigenschaften haben den selben Namen und die selbe Funktionalität. Dies macht eine Portierung (von Delphi zu Lazarus) einfach. Aber Lazarus ist kein 'Open Source Delphi Klon'. Erwarten Sie daher keine 100%ige Kompatibilität.
  
''' Lazarus ist nicht komplett, wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... . '''
+
=== Die größten Unterschiede ===
 +
Lazarus ist komplett Open Source, ist plattformunabhängig geschrieben und benutzt den mächtigen [[Free Pascal/de|Free Pascal]] Compiler (FPC). FPC läuft auf mehr als 15 Plattformen. Aber nicht alle Packages und Bibliotheken sind portiert, so dass Lazarus gegenwärtig unter Linux (i386, x86_64), FreeBSD (i386), Mac OS X (powerpc, i386) und Windows (i386, x86_64) läuft.
 +
 
 +
''' Lazarus ist nicht komplett, genau so wenig wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... . '''
 +
 
 +
=== Die erste Aktion bei der Konvertierung eines Delphi-Projekts ===
 +
Nachdem Lazarus gestartet ist, gehen Sie zu '''Werkzeuge''' und dann zu '''Delphi- in Lazarus-Project umwandeln'''. Das wird nicht alles für Sie erledigen, Sie aber ein gutes Stück weiter bringen. Beachten Sie, dass die Konvertierungstools der Lazarus-IDE generell nur Einweg-Konvertierungen durchführen. Falls Sie die Kompatibilität zu Delphi aufrecht halten müssen, sodass Sie Ihr Projekt sowohl mit Delphi als auch mit Lazarus kompilieren können, versuchen Sie stattdessen Ihre Dateien mit dem [http://wiki.lazarus.freepascal.org/XDev_Toolkit XDev Toolkit] zu konvertieren.
 +
 
 +
=== Unicode-Unterstützung ===
 +
 
 +
Die Versionen von Delphi bis zu Delphi 2007 hatten keine  Unterstützung von Unicode, aber verwendeten die Windows-ANSI-Kodierung. Delphi unterstützt Unicode mit in UTF-16 kodierten Zeichenketten seit der Version 2009.
 +
 
 +
Lazarus startete im Gegensatz dazu seine Unicode-Unterstützung früher und verwendet in UTF-8 kodierte Zeichenketten. Für weitere Informationen siehe [[LCL Unicode Support]].
 +
 
 +
== Delphi IDE -> Lazarus IDE ==
 +
=== Projekte ===
 +
Die Hauptdatei einer Delphi Anwendung ist die .dpr Datei. Die Hauptdatei eines Lazarus Projekts ist die .lpi Datei (Lazarus Project Information). Eine .dpr Datei ist die Hauptquelle eines Programms und die Delphi IDE speichert hier einige Informationen über die Compiler-Schalter und Units. Eine Lazarus-Anwendung hat auch eine .lpr Datei, die auch die wichtigste Quelldatei ist. Aber alle anderen Informationen werden in der .lpi Datei gespeichert. Daher ist die .lpi Datei die wichtigste Datei.
 +
 
 +
Zum Beispiel:
 +
 
 +
Delphi speichert die Pfade der Units in der .dpr-Datei. Beispielsweise: unit1 in 'path/Unit1.pas'. Diese 'in'-Pfade sind Delphispezifisch und werden nicht von der Lazarus-IDE gelesen. Verwenden Sie sie nicht. Benutzen Sie stattdessen die Unitpfade der Compilereinstellungen.
 +
 
 +
Delphi speichert Compilereinstellungen in der .dpr-Datei. Beispielsweise {$APPTYPE CONSOLE}. Diese werden von der Lazarus-IDE ignoriert. Verwenden Sie sie nicht. Benutzen Sie stattdessen die Compilereinstellungen.
  
==Delphi IDE -> Lazarus IDE==
 
===Projekte===
 
Die Hauptdatei einer Delphi Anwendung ist die .dpr Datei. Die Hauptdatei eines Lazarus Projekts ist die .lpi Datei (Lazarus Project Information). Eine .dpr Datei ist die Hauptquelle eines Programms und die Delphi IDE speichert hier einige Informationen über die Compiler Schalter und Units. Eine Lazarus Anwendung hat auch eine .lpr Datei, welche auch die wichtigste Quelldatei ist. Aber alle anderen Informationen werden in der .lpi Datei gespeichert. Daher, die wichtige datei ist die .lpi Datei.
 
  
 
Eine wichtige Regel: Es gibt ''immer'' ein Projekt.  
 
Eine wichtige Regel: Es gibt ''immer'' ein Projekt.  
Der einzige Weg um ein Projekt "zu beenden" ist, Lazarus zu beenden oder ein anderes Projekt zu öffnen. Das ist so, weil ein Lazarus Projekt auch eine "Sitzung" ist. Das bedeutet, daß die aktuellen Editor Einstellungen auch in der .lpi Datei gespeichert sind und wiederhergestellt werden, wenn sie das Projekt wieder öffnen. Zum Beispiel: Sie debuggen eine Anwendung, setzen eine Menge Haltepunkte (Breakpoints) und Lesezeichen (Bookmarks). Sie können das Projekt jederzeit speichern, Lazarus schließen oder ein anderes Projekt öffnen. Wenn sie das Projekt wieder öffnen, sogar auf einem anderen Computer, werden alle ihre Haltepunkte, Lesezeichen, geöffneten Dateien, Cursor Positionen, Sprunghistorie, ... wieder hergestellt.
+
Der einzige Weg, um ein Projekt "zu beenden", ist, Lazarus zu beenden oder ein anderes Projekt zu öffnen. Das ist so, weil ein Lazarus Projekt auch eine "Sitzung" ist. Das bedeutet, dass die aktuellen Editoreinstellungen auch in der .lpi Datei gespeichert sind und wiederhergestellt werden, wenn sie das Projekt wieder öffnen. Zum Beispiel: Sie debuggen eine Anwendung, setzen eine Menge Haltepunkte (Breakpoints) und Lesezeichen (Bookmarks). Sie können das Projekt jederzeit speichern, Lazarus schließen oder ein anderes Projekt öffnen. Wenn Sie das Projekt wieder öffnen, sogar auf einem anderen Computer, werden alle Ihre Haltepunkte, Lesezeichen, geöffneten Dateien, Cursorpositionen, Sprunghistorie, ... wieder hergestellt.
  
===Quelltext Editor===
+
=== Quelltext-Editor ===
Beinahe alle Tasten und Abkürzungen (short cuts) können definiert werden unter Einstellungen->Editoreinstellungen->Tastaturbelegung.
+
Nahezu alle Tasten und Tastenkürzel (short cuts) können unter 'Einstellungen -> Editoreinstellungen -> Tastaturbelegung' festgelegt werden.
  
Die Lazarus IDE besitzt eine Menge von Werkzeugen für Quellen. Viele von ihnen sehen aus und arbeiten sehr ähnlich zu Delphi. Aber es gibt einen wichtigen Unterschied: Lazarus benutzt nicht den Compiler um Code Informationen zu erhalten. Es analysiert die Quellen direkt. Dies hat eine Menge von bedeutenden Vorteilen:
+
Die Lazarus IDE besitzt eine Menge von Werkzeugen für Quelltexte. Viele von ihnen sehen aus und arbeiten sehr ähnlich wie Delphi. Aber es gibt einen wichtigen Unterschied: Lazarus benutzt nicht den Compiler, um Code-Informationen zu erhalten. Es analysiert die Quelltexte direkt. Dies hat eine Menge von bedeutenden Vorteilen:
  
Der Quelltext Editor arbeitet mit "Ausführungen" (comments). Für Delphi sind die Ausführungen in den Quellen einfach nur Leerzeichen im Code. Keine Code Eigenschaft funktioniert dort und wenn neuer Code automatisch eingefügt wird, dann reisen ihre Ausführungen. Unter Lazarus können sie eine find declaration sogar für Code in den Ausführungen erstellen. Obwohl dies nicht komplett verläßlich ist, funktioniert es oftmals. Und wenn neuer Code eingefügt ist, dann benutzt die IDE einige heuristische Methoden, um Ausführungen und Code zusammen zu halten. Zum Beispiel: Es wird nicht die Zeile "c: char; // comment" aufteilen.
+
Der Quelltext-Editor berücksichtigt Kommentare. Für Delphi sind die Kommentare in den Quellen einfach nur Leerzeichen im Code. Kein Code-Werkzeug funktioniert dort und wenn neuer Code automatisch eingefügt wird, dann wandern Ihre Kommentare. Unter Lazarus können Sie eine 'find declaration' sogar für Code in den Kommentaren erstellen. Obwohl dies nicht komplett zuverlässig ist, funktioniert es oftmals. Und wenn neuer Code eingefügt ist, dann benutzt die IDE einige heuristische Methoden, um Kommentare und Code zusammen zu halten. Zum Beispiel: Es wird die Zeile "c: char; // comment" nicht aufgeteilt.
  
Delphi's "Code Completion" (Ctrl+Space) wird "Identifier Completion" genannt unter Lazarus. Der Lazarus Begriff "Code Completion" ist ein Feature, welches "Automatic Class Completion" (das gleiche wie unter Delphi), "Local Variable Completion" und "Event Assignment Completion" kombiniert. Alle von ihnen werden augerufen mit Ctrl+Shift+C und die IDE ermittelt über die Cursor Position, was gemeint ist.
+
Delphi's "Code Completion" (Strg+Space) wird "Bezeichner-Vervollständigung" genannt unter Lazarus. Der Lazarus Begriff "Codevervollständigung" ist ein Werkzeug, das automatische "Klassenvervollständigung" (das gleiche wie unter Delphi), "Local Variable Completion" und "Event Assignment Completion" kombiniert. Alle von ihnen werden mit Strg+Shift+C aufgerufen und die IDE ermittelt über die Cursorposition, was gemeint ist.
 
+
 
====Beispiel für Local Variable Completion====
+
==== Beispiel für Local Variable Completion ====
Gehen sie davon aus, daß sie gerade eine neue Methode erzeugt haben und die Anweisung schreiben "i:=3;"
+
Nehmen wir an, dass Sie gerade eine neue Methode erzeugt haben und die Anweisung lautet "i:=3;"
{| class="code"
+
<syntaxhighlight lang=pascal>procedure TForm1.DoSomething;
|- class="code"
+
begin
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;
+
   i := 3;
<div class="key">begin</div>
+
end;</syntaxhighlight>
   i:= <div class="int" style="inline">3</div>;
+
 
<div class="key">end</div>;
+
Positionieren Sie den Cursor über dem Bezeichner "i" und drücken Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|C}} und Sie erhalten:
|}
 
  
Positionieren sie den Cursor über den Bezeichner "i" und drücken sie Ctrl+Shift+C um zu erhalten:
+
<syntaxhighlight lang=pascal>procedure TForm1.DoSomething;
{| class="code"
+
var i: Integer;
|- class="code"
+
begin
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;
+
   i := 3;
<div class="key">var</div> i: Integer;
+
end;</syntaxhighlight>
<div class="key">begin</div>
 
   i:= <div class="int">3</div>;
 
<div class="key">end</div>;
 
|}
 
  
====Beispiel für Event Assignment Completion====
+
==== Beispiel für Event Assignment Completion ====
Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können sie im Quelltext Editor erhalten.<br>
+
Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können Sie im Quelltext-Editor erhalten.<br>
 
Zum Beispiel:
 
Zum Beispiel:
: Button1.OnClick:=
 
Positionieren sie den Cursor hinter den assign operator ":=" und drücken sie Ctrl+Shift+C.
 
 
 
===="Word Completion" Ctrl+W====
 
Es arbeitet ähnlich wie die "Identifier Completion", aber es funktioniert nicht mit Pascal Bezeichnern, aber mit allen Wörtern. Es läßt sie alle Wörter in allen geöffneten Dateien wählen, die mit den selben Buchstaben beginnen.
 
  
====Unterstützt Include Dateien====
+
<syntaxhighlight lang=pascal>Button1.OnClick:=</syntaxhighlight>
Delphi unterstützt es nicht, und daher haben sie wahrscheinlich noch nicht viele Include Dateien erstellt. Aber Include Dateien haben einen großen Vorteil: Sie machen es möglich, Plattform unabhängigen Code zu schreiben ohne ihren Code durch IFDEFs zu verwirren.
+
 
Zum Beispiel: Method jumping, Class Completion, find declaration, .. arbeiten alle mit Include Dateien.
+
Positionieren Sie den Cursor hinter dem Zuweisungsoperator ":=" und drücken Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|C}}.
 +
 
 +
==== Beispiel für Procedure Call Completion ====
 +
Angenommen Sie haben gerade folgende Anweisung geschrieben: "DoSomething(Width);"
 +
<syntaxhighlight lang=pascal>procedure SomeProcedure;
 +
var
 +
  Width: integer;
 +
begin
 +
  Width:=3;
 +
  DoSomething(Width);
 +
end;</syntaxhighlight>
 +
 
 +
Positionieren Sie den Cursor über dem Bezeichner "DoSomething", drücken Sie {{keypress|Strg}}+{{keypress|Shift}}+{{keypress|C}} und Sie erhalten:
 +
 
 +
<syntaxhighlight lang=pascal>procedure DoSomething(aWidth: LongInt);
 +
begin
 +
 
 +
end;
 +
 
 +
procedure SomeProcedure;
 +
var
 +
  Width: integer;
 +
begin
 +
  Width:=3;
 +
  DoSomething(Width);
 +
end;</syntaxhighlight>
 +
 
 +
==== "Wortvervollständigung" Strg+W ====
 +
Sie arbeitet ähnlich wie die "Bezeichner-Vervollständigung", aber sie funktioniert nicht nur mit Pascal-Bezeichnern, sondern mit allen Wörtern. Sie lässt Sie aus allen Wörter in allen geöffneten Dateien wählen, die mit dem selben Buchstaben beginnen.
 +
 
 +
==== Unterstützung von Include-Dateien ====
 +
Delphi unterstützt diese nicht, und daher haben Sie wahrscheinlich noch nicht viele Include-Dateien erstellt. Aber Include-Dateien haben einen großen Vorteil: Sie machen es möglich, plattform-unabhängigen Code zu schreiben ohne Ihren Code durch IFDEFs unübersichtlich zu machen.
 +
Zum Beispiel: Method jumping, Class Completion, find declaration, .. arbeiten alle mit Include-Dateien.
  
 
Es gibt viele Optionen für die Code Features.
 
Es gibt viele Optionen für die Code Features.
  
===Designer===
+
=== Designer ===
 
- Richtlinien
 
- Richtlinien
====Objekt Inspektor====
+
==== Objektinspektor ====
In den Delphi und Lazarus IDE's wird der Object Inspector benutzt, um Komponenteneigenschaften zu editieren und Ereignisse zuzuweisen etc. Die folgenden Zeilen zeigen einige kleinere Unterschiede zur Beachtung für den Gebrauch  :
+
In den Delphi und Lazarus IDE's wird der Objektinspektor benutzt, um Komponenteneigenschaften zu editieren und Ereignisse zuzuweisen etc. Die folgenden Zeilen zeigen einige kleinere Unterschiede, auf die man achten muss:
# 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"
+
# Seit Delphi5 gibt es im Objektinspektor einen Objekt-Treeview, der zum Navigieren und Auswählen von Objekten unter Darstellung ihrer Hierarchie genutzt werden kann und so wahlweise die Dropdown-Liste des Objektinspektors ersetzt. In Lazarus ist dieser Treeview fester Bestandteil des Objektinspektors und er ersetzt die Dropdown-Liste völlig. Die Anzeige kann über das Kontextmenü "Komponentenbaum anzeigen" aktiviert bzw. deaktiviert werden.
# 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.
+
# In Delphi wird ein Doppelklick auf ein leeres Ereignis automatisch eines erzeugen und den Quelltext-Editor an dieser Position öffnen, in Lazarus gibt es alternativ dazu eine Schaltfläche auf der rechten Seite der ausgewählten Drop-down-Liste, die diese Aktion ebenfalls ausführt.
# 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)".
+
# In Delphi müssen Sie den Namen eines Ereignisses in der Editierzeile manuell löschen, um Anhänge zu entfernen. In Lazarus können Sie mittels Drop-down "keine" auswählen.
# 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
+
# Ähnlich wie bei Ereignissen, wird ein Doppelklick auf normale Eigenschaften wie 'boolean' nicht den Wert ändern. Sie müssen ihn aus einer Drop-down-Liste wählen. Und um solche mit einem zugeordneten Editorformular zu öffnen, müssen Sie auf den '...'-Button rechts vom Edit/Drop-down klicken.
====Packages====
+
 
Kann Lazarus Delphi Packages installieren und verwenden?
+
==== Packages ====
 +
F: Kann Lazarus Delphi-Packages installieren und verwenden?
  
Nein, wiel sie die Delphi Compiler Magie benötigen.
+
A: Nein, weil diese auf die "Delphi Compiler Magie" angewiesen sind.
  
Brauchen wir eines speziell für Lazarus gemacht?
+
F: Brauchen wir speziell für Lazarus erstellte Packages?
  
Ja.
+
A: Ja.
Erzeugen Sie ein neues Package, speichern sie es im Package Quellen Verzeichnis (normalerweise das selbe Verzeichnis der .dpk Datei), fügen sie die LCL als benötigtes Package hinzu und schließlich füegen siw die .pas Dateien hinzu.  
+
Erzeugen Sie ein neues Package, speichern Sie es im Package-Quellen-Verzeichnis (normalerweise das selbe Verzeichnis wie das der .dpk Datei), fügen Sie die LCL als benötigtes Paket und schließlich die .pas Dateien selbst hinzu.
Sie können es installieren, oder es jetzt in ihren Projekten verwenden.  
+
Sie können es installieren oder es ab jetzt in ihren Projekten verwenden.  
Es gibt einige Unterschiede zwischen Lazarus und Delphi Packages, daher lesen sie bitte  
+
Es gibt einige Unterschiede zwischen Lazarus- und Delphi-Packages, daher lesen Sie bitte  
  
 
- die docs/Packages.txt in den Lazarus Quellen.
 
- die docs/Packages.txt in den Lazarus Quellen.
  
===VCL -> LCL===
+
=== VCL -> LCL ===
Während die VCL und die LCL beide meist den selben Zwecken dienen - zu einer Objekt orientierten Komponenten Hierarchie besonders verzahnt in Richtung Rapid Application Development, sind sie nicht identisch. Zum Beispiel während die VCL viele nicht-visuelle Komponenten mitliefert, versucht die LCL nur visuelle Komponenten zu liefern, während die meisten nicht-visuellen Komponenten (wie zum Beispiel db access) von der FCL geliefert werden, welcge in [[Free Pascal]] enthalten ist.
+
Obwohl die VCL und die LCL beide meist den selben Zwecken dienen - dem einer objekt-orientierten Komponenten-Hierarchie ausgerichtet auf Rapid Application Development - sind sie nicht identisch. Während zum Beispiel die VCL viele nicht-visuelle Komponenten enthält, versucht die LCL nur visuelle Komponenten zu liefern, während die meisten nicht-visuellen Komponenten (wie zum Beispiel db access) von der FCL zur Verfügung gestellt werden, die in [[Free Pascal/de|Free Pascal]] enthalten ist.
  
Zusätzlich mögen viele Bedienelemente, die in der VCL enthalten sind, nicht in der LCL existieren, oder umgekehrt, oder sogar wenn Bedienelemente in beiden existieren, sind sie keine Klone, und Änderungen müssen gemacht werden in Anwendungen, Komponenten und Bedienelementen wenn sie portiert werden.
+
Zusätzlich mögen viele Bedienelemente, die in der VCL enthalten sind, nicht in der LCL existieren, oder umgekehrt. Sogar wenn Bedienelemente in beiden existieren, sind VCL und LCL keine echten Klone. Und deshalb müssen Änderungen gemacht werden in Anwendungen, Komponenten und Bedienelementen, wenn sie portiert werden.
  
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.
+
Das Folgende ist eine unvollständige Beschreibung der wichtigsten Unterschiede oder Inkompatibilitäten zwischen Delphi und Lazarus für Delphi-Benutzer. Es behandelt hauptsächlich die Unterschiede der VCL von D4, teilweise aber auch D5, D6, oder D7, mit der gegenwärtigen LCL, wie sie im SVN vorliegt. Insoweit können Unterschiede zu den von Ihnen verwendeten Versionen von Delphi und LCL bestehen. Sollten Ihnen Unterschiede oder Ungenauigkeiten zwischen dem Folgenden und der aktuellen LCL oder Ihrem Delphi auffallen, dann bitten wir Sie, den vorliegenden Text entsprechend zu modifizieren oder neue Abschnitte anzufügen. Wir möchten diese Beschreibung so umfassend und aktuell wie möglich für alle Lazarus-User zur Verfügung stellen.
  
====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.  
+
In der VCL ist es ziemlich einfach und normal, einen spezifischen Schriftart-Namen und Schriftart-Eigenschaften wie 'fett' und 'kursiv' für die Bedienelemente zu benutzen. In aller Regel werden diese Voreinstellungen auch entsprechend verwendet. Im laufenden Programm können sich diese Einstellungen von den Vorgaben von Windows unterscheiden. Ferner wird die TControl.ParentFont Eigenschaft mitgeliefert, die sicher stellt, dass ein Bedienelement immer der Schriftart seiner parent's folgt.
  
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.  
+
Dies trifft in der LCL nicht immer zu. Die LCL als cross-Plattform/cross-Interface hingegen, benutzt das Widget-Toolset, das aktuell auf dem benutztem Betriebssystem verwendet wird. Wenn ihr Desktop also gerade das GTK Interface benutzt, so wird LCL immer die Themes und spezifischen Schriftarten für Schaltflächen des GTK Widget-Toolset benutzen.  
  
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.
+
Das bedeutet, dass die meisten LCL Bedienelemente dem Desktop-Design des Zielrechners entsprechen werden. Das 'Look and feel' Ihrer Programmoberfläche kann sich also auf verschiedenen Zielrechnern auch entsprechend der Desktop-Einstellungen ändern.
  
If for instance a Label with a bold/special color font is required, a TStaticText must be used instead, as TLabel is an interface specific control and all interfaces will supply a native version, and most will have default settings which will be used regardless.
+
==== Bedienelemente ziehen und andocken ====
 +
In der VCL implementieren die meisten (Win-)Bedienelemente Methoden und Callback-Funktionen für die Handhabung des Ziehens (dragging) und Andockens von Bedienelementen, z.B. Ziehen eines Bedienelements von einem Panel und Andocken an einem anderen Panel zur Laufzeit.  
  
====Control Dragging/Docking====
+
Diese Funktionalität ist in der LCL derzeit noch nicht implementiert/beendet. Sie befindet sich gegenwärtig im Anfangsstadium der Planung und stellt schon einen Teil der Kompatibilität für diesen Verhalten bereit, wenn auch nicht in exakt der selben Art und Weise.  
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.
+
Das bedeutet derzeit, dass '''kein''' Bedienelement die folgenden TControl Funktionen, Prozeduren, Eigenschaften oder Ereignisse erben/benutzen wird  -
 +
<syntaxhighlight lang=pascal>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;</syntaxhighlight>
  
This currently means that no Control will inherit/use the following TControl functions, procedures, properties, or events  -
+
dass die folgenden Klassen nicht existieren/nicht verwendet werden können -
{| class="code"
+
 
|- class="code"
+
<syntaxhighlight lang=pascal>TDragImageList = class(TCustomImageList)
| class="code" |<div class="key">Protected</div>
+
TDockZone = class
  <div class="key">function</div> GetDockEdge(MousePos: TPoint): TAlign;
+
TDockTree = class(TInterfacedObject, IDockManager)
  <div class="key">function</div> GetDragImages: TDragImageList;
+
TDragObject = class(TObject)
  <div class="key">function</div> GetFloating: Boolean;
+
TBaseDragControlObject = class(TDragObject)
  <div class="key">function</div> GetFloatingDockSiteClass: TWinControlClass;
+
TDragControlObject = class(TBaseDragControlObject)
  <div class="key">procedure</div> DoEndDrag(Target:TObject); X, Y: Integer);
+
TDragDockObject = class(TBaseDragControlObject) </syntaxhighlight>
  <div class="key">procedure</div> DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);
+
 
  <div class="key">procedure</div> DoEndDock(Target: TObject; X, Y: Integer);
+
und dass die folgenden Funktionen auch nicht benutzbar/inkompatibel sind -
  <div class="key">procedure</div> DoDock(NewDockSite: TWinControl; <div class="key">var</div> ARect: TRect);
+
 
  <div class="key">procedure</div> DoStartDock(<div class="key">var</div> DragObject: TDragObject);
+
<syntaxhighlight lang=pascal>function FindDragTarget(const Pos: TPoint;
  <div class="key">procedure</div> DragCanceled;
+
                        AllowDisabled: Boolean) : TControl;
  <div class="key">procedure</div> DragOver(Source: TObject; X, Y: Integer; State: TDragState;
+
procedure CancelDrag;
                    <div class="key">var</div> Accept: Boolean);
+
function IsDragObject(sender: TObject): Boolean;</syntaxhighlight>
  <div class="key">procedure</div> DoEndDrag(Target: TObject; X, Y: Integer);
+
 
  <div class="key">procedure</div> DoStartDrag(<div class="key">var</div> DragObject: TDragObject);
+
Der Start des Docking-Managers wird hier beschrieben: [[Anchor Docking]]
  <div class="key">procedure</div> DrawDragDockImage(DragDockObject: TDragDockObject);
+
 
  <div class="key">procedure</div> EraseDragDockImage(DragDockObject: TDragDockObject);
+
==== TEdit/TCustomEdit ====
  <div class="key">procedure</div> PositionDockRect(DragDockObject: TDragDockObject);
+
Die Edit-Bedienelemente, die grundsätzlich gleich in der LCL wie in der VCL funktionieren, besitzen einige Besonderheiten, die bei einer Konvertierung beachtet werden sollten -
  <div class="key">procedure</div> SetDragMode(Value: TDragMode);
+
# Wegen Restriktionen in den Interfaces, arbeitet TEdit.PasswordChar noch nicht mit allen Interfaces (obwohl es mit der Zeit möglich sein wird), anstelle von TCustomEdit.EchoMode sollte emPassword benutzt werden, falls der Text verborgen werden muss.
  <div class="key">property</div> DragKind: TDragKind;
+
# On Drag/Dock Ereignisse sind noch nicht implementiert. Für mehr Informationen schauen Sie bitte im vorherigen Abschnitt [[#Bedienelemente ziehen und andocken|Bedienelemente ziehen und andocken]] nach.
  <div class="key">property</div> DragCursor: TCursor;
+
# Font-Eigenschaften werden üblicherweise für die Interface-Konsistenz ignoriert, für eine detaillierte Beschreibung schauen Sie bitte [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]] an.
  <div class="key">property</div> DragMode: TDragMode;
+
 
  <div class="key">property</div> OnDragDrop: TDragDropEvent;
+
==== TDBImage ====
  <div class="key">property</div> OnDragOver: TDragOverEvent;
+
Delphi und Lazarus haben beide ein TDBImage-Steuerelement, das Bilder anzeigt, die in einem Datenbankfeld gespeichert sind. Zusätzlich speichert Lazarus Informationen über den Bildtyp in dem Datenbankfeld vor den eigentlichen Bilddaten. Siehe die Prozedur ''TDBImage.UpdateData''
  <div class="key">property</div> OnEndDock: TEndDragEvent;
+
Dies bedeutet, dass die Implementationen von Delphi und Lazarus nicht kompatibel zueinander sind.
  <div class="key">property</div> OnEndDrag: TEndDragEvent;
+
 
  <div class="key">property</div> OnStartDock: TStartDockEvent;
+
Anmerkung: Die aktuelle Entwicklerversion (r40924, April 2013) Lazarus trunk hat Änderungen implementiert, die ein Delphi-kompatibles Verhalten gestatten. Bitte sehen Sie [[Lazarus_1.2.0_release_notes#TDBImage]] für Details.
  <div class="key">property</div> OnStartDrag: TStartDragEvent;
 
<div class="key">public</div>
 
  <div class="key">function</div> Dragging: Boolean;
 
  <div class="key">function</div> ManualDock(NewDockSite: TWinControl; DropControl: TControl;
 
                    <div class="key"> </div>ControlSide: TAlign): Boolean;
 
  <div class="key">function</div> ManualFloat(ScreenPos: TRect): Boolean;
 
  <div class="key">function</div> ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;
 
                    <div class="key"> </div>DropControl: TControl; ControlSide: TAlign): Boolean;
 
  <div class="key">procedure</div> BeginDrag(Immediate: Boolean; Threshold: Integer);
 
  <div class="key">procedure</div> Dock(NewDockSite: TWinControl; ARect: TRect);
 
  <div class="key">procedure</div> DragDrop(Source: TObject; X, Y: Integer);
 
  <div class="key">procedure</div> EndDrag(Drop: Boolean);
 
  <div class="key">property</div> DockOrientation: TDockOrientation;
 
  <div class="key">property</div> Floating: Boolean;
 
  <div class="key">property</div> FloatingDockSiteClass: TWinControlClass;
 
  <div class="key">property</div> HostDockSite: TWinControl;
 
  <div class="key">property</div> LRDockWidth: Integer;
 
  <div class="key">property</div> TBDockHeight: Integer;
 
  <div class="key">property</div> UndockHeight: Integer;
 
  <div class="key">property</div> UndockWidth: Integer;
 
|}
 
  
that the following classes do not exist/are unuseable -
+
=== (optional) TSplitter -> TPairSplitter ===
{| class="code"
+
'''Bitte verbessern Sie mich'''
|- class="code"
 
| class="code" | TDragImageList = <div class="key">class</div>(TCustomImageList)
 
TDockZone = <div class="key">class</div>
 
TDockTree = <div class="key">class</div>(TInterfacedObject, IDockManager)
 
TDragObject = <div class="key">class</div>(TObject)
 
TBaseDragControlObject = <div class="key">class</div>(TDragObject)
 
TDragControlObject = <div class="key">class</div>(TBaseDragControlObject)
 
TDragDockObject = <div class="key">class</div>(TBaseDragControlObject)  
 
|}
 
and that the following functions are also unuseable/incompatible -
 
{| class="code"
 
|- class="code"
 
| class="code" | <div class="key">function</div> FindDragTarget(<div class="key">const</div> Pos: TPoint;
 
                        <div class="key"> </div>AllowDisabled: Boolean) : TControl;
 
<div class="key">procedure</div> CancelDrag;
 
<div class="key">function</div> IsDragObject(sender: TObject): Boolean;
 
|}
 
  
====TEdit/TCustomEdit====
+
Es gibt jetzt ein [[TSplitter/de|TSplitter]] Bedienelement in der LCL, so dass kein Bedarf zum Konvertieren besteht.
The Edit controls, while functioning essentialy the same in the LCL as the VCL, do have some issues to be aware of in converting -
 
# 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.
 
# On Drag/Dock Events are not yet implemented. For more information please see earlier section on [LazarusForDelphiUsers#Control Dragging/Docking|Control Dragging/Docking].
 
# Font Properties are usually ignored for interface consistancy, for detailed explanation as too why please see [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]]
 
  
===(optional) TSplitter -> TPairSplitter===
+
Nichtsdestoweniger, wenn Sie es doch wollen, hier ist es beschrieben:
'''Please Improve Me'''
 
  
There is now a TSplitter control in the LCL, so no need to convert it.
+
Das Folgende basiert lose auf den Fragen von [[User:Vincent | Vincent Snijders]] in der Mailingliste und Antworten von [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson]:
  
Nevertheless, if you want, here it is explained:
+
Das in Delphi enthaltene "Splitting"-Control, das zwischen zwei Komponenten platziert werden kann, um dem einen oder anderen mehr Platz zu geben, wird in der VCL durch einen TSplitter realisiert. Dieses wird oft benutzt, beispielsweise in Delphi zwischen dem angedockten Codeexplorer und dem Quelltextfenster.
  
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]:
+
In der LCL gibt es dafür allerdings ein eigenes Control, den TPairSplitter, das den selben Zweck erfüllt, wie der TSplitter, allerdings zu diesem nicht kompatibel ist. Es sind also, wenn Sie Ihr Programm von einem TSplitter auf einen TPairsplitter ändern wollen, einige Anpassungen nötig.
  
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.
+
;Was sind nun genau die Unterschiede?
  
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.
+
Der größte Unterschied ist, dass ein TSplitter keine "Kinder" besitzt. Stattdessen wird es zwischen zwei Controls positioniert, die mittels Align ausgerichtet werden. So erlaubt er während der Laufzeit die dynamische Größenanpassung dieser Controls. Um dies zu ermöglichen, muss links und rechts ein mittels Align ausgerichtetes Control vorhanden sein. (Beispielsweise ein links-ausgerichtetes Panel + ein links-ausgerichteter TSplitter + ein client-ausgerichtetes Panel).
  
;So what exactly are the differences?
+
In der LCL ist der TPairSplitter ein spezielles Control mit zwei Panels. Er kann nur nützlich werden, wenn die zu verändernden Controls auf beiden Panels liegen. Er vergrößert bzw. verkleinert also die beiden Panels, unabhängig davon, ob sie Komponenten enthalten oder nicht.
  
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.
+
Der andere entscheidende Unterschied ist, dass der TSplitter der VCL seine Position relativ zu den anderen Komponenten verändert, abhängig von seiner Split-Position.
  
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.
+
In der LCL dagegen besitzt der TPairSplitter durch die Panels eine absolute Position, wie andere Controls auch, die sich nach den Eigenschaften top und left richtet. So verändert sich die Position nicht automatisch, wenn die Split-Position verändert wird. Ist dies erwünscht, ist es nötig, einen entsprechenden Callback zu setzen und die entsprechenden Einstellungen zu setzen.
  
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,
+
Beispielsweise befindet sich in einem verticalen TPairSplitter eine Komponente mit alClient. Soll diese automatisch bei Größenänderungen des Formulars im Verhältnis angepasst werden, ist es nötig, im OnResize-Ereignis des Formulars die neue Position zu setzen:
  
In the LCL since the side panels are seperate 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.
+
  PairSplitter.Position := PairSplitter.Width - PairSplitter.Position;
  
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 :
+
;Wie kann ich nun existierenden Code, der TSplitter verwendet, zu TPairSplitter konvertieren?
PairSplitter.Position := PairSplitter.Width - PairSplitter.Position;
 
  
;So how can I convert existing code using TSplitter to the TPairSplitter?
+
Wenn der Splitter und die Bedienelemente in einer effektiven Funktion (wie form oncreate) erzeugt wurden, sollte die Konvertierung nicht zu schwierig sein, hauptsächlich Reorganisieren des Codes, um die Bedienelemente in der Reihenfolge der neuen Hierarchie zu erzeugen und die Vorgänger der Nachfolgerbedienelemente zu setzen, um in die left/top und right/bottom Eigenschaften des PairSplitter aufzuteilen. Ein Beispiel für die Änderungen ist -
  
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 heirarchy 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 -
 
 
{| class="code"
 
{| class="code"
 
|-  
 
|-  
| class="header" | VCL || class="header" | LCL
+
| class="header" | '''VCL''' || class="header" | '''LCL'''
 
|- class="code"
 
|- class="code"
| class="code" |<div class="key">var</div>
+
| class="code" |
  BottomPanel: TPanel<div class="symbol">;</div>
+
<syntaxhighlight lang=pascal>var  
<div></div>
+
  BottomPanel: TPanel;
  VerticalSplitter: TSplitter<div class="symbol">;</div>
+
  VerticalSplitter: TSplitter;
  LeftPanel: TPanel<div class="symbol">;</div>
+
  LeftPanel: TPanel;
  HorizontalSplitter: TSplitter<div class="symbol">;</div>
+
  HorizontalSplitter: TSplitter;
<div></div>
+
  MainPanel: TPanel;
  MainPanel: TPanel<div class="symbol">;</div>
+
 
  <div class="key">begin</div>
+
begin
  BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  BottomPanel:= TPanel.Create(Self);
  <div class="key">with</div> (BottomPanel) <div class="key">do</div>
+
  with (BottomPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Height:= <div class="int">75</div><div class="symbol">;</div>
+
    Height:= 75;
    Align:= alBottom<div class="symbol">;</div>
+
    Align:= alBottom;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  VerticalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div>
+
  VerticalSplitter:= TSplitter.Create(Self);
  <div class="key">with</div> (VerticalSplitter) <div class="key">do</div>
+
  with (VerticalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alBottom<div class="symbol">;</div>
+
    Align:= alBottom;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  HorizontalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div>
+
  HorizontalSplitter:= TSplitter.Create(Self);
  <div class="key">with</div> (HorizontalSplitter) <div class="key">do</div>
+
  with (HorizontalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    align:= alLeft<div class="symbol">;</div>
+
    align:= alLeft;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  LeftPanel:= TPanel.Create(Self);
  <div class="key">with</div> (LeftPanel) <div class="key">do</div>
+
  with (LeftPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Width:= <div class="int">125</div><div class="symbol">;</div>
+
    Width:= 125;
    Align:= alLeft<div class="symbol">;</div>
+
    Align:= alLeft;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  MainPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  MainPanel:= TPanel.Create(Self);
  <div class="key">with</div> (MainPanel) <div class="key">do</div>
+
  with (MainPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Caption:= <div class="str">'Hello'</div><div class="symbol">;</div>
+
    Caption:= 'Hello';
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div class="key">end</div>;
+
end;</syntaxhighlight>
| class="code" | <div class="key">var</div>
+
| class="code" |  
  BottomPanel: TPanel<div class="symbol">;</div>
+
<syntaxhighlight lang=pascal>var
<div></div>
+
  BottomPanel: TPanel;
  VerticalSplitter: TPairSplitter<div class="symbol">;</div>
+
  VerticalSplitter: TPairSplitter;
  LeftPanel: TPanel<div class="symbol">;</div>
+
  LeftPanel: TPanel;
  HorizontalSplitter: TPairSplitter<div class="symbol">;</div>
+
  HorizontalSplitter: TPairSplitter;
<div></div>
+
  MainPanel: TPanel;
  MainPanel: TPanel<div class="symbol">;</div>
+
 
<div class="key">begin</div>
+
begin
  VerticalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div>
+
  VerticalSplitter:= TPairSplitter.Create(Self);
  <div class="key">with</div> (VerticalSplitter) <div class="key">do</div>
+
  with (VerticalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= Self<div class="symbol">;</div>
+
    Parent:= Self;
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Width:= Self.Width<div class="symbol">;</div>
+
    Width:= Self.Width;
    Height:= Self.Height<div class="symbol">;</div>
+
    Height:= Self.Height;
    SplitterType:= pstVertical<div class="symbol">;</div>
+
    SplitterType:= pstVertical;
    Position:= Height - <div class="int">75</div><div class="symbol">;</div>
+
    Position:= Height - 75;
    Sides[<div class="int">0</div>].Width:= Width<div class="symbol">;</div>
+
    Sides[0].Width:= Width;
    Sides[<div class="int">0</div>].Height:= Position<div class="symbol">;</div>
+
    Sides[0].Height:= Position;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  HorizontalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div>
+
  HorizontalSplitter:= TPairSplitter.Create(Self);
  <div class="key">with</div> (HorizontalSplitter) <div class="key">do</div>
+
  with (HorizontalSplitter) do
  <div class="key">begin</div>
+
  begin
    Parent:= VerticalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div>
+
    Parent:= VerticalSplitter.Sides[0];
    Width:= Self.Width<div class="symbol">;</div>
+
    Width:= Self.Width;
    Height:= VerticalSplitter.Position<div class="symbol">;</div>
+
    Height:= VerticalSplitter.Position;
    align:= alClient<div class="symbol">;</div>
+
    align:= alClient;
    SplitterType:= pstHorizontal<div class="symbol">;</div>
+
    SplitterType:= pstHorizontal;
    Position:= <div class="int">125</div><div class="symbol">;</div>
+
    Position:= 125;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  LeftPanel:= TPanel.Create(Self);
  <div class="key">with</div> (LeftPanel) <div class="key">do</div>
+
  with (LeftPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= HorizontalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div>
+
    Parent:= HorizontalSplitter.Sides[0];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  MainPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  MainPanel:= TPanel.Create(Self);
  <div class="key">with</div> (MainPanel) <div class="key">do</div>
+
  with (MainPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= HorizontalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div>
+
    Parent:= HorizontalSplitter.Sides[1];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
    Caption:= <div class="str">'Hello'</div><div class="symbol">;</div>
+
    Caption:= 'Hello';
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div></div>
+
 
  BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div>
+
  BottomPanel:= TPanel.Create(Self);
  <div class="key">with</div> (BottomPanel) <div class="key">do</div>
+
  with (BottomPanel) do
  <div class="key">begin</div>
+
  begin
    Parent:= VerticalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div>
+
    Parent:= VerticalSplitter.Sides[1];
    Align:= alClient<div class="symbol">;</div>
+
    Align:= alClient;
  <div class="key">end</div><div class="symbol">;</div>
+
  end;
<div class="key">end</div><div class="symbol">;</div>
+
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.
+
Wie man sieht, ist es ziemlich konsistent mit den meisten Kontrollhierarchien. Wenn Sie mit DFM vertraut sind, sollten die notwendigen Änderungen für eine DFM -> LFM Konversion offensichtlich sein, da sie die selbe Art von Änderungen in Parent/Owner darstellen.
 +
 
 +
Das obige Beispiel würde in etwa so aussehen -
  
So the above example would be something like -
 
  
 
{| class="code"
 
{| class="code"
 
|-  
 
|-  
| class="header" | Delphi DFM <div style="font-weight: normal">(exteranous values removed)</div>
+
| class="header" | '''Delphi DFM''' <div style="font-weight: normal">'''(weitere Werte wurden entfernt)'''
| class="header" | Lazarus LFM <div style="font-weight: normal">(most width, height etc removed)</div>
+
| class="header" | '''Lazarus LFM''' <div style="font-weight: normal">'''(width, height, etc. entfernt)'''
 
|- class="code"
 
|- class="code"
| class="code" |<div class="key">object</div>VerticalSplitter: TSplitter
+
| class="code" |
   Height <div class="symbol">=</div> <div class="int">3</div>
+
<syntaxhighlight lang=pascal>object VerticalSplitter: TSplitter
   Cursor <div class="symbol">=</div> crVSplit
+
   Height = 3
   Align <div class="symbol">=</div> alBottom
+
   Cursor = crVSplit
<div class="key">end</div>
+
   Align = alBottom
<div class="key">object</div> HorizontalSplitter: TSplitter
+
end
   Width <div class="symbol">=</div> <div class="int">3</div>
+
object HorizontalSplitter: TSplitter
   Align <div class="symbol">=</div> alLeft
+
   Width = 3
<div class="key">end</div>
+
   Align = alLeft
<div class="key">object</div> BottomPanel: TPanel
+
end
   Height <div class="symbol">=</div> <div class="int">75</div>
+
object BottomPanel: TPanel
   Align <div class="symbol">=</div> alBottom
+
   Height = 75
<div class="key">end</div>
+
   Align = alBottom
<div class="key">object</div> LeftPanel: TPanel
+
end
   Width <div class="symbol">=</div> <div class="int">125</div>
+
object LeftPanel: TPanel
   Align <div class="symbol">=</div> alLeft
+
   Width = 125
<div class="key">end</div>
+
   Align = alLeft
<div class="key">object</div> MainPanel: TPanel
+
end
   Align <div class="symbol">=</div> alClient
+
object MainPanel: TPanel
<div class="key">end</div>  
+
   Align = alClient
| class="code" |<div class="key">object</div> VerticalSplitter: TPairSplitter
+
end</syntaxhighlight>
   Align <div class="symbol">=</div> alClient
+
| class="code" |
   SplitterType <div class="symbol">=</div> pstVertical
+
<syntaxhighlight lang=pascal>object VerticalSplitter: TPairSplitter
   Position <div class="symbol">=</div> <div class="int">225</div>
+
   Align = alClient
   Height <div class="symbol">=</div> <div class="int">300</div>
+
   SplitterType = pstVertical
   Width <div class="symbol">=</div> <div class="int">400</div>
+
   Position = 225
   <div class="key">object</div> Pairsplitterside1: TPairSplitterIde
+
   Height = 300
     <div class="key">object</div> HorizontalSplitter: TPairSplitter
+
   Width = 400
       Align <div class="symbol">=</div> alClient
+
   object Pairsplitterside1: TPairSplitterIde
       Position <div class="symbol">=</div> <div class="int">125</div>
+
     object HorizontalSplitter: TPairSplitter
       <div class="key">object</div> Pairsplitterside3: TPairSplitterIde
+
       Align = alClient
         Width <div class="symbol">=</div> <div class="int">125</div>
+
       Position = 125
         <div class="key">object</div> LeftPanel: TPanel
+
       object Pairsplitterside3: TPairSplitterIde
           Align <div class="symbol">=</div> alClient
+
         Width = 125
           Width <div class="symbol">=</div> <div class="int">125</div>
+
         object LeftPanel: TPanel
         <div class="key">end</div>
+
           Align = alClient
       <div class="key">end</div>
+
           Width = 125
       <div class="key">object</div> Pairsplitterside4: TPairSplitterIde
+
         end
         <div class="key">object</div> MainPanel: TPanel
+
       end
           Align <div class="symbol">=</div> alClient
+
       object Pairsplitterside4: TPairSplitterIde
         <div class="key">end</div>
+
         object MainPanel: TPanel
       <div class="key">end</div>
+
           Align = alClient
     <div class="key">end</div>
+
         end
   <div class="key">end</div>
+
       end
   <div class="key">object</div> Pairsplitterside2: TPairSplitterIde
+
     end
     <div class="key">object</div> BottomPanel: TPanel
+
   end
       Align <div class="symbol">=</div> alClient
+
   object Pairsplitterside2: TPairSplitterIde
       Height <div class="symbol">=</div> <div class="int">75</div>
+
     object BottomPanel: TPanel
     <div class="key">end</div>
+
       Align = alClient
   <div class="key">end</div>
+
       Height = 75
<div class="key">end</div>
+
     end
 +
   end
 +
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 -
+
Beide, VCL und die LCL, bieten eine TCustomTreeView/TTreeView Komponente, die für in Bäumen strukturierte Datenlisten mit mehrfachen Knoten und erweiterter Auswahl sowie für Bilderlisten benutzt wird. Und obwohl einige Features vergleichbar sind, sind nicht alle Eigenschaften völlig kompatibel. Hauptsächliche Unterschiede sind folgende -
  
'''Incomplete list, also update to include TCustomTreeView Mark functions and protected methods '''
+
'''Unvollständige Liste (sollte aktualisiert werden, um die TCustomTreeView-Markierungsfunktionen und geschützten Methoden zu enthalten) '''
  
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 :
+
Die LCL bietet TCustomTreeView.Options, eine Reihe von Optionen, die im Bedienelement eingestellt werden können, um sein Verhalten und Erscheinungbild ändern. Diese Optionen sind :
 
#* tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL
 
#* tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL
 
#* tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand
 
#* tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand
 
#* tvoAutoInsertMark - Update the Drag preview on mouse move.
 
#* tvoAutoInsertMark - Update the Drag preview on mouse move.
#* tvoAutoItemHeight - Adjust the item heights automatically.
+
#* tvoAutoItemHeight - Passt die Item Höhen automatisch an.
#* tvoHideSelection - Do not mark the selected item.
+
#* tvoHideSelection - Markiert das gewählte Item nicht.
 
#* tvoHotTrack  - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack
 
#* tvoHotTrack  - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack
 
#* tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes
 
#* tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes
 
#* tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly
 
#* tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly
 
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
 
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
#* tvoRowSelect  - allow selecting rows, equivalent to enabling TCustomTreeView.RowSelect
+
#* tvoRowSelect  - Erlaubt das Auswählen von Zeilen, entsprechend der Ermöglichung von TCustomTreeView.RowSelect
#* tvoShowButtons  - show buttons, equivalent to enabling TCustomTreeView.ShowButtons
+
#* tvoShowButtons  - Zeigt Schaltflächen, entsprechend der Ermöglichung von TCustomTreeView.ShowButtons
 
#* tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
 
#* tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
 
#* tvoShowRoot  - show root note, equivalent to enabling TCustomTreeView.ShowRoot
 
#* tvoShowRoot  - show root note, equivalent to enabling TCustomTreeView.ShowRoot
#* tvoShowSeparators  - show seperators
+
#* tvoShowSeparators  - zeigt Begrenzungszeichen
 
#* tvoToolTips - show tooltips for individual nodes
 
#* tvoToolTips - show tooltips for individual nodes
# The LCL provides additional properties:
+
# Die LCL bietet zusätzliche Eigenschaften:
#* TCustomTreeView.OnSelectionChange event
+
#* TCustomTreeView.OnSelectionChange Ereignis
#* TCustomTreeView.DefaultItems, for the default number of Items
+
#* TCustomTreeView.DefaultItems, für die Standardanzahl von Items
 
#* TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
 
#* TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
# 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.
+
# Obwohl die meisten On Drag/Dock Ereignisse in der LCL verfügbar sind, funktionieren sie nicht. Für mehr Informationen lesen Ssie bitte den früheren Abschnitt über 'Bedienelemente ziehen und andocken'.
 +
 
 +
=== Nachrichten / Ereignisse ===
 +
 
 +
Die Reihenfolge und Häufigkeit von Nachrichten (Messages) und Ereignissen (Events) (OnShow, OnActivate, OnEnter, ...) unterscheiden sich von der VCL und hängen vom [[Widgetset]] ab.
 +
Die LCL stellt eine Untermenge von WinAPI-ähnlichen Nachrichten zur Verfügung, um das Portieren von Delphi-Komponenten zu erleichtern, aber fast alle LCL-Nachrichten arbeiten etwas anders als die VCL/WinAPI Gegenstücke. Der größte Teil des Delphi Codes, der WinAPI-Nachrichten benutzt, benutzt sie auch deshalb, weil der VCL ein Feature fehlt oder die VCL zu langsam ist. Solcher Code funktioniert unter der LCL selten genau so und muss sorgfältig und von Hand überprüft werden. Deshalb heißen LCL Nachrichten zum Beispiel LM_SIZE (aus der Unit lmessages) und nicht WM_SIZE.
 +
 
 +
'''Anmerkung über den Umgang mit benutzerdefinierten Nachrichten!'''
 +
Seit der Version 0.9.26 (Dezember 2008), unterscheidet sich der Umgang mit benutzerdefinierten WinAPI-Nachrichten (z.B. WM_HOTKEY, WM_SYSCOMMAND)  von der Art, wie Delphi diese Nachrichten behandelt. Derzeit können Sie diese nicht mittels der Direktive '''message''' oder durch Überschreiben der ''WndProc''-Methode des Formulars ansprechen. Der einzige Weg dazu besteht darin, im Formular selbst einen Hook auf Windows ''windowproc'' anzulegen. Lesen Sie hier weiter: [[Win32/64_Interface#Processing_non-user_messages_in_your_window | Processing non-user messages in your window]]
 +
 
 +
==Siehe auch==
  
==Mitwirkende und Änderungen==
+
* [[Code Conversion Guide| Code Conversion Guide (from Delphi & Kylix)]]
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusForDelphiUsers Version] konvertiert.
+
* [[Compile With Delphi]]
* Initial import and formatting - [[User:Tom | VlxAdmin]] 9/26/2003
 
* Begin VCL -> LCL with a section on TSplitter -> TPairSplitter - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003
 
* Add TControl.Font/TControl.ParentFont to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003
 
* Update TEdit/TCustomEdit section in VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003
 
* Add Control Dragging/Docking to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003
 
* Added "Object Inspector" to Delphi IDE -> Lazarus IDE - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003
 
* Added initial "TCustomTreeView/TTreeView" to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003
 
* Added introduction to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003
 
* Fixed some typos - [[User:Vincent | Vincent]] 10/2/2003
 
* Fixed Typo [[User:Kirkpatc]] 20 May 2004
 

Latest revision as of 00:52, 19 February 2020

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

Zurück zu den Zusätzlichen Informationen.

Diese Beschreibung ist für Leute gedacht, die an Lazarus interessiert sind und Delphi bereits kennen. Sie beschreibt die Unterschiede zwischen den beiden.

Delphi -> Lazarus

Lazarus ist ein Rapid Application Development (RAD) Tool wie Delphi. Das bedeutet, es enthält eine visuelle Komponentenbibliothek und eine IDE. Die Lazarus Component Library (LCL) ist sehr ähnlich zu Delphi's VCL. Die meisten Units, Klassen und Eigenschaften haben den selben Namen und die selbe Funktionalität. Dies macht eine Portierung (von Delphi zu Lazarus) einfach. Aber Lazarus ist kein 'Open Source Delphi Klon'. Erwarten Sie daher keine 100%ige Kompatibilität.

Die größten Unterschiede

Lazarus ist komplett Open Source, ist plattformunabhängig geschrieben und benutzt den mächtigen Free Pascal Compiler (FPC). FPC läuft auf mehr als 15 Plattformen. Aber nicht alle Packages und Bibliotheken sind portiert, so dass Lazarus gegenwärtig unter Linux (i386, x86_64), FreeBSD (i386), Mac OS X (powerpc, i386) und Windows (i386, x86_64) läuft.

Lazarus ist nicht komplett, genau so wenig wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... .

Die erste Aktion bei der Konvertierung eines Delphi-Projekts

Nachdem Lazarus gestartet ist, gehen Sie zu Werkzeuge und dann zu Delphi- in Lazarus-Project umwandeln. Das wird nicht alles für Sie erledigen, Sie aber ein gutes Stück weiter bringen. Beachten Sie, dass die Konvertierungstools der Lazarus-IDE generell nur Einweg-Konvertierungen durchführen. Falls Sie die Kompatibilität zu Delphi aufrecht halten müssen, sodass Sie Ihr Projekt sowohl mit Delphi als auch mit Lazarus kompilieren können, versuchen Sie stattdessen Ihre Dateien mit dem XDev Toolkit zu konvertieren.

Unicode-Unterstützung

Die Versionen von Delphi bis zu Delphi 2007 hatten keine Unterstützung von Unicode, aber verwendeten die Windows-ANSI-Kodierung. Delphi unterstützt Unicode mit in UTF-16 kodierten Zeichenketten seit der Version 2009.

Lazarus startete im Gegensatz dazu seine Unicode-Unterstützung früher und verwendet in UTF-8 kodierte Zeichenketten. Für weitere Informationen siehe LCL Unicode Support.

Delphi IDE -> Lazarus IDE

Projekte

Die Hauptdatei einer Delphi Anwendung ist die .dpr Datei. Die Hauptdatei eines Lazarus Projekts ist die .lpi Datei (Lazarus Project Information). Eine .dpr Datei ist die Hauptquelle eines Programms und die Delphi IDE speichert hier einige Informationen über die Compiler-Schalter und Units. Eine Lazarus-Anwendung hat auch eine .lpr Datei, die auch die wichtigste Quelldatei ist. Aber alle anderen Informationen werden in der .lpi Datei gespeichert. Daher ist die .lpi Datei die wichtigste Datei.

Zum Beispiel:

Delphi speichert die Pfade der Units in der .dpr-Datei. Beispielsweise: unit1 in 'path/Unit1.pas'. Diese 'in'-Pfade sind Delphispezifisch und werden nicht von der Lazarus-IDE gelesen. Verwenden Sie sie nicht. Benutzen Sie stattdessen die Unitpfade der Compilereinstellungen.

Delphi speichert Compilereinstellungen in der .dpr-Datei. Beispielsweise {$APPTYPE CONSOLE}. Diese werden von der Lazarus-IDE ignoriert. Verwenden Sie sie nicht. Benutzen Sie stattdessen die Compilereinstellungen.


Eine wichtige Regel: Es gibt immer ein Projekt. Der einzige Weg, um ein Projekt "zu beenden", ist, Lazarus zu beenden oder ein anderes Projekt zu öffnen. Das ist so, weil ein Lazarus Projekt auch eine "Sitzung" ist. Das bedeutet, dass die aktuellen Editoreinstellungen auch in der .lpi Datei gespeichert sind und wiederhergestellt werden, wenn sie das Projekt wieder öffnen. Zum Beispiel: Sie debuggen eine Anwendung, setzen eine Menge Haltepunkte (Breakpoints) und Lesezeichen (Bookmarks). Sie können das Projekt jederzeit speichern, Lazarus schließen oder ein anderes Projekt öffnen. Wenn Sie das Projekt wieder öffnen, sogar auf einem anderen Computer, werden alle Ihre Haltepunkte, Lesezeichen, geöffneten Dateien, Cursorpositionen, Sprunghistorie, ... wieder hergestellt.

Quelltext-Editor

Nahezu alle Tasten und Tastenkürzel (short cuts) können unter 'Einstellungen -> Editoreinstellungen -> Tastaturbelegung' festgelegt werden.

Die Lazarus IDE besitzt eine Menge von Werkzeugen für Quelltexte. Viele von ihnen sehen aus und arbeiten sehr ähnlich wie Delphi. Aber es gibt einen wichtigen Unterschied: Lazarus benutzt nicht den Compiler, um Code-Informationen zu erhalten. Es analysiert die Quelltexte direkt. Dies hat eine Menge von bedeutenden Vorteilen:

Der Quelltext-Editor berücksichtigt Kommentare. Für Delphi sind die Kommentare in den Quellen einfach nur Leerzeichen im Code. Kein Code-Werkzeug funktioniert dort und wenn neuer Code automatisch eingefügt wird, dann wandern Ihre Kommentare. Unter Lazarus können Sie eine 'find declaration' sogar für Code in den Kommentaren erstellen. Obwohl dies nicht komplett zuverlässig ist, funktioniert es oftmals. Und wenn neuer Code eingefügt ist, dann benutzt die IDE einige heuristische Methoden, um Kommentare und Code zusammen zu halten. Zum Beispiel: Es wird die Zeile "c: char; // comment" nicht aufgeteilt.

Delphi's "Code Completion" (Strg+Space) wird "Bezeichner-Vervollständigung" genannt unter Lazarus. Der Lazarus Begriff "Codevervollständigung" ist ein Werkzeug, das automatische "Klassenvervollständigung" (das gleiche wie unter Delphi), "Local Variable Completion" und "Event Assignment Completion" kombiniert. Alle von ihnen werden mit Strg+Shift+C aufgerufen und die IDE ermittelt über die Cursorposition, was gemeint ist.

Beispiel für Local Variable Completion

Nehmen wir an, dass Sie gerade eine neue Methode erzeugt haben und die Anweisung lautet "i:=3;"

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

Positionieren Sie den Cursor über dem Bezeichner "i" und drücken Sie Strg+ Shift+C und Sie erhalten:

procedure TForm1.DoSomething;
var i: Integer;
begin
  i := 3;
end;

Beispiel für Event Assignment Completion

Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können Sie im Quelltext-Editor erhalten.
Zum Beispiel:

Button1.OnClick:=

Positionieren Sie den Cursor hinter dem Zuweisungsoperator ":=" und drücken Sie Strg+ Shift+C.

Beispiel für Procedure Call Completion

Angenommen Sie haben gerade folgende Anweisung geschrieben: "DoSomething(Width);"

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

Positionieren Sie den Cursor über dem Bezeichner "DoSomething", drücken Sie Strg+ Shift+C und Sie erhalten:

procedure DoSomething(aWidth: LongInt);
begin

end;

procedure SomeProcedure;
var
  Width: integer;
begin
  Width:=3;
  DoSomething(Width);
end;

"Wortvervollständigung" Strg+W

Sie arbeitet ähnlich wie die "Bezeichner-Vervollständigung", aber sie funktioniert nicht nur mit Pascal-Bezeichnern, sondern mit allen Wörtern. Sie lässt Sie aus allen Wörter in allen geöffneten Dateien wählen, die mit dem selben Buchstaben beginnen.

Unterstützung von Include-Dateien

Delphi unterstützt diese nicht, und daher haben Sie wahrscheinlich noch nicht viele Include-Dateien erstellt. Aber Include-Dateien haben einen großen Vorteil: Sie machen es möglich, plattform-unabhängigen Code zu schreiben ohne Ihren Code durch IFDEFs unübersichtlich zu machen. Zum Beispiel: Method jumping, Class Completion, find declaration, .. arbeiten alle mit Include-Dateien.

Es gibt viele Optionen für die Code Features.

Designer

- Richtlinien

Objektinspektor

In den Delphi und Lazarus IDE's wird der Objektinspektor benutzt, um Komponenteneigenschaften zu editieren und Ereignisse zuzuweisen etc. Die folgenden Zeilen zeigen einige kleinere Unterschiede, auf die man achten muss:

  1. Seit Delphi5 gibt es im Objektinspektor einen Objekt-Treeview, der zum Navigieren und Auswählen von Objekten unter Darstellung ihrer Hierarchie genutzt werden kann und so wahlweise die Dropdown-Liste des Objektinspektors ersetzt. In Lazarus ist dieser Treeview fester Bestandteil des Objektinspektors und er ersetzt die Dropdown-Liste völlig. Die Anzeige kann über das Kontextmenü "Komponentenbaum anzeigen" aktiviert bzw. deaktiviert werden.
  2. In Delphi wird ein Doppelklick auf ein leeres Ereignis automatisch eines erzeugen und den Quelltext-Editor an dieser Position öffnen, in Lazarus gibt es alternativ dazu eine Schaltfläche auf der rechten Seite der ausgewählten Drop-down-Liste, die diese Aktion ebenfalls ausführt.
  3. In Delphi müssen Sie den Namen eines Ereignisses in der Editierzeile manuell löschen, um Anhänge zu entfernen. In Lazarus können Sie mittels Drop-down "keine" auswählen.
  4. Ähnlich wie bei Ereignissen, wird ein Doppelklick auf normale Eigenschaften wie 'boolean' nicht den Wert ändern. Sie müssen ihn aus einer Drop-down-Liste wählen. Und um solche mit einem zugeordneten Editorformular zu öffnen, müssen Sie auf den '...'-Button rechts vom Edit/Drop-down klicken.

Packages

F: Kann Lazarus Delphi-Packages installieren und verwenden?

A: Nein, weil diese auf die "Delphi Compiler Magie" angewiesen sind.

F: Brauchen wir speziell für Lazarus erstellte Packages?

A: Ja. Erzeugen Sie ein neues Package, speichern Sie es im Package-Quellen-Verzeichnis (normalerweise das selbe Verzeichnis wie das der .dpk Datei), fügen Sie die LCL als benötigtes Paket und schließlich die .pas Dateien selbst hinzu. Sie können es installieren oder es ab jetzt in ihren Projekten verwenden. Es gibt einige Unterschiede zwischen Lazarus- und Delphi-Packages, daher lesen Sie bitte

- die docs/Packages.txt in den Lazarus Quellen.

VCL -> LCL

Obwohl die VCL und die LCL beide meist den selben Zwecken dienen - dem einer objekt-orientierten Komponenten-Hierarchie ausgerichtet auf Rapid Application Development - sind sie nicht identisch. Während zum Beispiel die VCL viele nicht-visuelle Komponenten enthält, versucht die LCL nur visuelle Komponenten zu liefern, während die meisten nicht-visuellen Komponenten (wie zum Beispiel db access) von der FCL zur Verfügung gestellt werden, die in Free Pascal enthalten ist.

Zusätzlich mögen viele Bedienelemente, die in der VCL enthalten sind, nicht in der LCL existieren, oder umgekehrt. Sogar wenn Bedienelemente in beiden existieren, sind VCL und LCL keine echten Klone. Und deshalb müssen Änderungen gemacht werden in Anwendungen, Komponenten und Bedienelementen, wenn sie portiert werden.

Das Folgende ist eine unvollständige Beschreibung der wichtigsten Unterschiede oder Inkompatibilitäten zwischen Delphi und Lazarus für Delphi-Benutzer. Es behandelt hauptsächlich die Unterschiede der VCL von D4, teilweise aber auch D5, D6, oder D7, mit der gegenwärtigen LCL, wie sie im SVN vorliegt. Insoweit können Unterschiede zu den von Ihnen verwendeten Versionen von Delphi und LCL bestehen. Sollten Ihnen Unterschiede oder Ungenauigkeiten zwischen dem Folgenden und der aktuellen LCL oder Ihrem Delphi auffallen, dann bitten wir Sie, den vorliegenden Text entsprechend zu modifizieren oder neue Abschnitte anzufügen. Wir möchten diese Beschreibung so umfassend und aktuell wie möglich für alle Lazarus-User zur Verfügung stellen.

TControl.Font/TControl.ParentFont

In der VCL ist es ziemlich einfach und normal, einen spezifischen Schriftart-Namen und Schriftart-Eigenschaften wie 'fett' und 'kursiv' für die Bedienelemente zu benutzen. In aller Regel werden diese Voreinstellungen auch entsprechend verwendet. Im laufenden Programm können sich diese Einstellungen von den Vorgaben von Windows unterscheiden. Ferner wird die TControl.ParentFont Eigenschaft mitgeliefert, die sicher stellt, dass ein Bedienelement immer der Schriftart seiner parent's folgt.

Dies trifft in der LCL nicht immer zu. Die LCL als cross-Plattform/cross-Interface hingegen, benutzt das Widget-Toolset, das aktuell auf dem benutztem Betriebssystem verwendet wird. Wenn ihr Desktop also gerade das GTK Interface benutzt, so wird LCL immer die Themes und spezifischen Schriftarten für Schaltflächen des GTK Widget-Toolset benutzen.

Das bedeutet, dass die meisten LCL Bedienelemente dem Desktop-Design des Zielrechners entsprechen werden. Das 'Look and feel' Ihrer Programmoberfläche kann sich also auf verschiedenen Zielrechnern auch entsprechend der Desktop-Einstellungen ändern.

Bedienelemente ziehen und andocken

In der VCL implementieren die meisten (Win-)Bedienelemente Methoden und Callback-Funktionen für die Handhabung des Ziehens (dragging) und Andockens von Bedienelementen, z.B. Ziehen eines Bedienelements von einem Panel und Andocken an einem anderen Panel zur Laufzeit.

Diese Funktionalität ist in der LCL derzeit noch nicht implementiert/beendet. Sie befindet sich gegenwärtig im Anfangsstadium der Planung und stellt schon einen Teil der Kompatibilität für diesen Verhalten bereit, wenn auch nicht in exakt der selben Art und Weise.

Das bedeutet derzeit, dass kein Bedienelement die folgenden TControl Funktionen, Prozeduren, Eigenschaften oder Ereignisse erben/benutzen wird -

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;

dass die folgenden Klassen nicht existieren/nicht verwendet werden können -

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

und dass die folgenden Funktionen auch nicht benutzbar/inkompatibel sind -

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

Der Start des Docking-Managers wird hier beschrieben: Anchor Docking

TEdit/TCustomEdit

Die Edit-Bedienelemente, die grundsätzlich gleich in der LCL wie in der VCL funktionieren, besitzen einige Besonderheiten, die bei einer Konvertierung beachtet werden sollten -

  1. Wegen Restriktionen in den Interfaces, arbeitet TEdit.PasswordChar noch nicht mit allen Interfaces (obwohl es mit der Zeit möglich sein wird), anstelle von TCustomEdit.EchoMode sollte emPassword benutzt werden, falls der Text verborgen werden muss.
  2. On Drag/Dock Ereignisse sind noch nicht implementiert. Für mehr Informationen schauen Sie bitte im vorherigen Abschnitt Bedienelemente ziehen und andocken nach.
  3. Font-Eigenschaften werden üblicherweise für die Interface-Konsistenz ignoriert, für eine detaillierte Beschreibung schauen Sie bitte TControl.Font/TControl.ParentFont an.

TDBImage

Delphi und Lazarus haben beide ein TDBImage-Steuerelement, das Bilder anzeigt, die in einem Datenbankfeld gespeichert sind. Zusätzlich speichert Lazarus Informationen über den Bildtyp in dem Datenbankfeld vor den eigentlichen Bilddaten. Siehe die Prozedur TDBImage.UpdateData Dies bedeutet, dass die Implementationen von Delphi und Lazarus nicht kompatibel zueinander sind.

Anmerkung: Die aktuelle Entwicklerversion (r40924, April 2013) Lazarus trunk hat Änderungen implementiert, die ein Delphi-kompatibles Verhalten gestatten. Bitte sehen Sie Lazarus_1.2.0_release_notes#TDBImage für Details.

(optional) TSplitter -> TPairSplitter

Bitte verbessern Sie mich

Es gibt jetzt ein TSplitter Bedienelement in der LCL, so dass kein Bedarf zum Konvertieren besteht.

Nichtsdestoweniger, wenn Sie es doch wollen, hier ist es beschrieben:

Das Folgende basiert lose auf den Fragen von Vincent Snijders in der Mailingliste und Antworten von Andrew Johnson:

Das in Delphi enthaltene "Splitting"-Control, das zwischen zwei Komponenten platziert werden kann, um dem einen oder anderen mehr Platz zu geben, wird in der VCL durch einen TSplitter realisiert. Dieses wird oft benutzt, beispielsweise in Delphi zwischen dem angedockten Codeexplorer und dem Quelltextfenster.

In der LCL gibt es dafür allerdings ein eigenes Control, den TPairSplitter, das den selben Zweck erfüllt, wie der TSplitter, allerdings zu diesem nicht kompatibel ist. Es sind also, wenn Sie Ihr Programm von einem TSplitter auf einen TPairsplitter ändern wollen, einige Anpassungen nötig.

Was sind nun genau die Unterschiede?

Der größte Unterschied ist, dass ein TSplitter keine "Kinder" besitzt. Stattdessen wird es zwischen zwei Controls positioniert, die mittels Align ausgerichtet werden. So erlaubt er während der Laufzeit die dynamische Größenanpassung dieser Controls. Um dies zu ermöglichen, muss links und rechts ein mittels Align ausgerichtetes Control vorhanden sein. (Beispielsweise ein links-ausgerichtetes Panel + ein links-ausgerichteter TSplitter + ein client-ausgerichtetes Panel).

In der LCL ist der TPairSplitter ein spezielles Control mit zwei Panels. Er kann nur nützlich werden, wenn die zu verändernden Controls auf beiden Panels liegen. Er vergrößert bzw. verkleinert also die beiden Panels, unabhängig davon, ob sie Komponenten enthalten oder nicht.

Der andere entscheidende Unterschied ist, dass der TSplitter der VCL seine Position relativ zu den anderen Komponenten verändert, abhängig von seiner Split-Position.

In der LCL dagegen besitzt der TPairSplitter durch die Panels eine absolute Position, wie andere Controls auch, die sich nach den Eigenschaften top und left richtet. So verändert sich die Position nicht automatisch, wenn die Split-Position verändert wird. Ist dies erwünscht, ist es nötig, einen entsprechenden Callback zu setzen und die entsprechenden Einstellungen zu setzen.

Beispielsweise befindet sich in einem verticalen TPairSplitter eine Komponente mit alClient. Soll diese automatisch bei Größenänderungen des Formulars im Verhältnis angepasst werden, ist es nötig, im OnResize-Ereignis des Formulars die neue Position zu setzen:

 PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; 
Wie kann ich nun existierenden Code, der TSplitter verwendet, zu TPairSplitter konvertieren?

Wenn der Splitter und die Bedienelemente in einer effektiven Funktion (wie form oncreate) erzeugt wurden, sollte die Konvertierung nicht zu schwierig sein, hauptsächlich Reorganisieren des Codes, um die Bedienelemente in der Reihenfolge der neuen Hierarchie zu erzeugen und die Vorgänger der Nachfolgerbedienelemente zu setzen, um in die left/top und right/bottom Eigenschaften des PairSplitter aufzuteilen. Ein Beispiel für die Änderungen ist -

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;

Wie man sieht, ist es ziemlich konsistent mit den meisten Kontrollhierarchien. Wenn Sie mit DFM vertraut sind, sollten die notwendigen Änderungen für eine DFM -> LFM Konversion offensichtlich sein, da sie die selbe Art von Änderungen in Parent/Owner darstellen.

Das obige Beispiel würde in etwa so aussehen -


Delphi DFM
(weitere Werte wurden entfernt)
Lazarus LFM
(width, height, etc. entfernt)
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

Beide, VCL und die LCL, bieten eine TCustomTreeView/TTreeView Komponente, die für in Bäumen strukturierte Datenlisten mit mehrfachen Knoten und erweiterter Auswahl sowie für Bilderlisten benutzt wird. Und obwohl einige Features vergleichbar sind, sind nicht alle Eigenschaften völlig kompatibel. Hauptsächliche Unterschiede sind folgende -

Unvollständige Liste (sollte aktualisiert werden, um die TCustomTreeView-Markierungsfunktionen und geschützten Methoden zu enthalten)

  1. Die LCL bietet TCustomTreeView.Options, eine Reihe von Optionen, die im Bedienelement eingestellt werden können, um sein Verhalten und Erscheinungbild ändern. Diese Optionen sind :
    • 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 - Passt die Item Höhen automatisch an.
    • tvoHideSelection - Markiert das gewählte Item nicht.
    • 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 - Erlaubt das Auswählen von Zeilen, entsprechend der Ermöglichung von TCustomTreeView.RowSelect
    • tvoShowButtons - Zeigt Schaltflächen, entsprechend der Ermöglichung von TCustomTreeView.ShowButtons
    • tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
    • tvoShowRoot - show root note, equivalent to enabling TCustomTreeView.ShowRoot
    • tvoShowSeparators - zeigt Begrenzungszeichen
    • tvoToolTips - show tooltips for individual nodes
  2. Die LCL bietet zusätzliche Eigenschaften:
    • TCustomTreeView.OnSelectionChange Ereignis
    • TCustomTreeView.DefaultItems, für die Standardanzahl von Items
    • TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
  3. Obwohl die meisten On Drag/Dock Ereignisse in der LCL verfügbar sind, funktionieren sie nicht. Für mehr Informationen lesen Ssie bitte den früheren Abschnitt über 'Bedienelemente ziehen und andocken'.

Nachrichten / Ereignisse

Die Reihenfolge und Häufigkeit von Nachrichten (Messages) und Ereignissen (Events) (OnShow, OnActivate, OnEnter, ...) unterscheiden sich von der VCL und hängen vom Widgetset ab. Die LCL stellt eine Untermenge von WinAPI-ähnlichen Nachrichten zur Verfügung, um das Portieren von Delphi-Komponenten zu erleichtern, aber fast alle LCL-Nachrichten arbeiten etwas anders als die VCL/WinAPI Gegenstücke. Der größte Teil des Delphi Codes, der WinAPI-Nachrichten benutzt, benutzt sie auch deshalb, weil der VCL ein Feature fehlt oder die VCL zu langsam ist. Solcher Code funktioniert unter der LCL selten genau so und muss sorgfältig und von Hand überprüft werden. Deshalb heißen LCL Nachrichten zum Beispiel LM_SIZE (aus der Unit lmessages) und nicht WM_SIZE.

Anmerkung über den Umgang mit benutzerdefinierten Nachrichten! Seit der Version 0.9.26 (Dezember 2008), unterscheidet sich der Umgang mit benutzerdefinierten WinAPI-Nachrichten (z.B. WM_HOTKEY, WM_SYSCOMMAND) von der Art, wie Delphi diese Nachrichten behandelt. Derzeit können Sie diese nicht mittels der Direktive message oder durch Überschreiben der WndProc-Methode des Formulars ansprechen. Der einzige Weg dazu besteht darin, im Formular selbst einen Hook auf Windows windowproc anzulegen. Lesen Sie hier weiter: Processing non-user messages in your window

Siehe auch