Sign in Join
Wiki copytemporary

Lazarus For Delphi Users/de: what changed

Revision 2 to 3. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11Zurück zu den [[Additional information/de|Zusätzlichen Informationen]].\
22
33Diese Beschreibung ist für Leute gedacht, die an Lazarus interessiert sind und Delphi bereits kennen. Sie beschreibt die Unterschiede zwischen den beiden.
44
55## Delphi -\> Lazarus
66
77Lazarus 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.
88
99### Die größten Unterschiede
1010
1111Lazarus 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.
1212
1313**Lazarus ist nicht komplett, genau so wenig wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... .**
1414
1515### Die erste Aktion bei der Konvertierung eines Delphi-Projekts
1616
1717Nachdem 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](http://wiki.lazarus.freepascal.org/XDev_Toolkit) zu konvertieren.
1818
1919### Unicode-Unterstützung
2020
2121Die 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.
2222
2323Lazarus 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]].
2424
2525## Delphi IDE -\> Lazarus IDE
2626
2727### Projekte
2828
2929Die 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.
3030
3131Zum Beispiel:
3232
3333Delphi 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.
3434
3535Delphi 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.
3636
3737Eine 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.
3838
3939### Quelltext-Editor
4040
4141Nahezu alle Tasten und Tastenkürzel (short cuts) können unter 'Einstellungen -\> Editoreinstellungen -\> Tastaturbelegung' festgelegt werden.
4242
4343Die 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:
4444
4545Der 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.
4646
4747Delphi'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.
4848
4949#### Beispiel für Local Variable Completion
5050
5151Nehmen wir an, dass Sie gerade eine neue Methode erzeugt haben und die Anweisung lautet "i:=3;"
5252
5353``` pascal
5454procedure TForm1.DoSomething;
5555begin
5656 i := 3;
5757end;
5858```
5959
6060Positionieren Sie den Cursor über dem Bezeichner "i" und drücken Sie `Strg`+`Shift`+`C` und Sie erhalten:
6161
6262``` pascal
6363procedure TForm1.DoSomething;
6464var i: Integer;
6565begin
6666 i := 3;
6767end;
6868```
6969
7070#### Beispiel für Event Assignment Completion
7171
7272Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können Sie im Quelltext-Editor erhalten.\
7373Zum Beispiel:
7474
7575``` pascal
7676Button1.OnClick:=
7777```
7878
7979Positionieren Sie den Cursor hinter dem Zuweisungsoperator ":=" und drücken Sie `Strg`+`Shift`+`C`.
8080
8181#### Beispiel für Procedure Call Completion
8282
8383Angenommen Sie haben gerade folgende Anweisung geschrieben: "DoSomething(Width);"
8484
8585``` pascal
8686procedure SomeProcedure;
8787var
8888 Width: integer;
8989begin
9090 Width:=3;
9191 DoSomething(Width);
9292end;
9393```
9494
9595Positionieren Sie den Cursor über dem Bezeichner "DoSomething", drücken Sie `Strg`+`Shift`+`C` und Sie erhalten:
9696
9797``` pascal
9898procedure DoSomething(aWidth: LongInt);
9999begin
100100
101101end;
102102
103103procedure SomeProcedure;
104104var
105105 Width: integer;
106106begin
107107 Width:=3;
108108 DoSomething(Width);
109109end;
110110```
111111
112112#### "Wortvervollständigung" Strg+W
113113
114114Sie 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.
115115
116116#### Unterstützung von Include-Dateien
117117
118118Delphi 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.
119119
120120Es gibt viele Optionen für die Code Features.
121121
122122### Designer
123123
124124\- Richtlinien
125125
126126#### Objektinspektor
127127
128128In 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:
129129
1301301. 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.
1311312. 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.
1321323. 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.
1331334. Ä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.
134134
135135#### Packages
136136
137137F: Kann Lazarus Delphi-Packages installieren und verwenden?
138138
139139A: Nein, weil diese auf die "Delphi Compiler Magie" angewiesen sind.
140140
141141F: Brauchen wir speziell für Lazarus erstellte Packages?
142142
143143A: 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
144144
145145\- die docs/Packages.txt in den Lazarus Quellen.
146146
147147### VCL -\> LCL
148148
149149Obwohl 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.
150150
151151Zusä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.
152152
153153Das 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.
154154
155155#### TControl.Font/TControl.ParentFont
156156
157157In 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.
158158
159159Dies 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.
160160
161161Das 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.
162162
163163#### Bedienelemente ziehen und andocken
164164
165165In 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.
166166
167167Diese 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.
168168
169169Das bedeutet derzeit, dass **kein** Bedienelement die folgenden TControl Funktionen, Prozeduren, Eigenschaften oder Ereignisse erben/benutzen wird -
170170
171171``` pascal
172172Protected
173173 function GetDockEdge(MousePos: TPoint): TAlign;
174174 function GetDragImages: TDragImageList;
175175 function GetFloating: Boolean;
176176 function GetFloatingDockSiteClass: TWinControlClass;
177177 procedure DoEndDrag(Target:TObject); X, Y: Integer);
178178 procedure DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);
179179 procedure DoEndDock(Target: TObject; X, Y: Integer);
180180 procedure DoDock(NewDockSite: TWinControl; var ARect: TRect);
181181 procedure DoStartDock(var DragObject: TDragObject);
182182 procedure DragCanceled;
183183 procedure DragOver(Source: TObject; X, Y: Integer; State: TDragState;
184184 var Accept: Boolean);
185185 procedure DoEndDrag(Target: TObject; X, Y: Integer);
186186 procedure DoStartDrag(var DragObject: TDragObject);
187187 procedure DrawDragDockImage(DragDockObject: TDragDockObject);
188188 procedure EraseDragDockImage(DragDockObject: TDragDockObject);
189189 procedure PositionDockRect(DragDockObject: TDragDockObject);
190190 procedure SetDragMode(Value: TDragMode);
191191 property DragKind: TDragKind;
192192 property DragCursor: TCursor;
193193 property DragMode: TDragMode;
194194 property OnDragDrop: TDragDropEvent;
195195 property OnDragOver: TDragOverEvent;
196196 property OnEndDock: TEndDragEvent;
197197 property OnEndDrag: TEndDragEvent;
198198 property OnStartDock: TStartDockEvent;
199199 property OnStartDrag: TStartDragEvent;
200200public
201201 function Dragging: Boolean;
202202 function ManualDock(NewDockSite: TWinControl; DropControl: TControl;
203203 ControlSide: TAlign): Boolean;
204204 function ManualFloat(ScreenPos: TRect): Boolean;
205205 function ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;
206206 DropControl: TControl; ControlSide: TAlign): Boolean;
207207 procedure BeginDrag(Immediate: Boolean; Threshold: Integer);
208208 procedure Dock(NewDockSite: TWinControl; ARect: TRect);
209209 procedure DragDrop(Source: TObject; X, Y: Integer);
210210 procedure EndDrag(Drop: Boolean);
211211 property DockOrientation: TDockOrientation;
212212 property Floating: Boolean;
213213 property FloatingDockSiteClass: TWinControlClass;
214214 property HostDockSite: TWinControl;
215215 property LRDockWidth: Integer;
216216 property TBDockHeight: Integer;
217217 property UndockHeight: Integer;
218218 property UndockWidth: Integer;
219219```
220220
221221dass die folgenden Klassen nicht existieren/nicht verwendet werden können -
222222
223223``` pascal
224224TDragImageList = class(TCustomImageList)
225225TDockZone = class
226226TDockTree = class(TInterfacedObject, IDockManager)
227227TDragObject = class(TObject)
228228TBaseDragControlObject = class(TDragObject)
229229TDragControlObject = class(TBaseDragControlObject)
230230TDragDockObject = class(TBaseDragControlObject)
231231```
232232
233233und dass die folgenden Funktionen auch nicht benutzbar/inkompatibel sind -
234234
235235``` pascal
236236function FindDragTarget(const Pos: TPoint;
237237 AllowDisabled: Boolean) : TControl;
238238procedure CancelDrag;
239239function IsDragObject(sender: TObject): Boolean;
240240```
241241
242242Der Start des Docking-Managers wird hier beschrieben: [[Anchor Docking]]
243243
244244#### TEdit/TCustomEdit
245245
246246Die Edit-Bedienelemente, die grundsätzlich gleich in der LCL wie in der VCL funktionieren, besitzen einige Besonderheiten, die bei einer Konvertierung beachtet werden sollten -
247247
2482481. 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.
2492492. On Drag/Dock Ereignisse sind noch nicht implementiert. Für mehr Informationen schauen Sie bitte im vorherigen Abschnitt Bedienelemente ziehen und andocken nach.
2502503. Font-Eigenschaften werden üblicherweise für die Interface-Konsistenz ignoriert, für eine detaillierte Beschreibung schauen Sie bitte TControl.Font/TControl.ParentFont an.
251251
252252#### TDBImage
253253
254254Delphi 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.
255255
256256Anmerkung: 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|Lazarus_1.2.0_release_notes#TDBImage]] für Details.
257257
258258### (optional) TSplitter -\> TPairSplitter
259259
260260**Bitte verbessern Sie mich**
261261
262262Es gibt jetzt ein [[TSplitter/de|TSplitter]] Bedienelement in der LCL, so dass kein Bedarf zum Konvertieren besteht.
263263
264264Nichtsdestoweniger, wenn Sie es doch wollen, hier ist es beschrieben:
265265
266266Das Folgende basiert lose auf den Fragen von Vincent Snijders in der Mailingliste und Antworten von [Andrew Johnson](http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson):
267267
268268Das 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.
269269
270270In 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.
271271
272272Was sind nun genau die Unterschiede?
273273
274274Der 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).
275275
276276In 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.
277277
278278Der andere entscheidende Unterschied ist, dass der TSplitter der VCL seine Position relativ zu den anderen Komponenten verändert, abhängig von seiner Split-Position.
279279
280280In 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.
281281
282282Beispielsweise 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:
283283
284-` PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; `
284+``` pascal
285+ PairSplitter.Position := PairSplitter.Width - PairSplitter.Position;
286+```
285287
286288Wie kann ich nun existierenden Code, der TSplitter verwendet, zu TPairSplitter konvertieren?
287289
288290Wenn 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 -
289291
290292**VCL**
291293
292294**LCL**
293295
294296``` pascal
295297var
296298 BottomPanel: TPanel;
297299 VerticalSplitter: TSplitter;
298300 LeftPanel: TPanel;
299301 HorizontalSplitter: TSplitter;
300302 MainPanel: TPanel;
301303
302304begin
303305 BottomPanel:= TPanel.Create(Self);
304306 with (BottomPanel) do
305307 begin
306308 Parent:= Self;
307309 Height:= 75;
308310 Align:= alBottom;
309311 end;
310312
311313 VerticalSplitter:= TSplitter.Create(Self);
312314 with (VerticalSplitter) do
313315 begin
314316 Parent:= Self;
315317 Align:= alBottom;
316318 end;
317319
318320 HorizontalSplitter:= TSplitter.Create(Self);
319321 with (HorizontalSplitter) do
320322 begin
321323 Parent:= Self;
322324 align:= alLeft;
323325 end;
324326
325327 LeftPanel:= TPanel.Create(Self);
326328 with (LeftPanel) do
327329 begin
328330 Parent:= Self;
329331 Width:= 125;
330332 Align:= alLeft;
331333 end;
332334
333335 MainPanel:= TPanel.Create(Self);
334336 with (MainPanel) do
335337 begin
336338 Parent:= Self;
337339 Align:= alClient;
338340 Caption:= 'Hello';
339341 end;
340342end;
341343```
342344
343345``` pascal
344346var
345347 BottomPanel: TPanel;
346348 VerticalSplitter: TPairSplitter;
347349 LeftPanel: TPanel;
348350 HorizontalSplitter: TPairSplitter;
349351 MainPanel: TPanel;
350352
351353begin
352354 VerticalSplitter:= TPairSplitter.Create(Self);
353355 with (VerticalSplitter) do
354356 begin
355357 Parent:= Self;
356358 Align:= alClient;
357359 Width:= Self.Width;
358360 Height:= Self.Height;
359361 SplitterType:= pstVertical;
360362 Position:= Height - 75;
361363 Sides[0].Width:= Width;
362364 Sides[0].Height:= Position;
363365 end;
364366
365367 HorizontalSplitter:= TPairSplitter.Create(Self);
366368 with (HorizontalSplitter) do
367369 begin
368370 Parent:= VerticalSplitter.Sides[0];
369371 Width:= Self.Width;
370372 Height:= VerticalSplitter.Position;
371373 align:= alClient;
372374 SplitterType:= pstHorizontal;
373375 Position:= 125;
374376 end;
375377
376378 LeftPanel:= TPanel.Create(Self);
377379 with (LeftPanel) do
378380 begin
379381 Parent:= HorizontalSplitter.Sides[0];
380382 Align:= alClient;
381383 end;
382384
383385 MainPanel:= TPanel.Create(Self);
384386 with (MainPanel) do
385387 begin
386388 Parent:= HorizontalSplitter.Sides[1];
387389 Align:= alClient;
388390 Caption:= 'Hello';
389391 end;
390392
391393 BottomPanel:= TPanel.Create(Self);
392394 with (BottomPanel) do
393395 begin
394396 Parent:= VerticalSplitter.Sides[1];
395397 Align:= alClient;
396398 end;
397399end;
398400```
399401
400402Wie 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.
401403
402404Das obige Beispiel würde in etwa so aussehen -
403405
404406**Delphi DFM**
405407
406408**(weitere Werte wurden entfernt)**
407409
408410**Lazarus LFM**
409411
410412**(width, height, etc. entfernt)**
411413
412-``` pascal
414+``` lfm
413415object VerticalSplitter: TSplitter
414416 Height = 3
415417 Cursor = crVSplit
416418 Align = alBottom
417419end
418420object HorizontalSplitter: TSplitter
419421 Width = 3
420422 Align = alLeft
421423end
422424object BottomPanel: TPanel
423425 Height = 75
424426 Align = alBottom
425427end
426428object LeftPanel: TPanel
427429 Width = 125
428430 Align = alLeft
429431end
430432object MainPanel: TPanel
431433 Align = alClient
432434end
433435```
434436
435-``` pascal
437+``` lfm
436438object VerticalSplitter: TPairSplitter
437439 Align = alClient
438440 SplitterType = pstVertical
439441 Position = 225
440442 Height = 300
441443 Width = 400
442444 object Pairsplitterside1: TPairSplitterIde
443445 object HorizontalSplitter: TPairSplitter
444446 Align = alClient
445447 Position = 125
446448 object Pairsplitterside3: TPairSplitterIde
447449 Width = 125
448450 object LeftPanel: TPanel
449451 Align = alClient
450452 Width = 125
451453 end
452454 end
453455 object Pairsplitterside4: TPairSplitterIde
454456 object MainPanel: TPanel
455457 Align = alClient
456458 end
457459 end
458460 end
459461 end
460462 object Pairsplitterside2: TPairSplitterIde
461463 object BottomPanel: TPanel
462464 Align = alClient
463465 Height = 75
464466 end
465467 end
466468end
467469```
468470
469471### TCustomTreeView/TTreeView
470472
471473Beide, 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 -
472474
473475**Unvollständige Liste (sollte aktualisiert werden, um die TCustomTreeView-Markierungsfunktionen und geschützten Methoden zu enthalten)**
474476
4754771. 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 :
476478 - tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL
477479 - tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand
478480 - tvoAutoInsertMark - Update the Drag preview on mouse move.
479481 - tvoAutoItemHeight - Passt die Item Höhen automatisch an.
480482 - tvoHideSelection - Markiert das gewählte Item nicht.
481483 - tvoHotTrack - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack
482484 - tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes
483485 - tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly
484486 - tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect
485487 - tvoRowSelect - Erlaubt das Auswählen von Zeilen, entsprechend der Ermöglichung von TCustomTreeView.RowSelect
486488 - tvoShowButtons - Zeigt Schaltflächen, entsprechend der Ermöglichung von TCustomTreeView.ShowButtons
487489 - tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines
488490 - tvoShowRoot - show root note, equivalent to enabling TCustomTreeView.ShowRoot
489491 - tvoShowSeparators - zeigt Begrenzungszeichen
490492 - tvoToolTips - show tooltips for individual nodes
4914932. Die LCL bietet zusätzliche Eigenschaften:
492494 - TCustomTreeView.OnSelectionChange Ereignis
493495 - TCustomTreeView.DefaultItems, für die Standardanzahl von Items
494496 - TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes
4954973. 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'.
496498
497499### Nachrichten / Ereignisse
498500
499501Die 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.
500502
501503**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]]
502504
503505## Siehe auch
504506
505507- [[Code Conversion Guide|Code Conversion Guide (from Delphi & Kylix)]]
506508- [[Compile With Delphi]]
507509
508510---
509511*From the Free Pascal wiki, page "Lazarus For Delphi Users/de", as it stood on 2020-02-18 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history