https://wiki.freepascal.org/api.php?action=feedcontributions&user=MaD&feedformat=atomLazarus wiki - User contributions [en]2024-03-28T09:25:14ZUser contributionsMediaWiki 1.35.6https://wiki.freepascal.org/index.php?title=Code_Conversion_Guide/de&diff=16235Code Conversion Guide/de2007-01-19T11:18:21Z<p>MaD: /* Syntax Unterschiede */ Übersetzung</p>
<hr />
<div>{{Code Conversion Guide}}<br />
<br />
Diese Seite handelt darüber, wie man bestehenden Delphi oder Kylix Code konvertiert, um ihn mit dem [[Free Pascal/de|Free Pascal]] Compiler und der Lazarus IDE zum Laufen zu bringen. Obwohl Lazarus und der Free Pascal Compiler gemeinsame Aspekte mit Delphi und Kylix haben, sind sie keine Klone. Es gibt eine Anzahl von Bibliotheksaufrufen und Konventionsunterschieden... und in einigen Bereichen ist FPC erweitert und kann anspruchsvoller sein about correct syntax. Bitte schauen sie im [[Lazarus For Delphi Users/de|Lazarus für Delphi Benutzer]] Handbuch nach für eine Beschreibung von einigen der funktionellen Unterschiede. <br />
<br />
Der Zweck dieses Handbuchs ist es, einige der spezifischen Unterschiede zu dokumentieren, die häufig auftreten während des Codekonvertierungsprozesses, wenn existierender Code von Delphi nach Lazarus übersetzt wird.<br />
<br />
Dieses Dokument wurde im Wissensbasis Bereich des Wikis platziert, so daß es einfach erweitert werden kann von jedem, der auf ein einzigartiges Problem gestoßen ist und andere darauf aufmerksam machen möchte.<br />
<br />
== Auswahl einer Komponente oder Bibliothek für die Konvertierung ==<br />
<br />
=== Wo Code zum Konvertieren zu finden ist ===<br />
<br />
Im Internet ist eine MENGE von Code verfügbar, der konvertiert werden kann für die Verwendung mit FPC und Lazarus. Hier ist eine [[Page Of Code Sites|Seite]], die einfach ein Anfang ist. Bitte erweitern sie die Seite, wenn sie weitere Stellen kennen. TurboPower Software has recently released their entire commercial offering under the MPL. Eine Liste von verfügbaren Packages ist [http://sourceforge.net/users/tpsfadmin/ hier] zu finden.<br />
<br />
Um doppelten Aufwand zu vermeiden, sind bereits konvertierte Packages gelistet auf der [[Components and Code examples]] Seite. Wenn sie ein Package konvertiert haben oder daran arbeiten, dann fügen sie bitte eine Notiz auf der [[Current conversion projects]] Seite hinzu.<br />
<br />
=== Lizenzierung ===<br />
<br />
Lizenzen für existierenden Code reichen von Freeware/Public Domain bis zu eingeschränkten Versionen, welche Modifizierung, Weiterverteilung und kommerzielle Verwendung verbieten. Bevor sie irgendein Package konvertieren, ist es eine gute Idee, seine Lizenz zu überprüfen und sicherzustellen, daß sie kompatibel wird mit Lazarus und dem Free Pascal Compiler. Lizenzauswahl ist besonders wichtig bei Komponenten, seit das Ablegen auf einem Formular eine nicht gewollte oder inkompatible Lizenz für die gesamte Anwendung aufbürden kann.<br />
<br />
Wenn sie Komponenten konvertieren, respektieren sie bitte die Wünsche des Originalautors und belassen alle Copyright- und Lizenz-Header mit Email-Adressen und URl's. Es gehört zum guten Ton und ist oft hilfreich, um den Autor zu informieren, daß seine Komponente konvertiert wurde... besonders wenn sich die Komponente unter einer restriktiven Lizenz befindet. Neues Interesse an einer alten oder vergessenen Komponente kann manchmal die Autoren inspirieren, um ihr Original und die allzu restriktive Lizenzierung zu überarbeiten.<br />
<br />
Im Allgemeinen sind Public Domain (Freeware) und die LGPL/MPL Komponenten die flexibelsten zum Vertreiben. Für mehr Information ist die [http://www.opensource.org/docs/definition.php Open Source Definition] ein guter Platz zum starten. Dort gibt es auch verschiedene Vergleiche to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Suchen sie nach "open source license comparison"<br />
<br />
=== Abhängigkeiten ===<br />
<br />
Ein anderer Schritt bevor sie an einer Konvertierung arbeiten ist, daß sie überprüfen, daß der Code keine verborgenen Abhängigkeiten von anderen Packages enthält, die nicht verfügbar sein können oder einen beträchtlichen Konvertierungsaufwand darstellen. Einige Freeware Angebote sind gebunden an oder erweitern proprietäre Packages, die häufig nicht länger erhältlich sind oder mit ungeeigneten Lizenzen kommen.<br />
<br />
=== Compiler Probleme ===<br />
<br />
Siehe:<br />
* [http://www.freepascal.org/probs.html bekannte Probleme]<br />
* [http://www.freepascal.org/bugs/db.php3?statusfield=Unfixed Nichtbereinigte Bugs]<br />
<br />
=== Plattform und OS Probleme ===<br />
<br />
Lazarus und der Free Pascal Compiler sind [[Glossary#CrossPlatform|cross-platform]] und cross-architecture Entwicklungswerkzeuge. Im Gegensatz wurde der meiste existierende Delphi Code speziell vorgesehen, auf einem Intel Prozessor unter Win32 zu laufen. Wenn ihr Kandidat eine Menge von Win32 spezifischem Code hat, mag es weise sein, nach einer weniger plattformabhängigen Alternative zu suchen. Aber lassen sie sich davon nicht entmutigen. Es ist erstaunlich, was die LCL unterstützt!<br />
<br />
== Durchführen der Konvertierung ==<br />
<br />
=== Einrichten der Lazarus Umgebung für ein Konvertierungs-Projekt ===<br />
<br />
==== Erstellen eines Testprojekts ====<br />
* Platzieren sie den zu konvertierenden Code in ein Unterverzeichnis (z.B.: convertdir)<br />
* Holen sie Lazarus hervor<br />
* Datei -> Alles speichern in das convertdir Unterverzeichnis. Aussagekräftige Namen für Projekt und Units sind optional.<br />
* Öffnen sie die zu konvertierende "main" Unit in convertdir<br />
* Fügen sie sie zum Projekt hinzu: Projekt -> Datei im Editor ins Projekt aufnehmen<br />
* Starten sie Werkzeuge -> Schnelle Syntaxüberprüfung oder Start -> Alles neu erstellen um loszulegen.<br />
<br />
==== Initial items to watch out for ====<br />
* Dateinamen sind case sensitive with the 1.0.x series compilers. Wenn sie mit dieser Version arbeiten, schreiben sie alle Dateinamen klein. Sie werden "File not found" Fehler bekommen, wenn sie es nicht tun.<br />
<br />
==== Delphi VCL, Kylix CLX Quellen in Lazarus ====<br />
<br />
Während der Konvertierung von Delphi/Kylix Quellen ist es oft hilfreich, eine find declaration zu machen um zu sehen, was eine bestimmte Funktion macht. Die Lazarus IDE kann die Delphi/Kylix Quellen analysieren. Um dies zu tun werden einige Suchpfade und Compilereinstellungen benötigt. Sie können dies einfach einrichten unter<br />
<br />
Einstellungen -> CodeTools Defines Editor -> Vorlage einfügen<br />
<br />
=== Konvertierungsprobleme und Lösungen ===<br />
<br />
==== Delphi / Kylix Datei-Entsprechungen in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Beschreibung<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr (main project file)<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi (main project file)<br />
.ppu<br />
| class="code" |Pascal Unit Datei<br />
Formulardaten Datei<br />
Compilierte Unit Datei<br />
Projektdatei<br />
Ressourcendatei<br />
Projektoptionen Datei<br />
Lazarus Ressourcen Datei<br />
Lazarus Projekt Informations Datei<br />
FPC Unit Beschreibungsdatei<br />
|}<br />
<br />
==== Konvertierung von Delphi Projekten/Formularen/Units nach Lazarus ====<br />
<br />
Benennen sie die .dpr Datei in eine .lpr Datei um. Kommentieren sie die <div class="dir">{$R *.res}</div> Direktive aus oder entfernen sie und fügen eine <div class="dir">{$mode delphi}{$H+}</div> oder <div class="dir">{$mode objfpc}{$H+}</div> Direktive zur .lpr Datei hinzu. Die Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". Sie fragt nach einer .dpr (Delphi Project) Datei und konvertiert sie in eine .lpr; außerdem erzeugt sie die .lpi Datei und konvertiert alle Units.<br />
<br />
Viele existierende Delphi Formulare können konvertiert werden um mit Lazarus zu funktionieren durch Verwendung des in die IDE eingebauten .dfm to .lfm form Umwandlers. Er ist zu finden im Werkzeuge Menü als "Convert DFM file to LFM". Bring up the file dialog, wählen sie die dfm Datei und der Umwandler wird den Rest erledigen.<br />
<br />
Wenn sie die ganze Unit konvertieren müssen (mit oder ohne ein Formular), enhält Lazarus auch ein eingebautes "Convert Delphi unit to Lazarus unit", welches das folgende für sie erledigt -<br />
<br />
# fixes the case of include filenames and uses sections.<br />
# konvertiert die .dfm Datei in eine .lfm Datei (gegenwärtig ohne Inhaltsprüfung, nur Formatierung)<br />
# erzeugt eine leere .lrs Datei (der Inhalt wird später erzeugt)<br />
# fügt die <div class="dir">{$mode delphi}</div> Direktive hinzu<br />
# ersetzt die windows Unit durch LCLIntf<br />
# adds LResources unit if needed (i.e., if unit.lrs is to be used; <div class="dir">uses LResources </div> can be in the implementation part)<br />
# entfernt die variants Unit<br />
# entfernt die <div class="dir">{$R *.dfm}</div> Direktive<br />
# fügt den initialization Abschnitt und die <div class="dir">{$i unit.lrs}</div> Direktive hinzu<br />
<br />
==== Auswahl des richtigen Compilermodus ====<br />
<br />
Der [[Free Pascal/de|Free Pascal]] Compiler unterstützt 5 unterschiedliche Pascal Modi. Zum Beispiel TP für Turbo Pascal, lässt sie Turbo Pascal Units kompilieren. Es gibt auch einen DELPHI Kompatibilitäts-Modus, der gesetzt werden kann, um bestehenden Code einfacher zu konvertieren. Lazarus bevorzugt den OBJFPC Modus, welcher fast dem DELPHI Modus gleicht, aber weniger mehrdeutig als die Delphi Syntax ist. Hier sind die wichtigen Punkte:<br />
<br />
Der Modus kann auf der Befehlszeile oder beim Start der Quelle gewählt werden. Die Verwendung der Befehlszeile hat den Vorteil, daß sie die Quelle nicht ändern müssen, aber den Nachteil, daß anderes erzählt werden muß.<br />
<br />
Die meisten Delphi Units können mit dem [[Free Pascal/de|Free Pascal]] Compiler kompiliert werden durch hinzufügen von <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
gleich nach dem Unit Namen.<br />
<br />
Für mehr Details über die [[Free Pascal/de|Free Pascal]] Modi siehe die [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Dokumentation].<br />
<br />
==== Cross-Plattform Überlegungen ====<br />
<br />
* Inline Assembler ist immer ein Problem, weil er den Code an die Intel Architektur bindet. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately TurboPower did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* Wenn sie Betriebssystem-spezifischen Code benötigen, dann können sie IFDEFs verwenden. Siehe unten für eine Liste der Makros.<br />
<br />
==== Hilfreiche Compiler Variablen ====<br />
<br />
Um Code zu schreiben, der sich auf verschiedenen Systemen unterschiedlich verhält, können sie die <div class="dir">{$IFDEF Name}</div> Anweisungen verwenden.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird. Hilfreich um Code zu schreiben, der mit der LCL und Delphi funktioniert.<br />
* <div class="dir">{$IfDef LCLGtk}</div>, <div class="dir">{$IfDef LCLWin32}</div>, <div class="dir">{$IfDef LCLQt}</div>, ...<br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird und das spezifische widgetset is currently used. Hilfreich um Code zu schreiben, der mit der LCL auf einer spezifischen Plattform funktioniert.<br />
* <div class="dir">{$IfDef FPC}</div><br />
Diese Variable ist definiert, wenn der FPC Compiler verwendet wird. Hilfreich um Code zu schreiben, der mit FPC und Delphi funktioniert.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Von FPC für das aktuelle Ziel OS definiert. Delphi definiert "Linux", "Win32" und "MSWindows". [[Free Pascal/de|Free Pascal]] läuft auf viel mehr Plattformen und daher wird empfohlen, allgemeinere Begriffe zu verwenden. Zum Beispiel ist "Unix" definiert für Linux, FreeBSD, NetBSD und OpenBSD, wo Lazarus bereits läuft.<br />
Verwenden sie<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
Für mehr Details siehe die [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Dokumentation].<br />
<br />
==== Finden eines fehlenden Bezeichners ====<br />
<br />
Es gibt Unterschiede darin, wie die LCL organisiert ist im Vergleich zur Delphi VCL. Wenn sie einen "not found" Compilerfehler erhalten über eine wichtige Klasse oder Bezeichner, stehen die Chancen gut, daß Sie die Klasse oder den Bezeichner in einer anderen Unit finden könne. Eine komplette Cross-Reference können Sie finden, indem Sie grep auf das Verzeichnis lazarus/docs/xml oder das Unterverezeichnis lcl anwenden.<br />
<br />
Zum Beispiel erzeugt der häufig verwendete TButton üblicherweise einen Fehler im Delphi Code, weil er sich in der Unit buttons.pp befindet. Das folgende Kommando findet die richtige Unit sehr schnell (im Lazarus Quellenverzeichnis):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
==== Wichtige Unit Unterschiede zwischen Lazarus und Delphi ====<br />
<br />
'''Bitte ergänzen sie diesen Abschnitt!'''<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
Die die LCL nicht Windows-spezifisch ist, ist der Code, der sich in der Delphi Windows Unit für den direkten Zugriff auf das Win32 API befindet, abstrahiert in separate Schnittstellen, auf welche mit der LCLIntf Unit Zugriff besteht. Beachten Sie, daß Lazarus nicht win32 emuliert, so daß mehrere Funktionen fehlen und einige nicht wie ihre win32-Gegenstücke funktionieren. Diese Funktionen existieren nur für die Delphi-Kompatibilität und sollten nur für Quick&Dirty-Portierungen benutzt werden. LCL beinhalte auch viele Typen nicht, so daß oftmals LCLType und manchmal VCLGlobals benötigt werden. LCLProc enthält auch ein paar Funktionen, die hilfreich sein können für maschinennahere Bearbeitung wie "FreeThenNil" wie in Delphi 5 und höher, "DeleteAmpersands" um zusätzliche Et-Zeichen aus Zeichenketten für Kontrollen zu entfernen (vs && etc). Die Interfaces-Unit muß in der .lpr Datei enthalten sein, um das passende widgetset zu initialisieren.<br />
<br />
* Messages->LMessages<br />
<br />
TControl-Messages für win32-Ereignis-Callbacks vom Format WM_CALLBACK und die Structs, die dazugehören, finden sich oftmals in der Messages-Unit in Delphi. In LCL befinden diese sich meistens in LMessages, üblicherweise mit einer Namensänderung von WM zu LM, zum Beispiel WM_MOUSEENTER wird LM_MOUSEENTER, und TWMMouse wird TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
Um einige Sachen zu vereinfachen und die Komplexität von Kreisabhängigkeiten zwischen Units zu verringern, wurden einige Typen in einee gemeinsamen Unit namens GraphType abstrahiert, die sich in Delphi in Graphics oder Controls befinden, bspw. das bvNone usw. von Panels. Deswegen müssen Sie diese Unit gelegentlich einbinden. Eine weitere Unit, leider inkompatibel zu Delphi, liefert zusätzliche Funktionalität, GraphMath. Sie ermöglicht TFloatPoints für präzise Berechnungen, verschiedene Routinen für den Umgang mit Beziers, Linien und Kreisbögen, sowie überladene Operatoren zur Benutzung mit TPoints und TRect, um Punkte derart zu addieren Point1 := Point2 + Point3 oder Rechtecke zu vergleichen if(rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
Aus Überlegungen für eine bessere Benennung wurde die Unit für TMaskEdit [MaskeDit |] anstelle des leicht unklareren Mask wie in vielen Delphi Versionen.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In vielen Delphi Versionen befindet sich TButton in StdCtrls, während TSpeedButton und TBitBtn sich in Buttons befinden. Für eine Stetigkeit und Einfachheit steckt die LCL alle Buttontypen in Buttons, was gelegentlich die Code-Konvertierung ins Leere laufen lassen kann -- es ist also eine gute Idee, diese einzubinden.<br />
<br />
==== Eigenschaften und Methoden Unterschiede Delphi -> FPC/LCL ====<br />
* TBitmap verfügt über einen Kanvas in der LCL<br />
<br />
==== Syntax Unterschiede ====<br />
<br />
'''Bitte fügen sie weitere Informationen zu diesem Thema hinzu!'''<br />
<br />
Wegen der inhärenten Striktheit des FPC sind manche Syntaxändeungen notwendig, obwohl<div class="dir">{$Mode Delphi}</div> mehr Nachlässigkeit wie in Delphi erlaubt. Aus diesem Grund ist es in höchstem Maße empfehlenswert, soweit wie möglich den Syntaxregeln von <div class="dir">{$Mode ObjFPC}</div> zu entsprechen, auch wenn die Codebasis weiterhin von Delphi und LCL gemeinsam benutzt wird. Einiges davon entspricht einfach besserer Code-Praxis, anderes liegt an dem gelegentlich inakkuraten Delphi-Modus und manchmal funktioniert Code von Delphi mit dem FPC nicht so wie erwartet, auch wenn er sich kompilieren läßt. Letztlich sollte die folgende Liste als verbindlich betrachtet werden, auch wenn nicht alle Änderungen zwingend notwendig sind:<br />
<br />
<br />
===== Bei der Zuweisung eines Ereignis-Handler-Einstiegspunkts diesem ein "@" voranstellen =====<br />
<br />
Zum Beispiel, wenn Sie einen Button-Callback manuell zuweisen<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ wird nicht benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ wird benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== Wenn sie eine Prozedurenvariable aufrufen, verwenden sie diese Syntax: theprocname() =====<br />
<br />
In Delphi gibt es keinen Unterschied zwischen dem Ergebnis einer Funktion und einer Variablen, jedoch gibt es in FPC einen. Um eine Funktion aufzurufen, selbst wenn sie keine Parameter hat, müssen sie eine runde Klammer anhängen. Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//runde Klammer nicht benötigt</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//runde Klammer benötigt</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== Beim Zugriff auf den Wert eines Record mittels eines Zeigers muß dieser zuerst dereferenziert werden =====<br />
<br />
In Delphi ist es nicht nötig, einen Zeiger auf einen Record zu dereferenzieren, um auf einen Wert darin zuzugreifen. Tatsächlich kann ein Zeiger wie der Record selbst oder wie jedes andere Objekt behandelt werden. In FPC muß er zuerst dereferenziert werden. Beispiel:<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
===== Beim Zugriff auf Zeichen einer indizierten Zeichenketten-Eigenschaf eines Objektes muß dieses in runden Klammern stehen =====<br />
<br />
Mit Delphi ist es möglich, eine Eigenschaft genauso zu behandeln wie andere Konstanten oder Variablen, z.B. beim direkten Zugriff auf einzelne Zeichen einer Zeichenkette, wogegen daß mit FPC nicht immer möglich ist, speziell bei indizierten Eigenschaften. Stattdessen muß die entsprechende Eigenschaft zur besseren Unterscheidung in runden Klammer stehen. Dies mag zwar nicht immer nötig sein, es ist dennoch eine gute Praxis, das so zu machen. Beispiel:<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
===== Sie müssen eine Typumwandlung von Zeigern in den tatsächlichen Typ vornehmen, wird dieser Zeiger mit einer Variablen oder Funktion dieses Typs benutzt =====<br />
<br />
In Delphi haben sie manchmal einen Null-Zeiger-Variable, die ein Objekt repräsentiert. Auch wenn es nach einer gestellten Situation aussieht, ist es gängige Praxis gerade in großen Komponenten-Paketen, um zuviele Kreisreferenzen zwischen Objekten verschiedener Units zu vermeiden. In Delphi ist es möglich, diesen Null-Zeiger einer Funktion zu schicken, die ein Objekt dieses Typs erwartet, ohne sich mit einer Typenumwandlung beschäftigen zu müssen. In FPC muß eine solche Typenumwandlung stattfinden<br />
<br />
Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Ressourcen ====<br />
<br />
Delphi Ressourcendateien sind Win32 spezifisch und nicht kompatibel mit Lazarus, so daß sie sie neu erstellen und mit Lazres kompilieren müssen. Lazres ist im lazarus/tools Unterverzeichnis zu finden. Wenn sie die Lazarus Quellen heruntergeladen haben, müssen sie es erst kompilieren.<br />
* cd lazarus/tools<br />
* make install<br />
Um eine Ressource zu ihrer Anwendung hinzuzufügen:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Fügen sie die LResources Unit zu ihrem Uses Abschnitt hinzu<br />
* Nehmen sie die von ihnen erstellte .lrs Datei unter dem initialization Abschnitt auf<br />
Beispiel:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
=== Eine andere Methode um ein Delphi oder Kylix Projekt nach Lazarus zu konvertieren ===<br />
<br />
* Benennen sie alle .dfm oder .xfm Dateien in .lfm um. (Dies funktioniert nicht mit frühen Delphi Versionen da sie keine textbasierte .dfm Datei erstellen.)<br />
* Benennen sie die .dpr Datei in .lpr um.<br />
* Nehmen sie notwendige Änderungen in der .lpr Datei vor:<br />
# Fügen sie {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'Interfaces' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.res} Direktive aus oder löschen sie diese.<br />
* Nehmen sie notwendige Änderungen in allen .pas Unit Dateien vor:<br />
# Fügen sie die {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'LResources', und wenn das Formular Buttons hat, 'Buttons' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.dfm} oder {$R *.xfm} Direktive aus oder löschen sie diese.<br />
# Fügen sie einen 'Initialization' Abschnitt am Ende jeder Datei hinzu, und fügen die {$I unitname.lrs} Direktive darin hinzu.<br />
* Wählen sie Projekt -> Neues Projekt von Datei<br />
* Wählen sie die .lpr Datei<br />
* Im 'Erzeuge neues Projekt' Fenster wählen sie 'Anwendung'<br />
* Erzeugen sie das Projekt und nehmen sie weitere notwendige Korrekturen vor um eine ordentliche Kompilierung zu erhalten, an diesem Punkt wird die .lpi Datei automatisch generiert. Sie erhalten vielleicht 'Error reading Form' Meldungen. Klicken sie auf 'Continue Loading' falls dem so ist. <br />
* Speichern sie alles und sie haben ein Lazarus Projekt :-)<br />
<br />
== Hilfe erhalten ==<br />
<br />
Wenn sie während der Konvertierung auf ein Problem stoßen, das sie gerade nicht lösen können, gibt es eine große Auswahl von Orten, um Hilfe zu erhalten. Für reine Object Pascal und FPC Probleme, ist der beste Ort zu beginnen die Free Pascal [http://www.freepascal.org/docs-html/ Dokumentation] von Michaël Van Canneyt und Florian Klämpfl. Für mehr Lazarus orientierte Probleme ist die Lazarus Projekt Dokumentation in der [[Main Page/de|Lazarus-CCR Knowledgebase]] der nächste Ort zum nachschauen. Schließlich können sie eine Frage posten in einer der [http://www.freepascal.org/maillist.html Mailing Listen] für den Free Pascal Compiler oder den [http://community.freepascal.org:10000/bboard/ FPC Foren], wo eine Menge Experten eingeschrieben sind.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates betreibt eine schnelle [http://www.tamaracka.com/search.htm Such] Engine speziell für die Borland Usenet Archive. Mer Systems Inc. bietet eine ähnliche Such [http://www.mers.com/searchsite.html Engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Erstellen eines Lazarus Package für ihre Komponente(n) ===<br />
<br />
Das Erstellen eines Packages macht die Installation ihres konvertierten Codes viel einfacher... besonders wenn sie mehr als eine Komponente anbieten. Mattias Gärtner hat eine Übersicht über [[Lazarus Packages/de|Lazarus Packages]] geschrieben, die gelesen werden sollte bevor sie mit diesem Prozess beginnen.<br />
<br />
=== Dokumentation ===<br />
<br />
Der Zweck dieser Seite und dem Wiki Format ist, die Generierung einer professionellen Dokumenation zu einem einfachen und schnellen Prozess zu machen. Das Wiki macht es auch möglich, die Resultate ihres posting unverzüglich zu sehen und erlaubt ihnen, Änderungen in Echtzeit zu machen.<br />
<br />
Die Verwendung des Lazarus-CCR Wiki um eine schön anzuschauende Dokumentation zu erstellen ist sehr einfach. Wenn sie noch nie zuvor die Wiki Sprache verwendet haben, können sie sich damit vertraut machen in dem [[Sand Box]] Übungsbereich.<br />
<br />
=== Erzeugen einer Code Release Page ===<br />
<br />
Die Code Release Page enthält grundlegende Informationen über ihre Komponente, die ein potenzieller Nutzer wird wissen wollen, wie Lizenz, vorgesehene Plattform, Status (alpha, beta, stable...), wo sie herunterzuladen ist, wer sie geschrieben hat, ob Support verfügbar ist... etc.<br />
<br />
Die folgende Prozedur läßt sie eine Code Release Seite mit ihrem Browser erzeugen: <br />
<br />
* Gehen sie zu [[Release new component]]<br />
* Tippen sie den Namen ihrer Komponente in die Textbox und klicken auf ''Create Article''<br />
* Bearbeiten sie danach die Vorlage und vergessen sie nicht zu speichern.<br />
* Bearbeiten sie die [[Components and Code examples]] Seite und fügen den Link zu ihrer gerade erzeugten Seite hinzu im "Released Components" Abschnitt. Speichern sie die geänderte Seite.<br />
<br />
=== Einreichen der Komponente ===<br />
<br />
If you're a release technician on the project, uploaden sie ihre Komponente in das SourceForge File Release System und fügen sie sie zur Liste der release Packages hinzu. Sonst senden sie es zu einem der Projektadministratoren ([[User:Tom |Tom Lisjac]] oder [[User:Vincent |Vincent Snijders]]) und wir werden es zum Repository hinzufügen. Bevor wir es zu SourceForge hochladen, müssen sie eine ''Code Release Page'' erstellen, um ihre Komponente zu beschreiben. Sie können die [[Release new component]] Seite verwenden, um mit der Erzeugung einer solchen Seite zu beginnen.<br />
<br />
Wenn sie denken, daß sie die Entwicklung der Komponente fortsetzen müssen, we can also put it into SVN so you'll continue to have access to it. If we get tired from submitting your patches, we will give you write access to the SVN, so you can commit your patches yourself. For details see [[Using the Lazarus-ccr SVN repository]].<br />
<br />
== Mitwirkende und Änderungen ==<br />
<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide Version] konvertiert.<br />
* Anfangsversion von Tom Lisjac und Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux wurde in LCLIntf umbenannt, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003<br />
* Abschnitt 'Another method to convert a Delphi or Kylix project to Lazarus' hinzugefügt , [[User:Glober | George Lober]], 2/17/2006</div>MaDhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide/de&diff=16234Code Conversion Guide/de2007-01-19T10:45:44Z<p>MaD: /* Eigenschaften und Methoden Unterschiede Delphi -> FPC/LCL */ übersetzt</p>
<hr />
<div>{{Code Conversion Guide}}<br />
<br />
Diese Seite handelt darüber, wie man bestehenden Delphi oder Kylix Code konvertiert, um ihn mit dem [[Free Pascal/de|Free Pascal]] Compiler und der Lazarus IDE zum Laufen zu bringen. Obwohl Lazarus und der Free Pascal Compiler gemeinsame Aspekte mit Delphi und Kylix haben, sind sie keine Klone. Es gibt eine Anzahl von Bibliotheksaufrufen und Konventionsunterschieden... und in einigen Bereichen ist FPC erweitert und kann anspruchsvoller sein about correct syntax. Bitte schauen sie im [[Lazarus For Delphi Users/de|Lazarus für Delphi Benutzer]] Handbuch nach für eine Beschreibung von einigen der funktionellen Unterschiede. <br />
<br />
Der Zweck dieses Handbuchs ist es, einige der spezifischen Unterschiede zu dokumentieren, die häufig auftreten während des Codekonvertierungsprozesses, wenn existierender Code von Delphi nach Lazarus übersetzt wird.<br />
<br />
Dieses Dokument wurde im Wissensbasis Bereich des Wikis platziert, so daß es einfach erweitert werden kann von jedem, der auf ein einzigartiges Problem gestoßen ist und andere darauf aufmerksam machen möchte.<br />
<br />
== Auswahl einer Komponente oder Bibliothek für die Konvertierung ==<br />
<br />
=== Wo Code zum Konvertieren zu finden ist ===<br />
<br />
Im Internet ist eine MENGE von Code verfügbar, der konvertiert werden kann für die Verwendung mit FPC und Lazarus. Hier ist eine [[Page Of Code Sites|Seite]], die einfach ein Anfang ist. Bitte erweitern sie die Seite, wenn sie weitere Stellen kennen. TurboPower Software has recently released their entire commercial offering under the MPL. Eine Liste von verfügbaren Packages ist [http://sourceforge.net/users/tpsfadmin/ hier] zu finden.<br />
<br />
Um doppelten Aufwand zu vermeiden, sind bereits konvertierte Packages gelistet auf der [[Components and Code examples]] Seite. Wenn sie ein Package konvertiert haben oder daran arbeiten, dann fügen sie bitte eine Notiz auf der [[Current conversion projects]] Seite hinzu.<br />
<br />
=== Lizenzierung ===<br />
<br />
Lizenzen für existierenden Code reichen von Freeware/Public Domain bis zu eingeschränkten Versionen, welche Modifizierung, Weiterverteilung und kommerzielle Verwendung verbieten. Bevor sie irgendein Package konvertieren, ist es eine gute Idee, seine Lizenz zu überprüfen und sicherzustellen, daß sie kompatibel wird mit Lazarus und dem Free Pascal Compiler. Lizenzauswahl ist besonders wichtig bei Komponenten, seit das Ablegen auf einem Formular eine nicht gewollte oder inkompatible Lizenz für die gesamte Anwendung aufbürden kann.<br />
<br />
Wenn sie Komponenten konvertieren, respektieren sie bitte die Wünsche des Originalautors und belassen alle Copyright- und Lizenz-Header mit Email-Adressen und URl's. Es gehört zum guten Ton und ist oft hilfreich, um den Autor zu informieren, daß seine Komponente konvertiert wurde... besonders wenn sich die Komponente unter einer restriktiven Lizenz befindet. Neues Interesse an einer alten oder vergessenen Komponente kann manchmal die Autoren inspirieren, um ihr Original und die allzu restriktive Lizenzierung zu überarbeiten.<br />
<br />
Im Allgemeinen sind Public Domain (Freeware) und die LGPL/MPL Komponenten die flexibelsten zum Vertreiben. Für mehr Information ist die [http://www.opensource.org/docs/definition.php Open Source Definition] ein guter Platz zum starten. Dort gibt es auch verschiedene Vergleiche to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Suchen sie nach "open source license comparison"<br />
<br />
=== Abhängigkeiten ===<br />
<br />
Ein anderer Schritt bevor sie an einer Konvertierung arbeiten ist, daß sie überprüfen, daß der Code keine verborgenen Abhängigkeiten von anderen Packages enthält, die nicht verfügbar sein können oder einen beträchtlichen Konvertierungsaufwand darstellen. Einige Freeware Angebote sind gebunden an oder erweitern proprietäre Packages, die häufig nicht länger erhältlich sind oder mit ungeeigneten Lizenzen kommen.<br />
<br />
=== Compiler Probleme ===<br />
<br />
Siehe:<br />
* [http://www.freepascal.org/probs.html bekannte Probleme]<br />
* [http://www.freepascal.org/bugs/db.php3?statusfield=Unfixed Nichtbereinigte Bugs]<br />
<br />
=== Plattform und OS Probleme ===<br />
<br />
Lazarus und der Free Pascal Compiler sind [[Glossary#CrossPlatform|cross-platform]] und cross-architecture Entwicklungswerkzeuge. Im Gegensatz wurde der meiste existierende Delphi Code speziell vorgesehen, auf einem Intel Prozessor unter Win32 zu laufen. Wenn ihr Kandidat eine Menge von Win32 spezifischem Code hat, mag es weise sein, nach einer weniger plattformabhängigen Alternative zu suchen. Aber lassen sie sich davon nicht entmutigen. Es ist erstaunlich, was die LCL unterstützt!<br />
<br />
== Durchführen der Konvertierung ==<br />
<br />
=== Einrichten der Lazarus Umgebung für ein Konvertierungs-Projekt ===<br />
<br />
==== Erstellen eines Testprojekts ====<br />
* Platzieren sie den zu konvertierenden Code in ein Unterverzeichnis (z.B.: convertdir)<br />
* Holen sie Lazarus hervor<br />
* Datei -> Alles speichern in das convertdir Unterverzeichnis. Aussagekräftige Namen für Projekt und Units sind optional.<br />
* Öffnen sie die zu konvertierende "main" Unit in convertdir<br />
* Fügen sie sie zum Projekt hinzu: Projekt -> Datei im Editor ins Projekt aufnehmen<br />
* Starten sie Werkzeuge -> Schnelle Syntaxüberprüfung oder Start -> Alles neu erstellen um loszulegen.<br />
<br />
==== Initial items to watch out for ====<br />
* Dateinamen sind case sensitive with the 1.0.x series compilers. Wenn sie mit dieser Version arbeiten, schreiben sie alle Dateinamen klein. Sie werden "File not found" Fehler bekommen, wenn sie es nicht tun.<br />
<br />
==== Delphi VCL, Kylix CLX Quellen in Lazarus ====<br />
<br />
Während der Konvertierung von Delphi/Kylix Quellen ist es oft hilfreich, eine find declaration zu machen um zu sehen, was eine bestimmte Funktion macht. Die Lazarus IDE kann die Delphi/Kylix Quellen analysieren. Um dies zu tun werden einige Suchpfade und Compilereinstellungen benötigt. Sie können dies einfach einrichten unter<br />
<br />
Einstellungen -> CodeTools Defines Editor -> Vorlage einfügen<br />
<br />
=== Konvertierungsprobleme und Lösungen ===<br />
<br />
==== Delphi / Kylix Datei-Entsprechungen in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Beschreibung<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr (main project file)<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi (main project file)<br />
.ppu<br />
| class="code" |Pascal Unit Datei<br />
Formulardaten Datei<br />
Compilierte Unit Datei<br />
Projektdatei<br />
Ressourcendatei<br />
Projektoptionen Datei<br />
Lazarus Ressourcen Datei<br />
Lazarus Projekt Informations Datei<br />
FPC Unit Beschreibungsdatei<br />
|}<br />
<br />
==== Konvertierung von Delphi Projekten/Formularen/Units nach Lazarus ====<br />
<br />
Benennen sie die .dpr Datei in eine .lpr Datei um. Kommentieren sie die <div class="dir">{$R *.res}</div> Direktive aus oder entfernen sie und fügen eine <div class="dir">{$mode delphi}{$H+}</div> oder <div class="dir">{$mode objfpc}{$H+}</div> Direktive zur .lpr Datei hinzu. Die Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". Sie fragt nach einer .dpr (Delphi Project) Datei und konvertiert sie in eine .lpr; außerdem erzeugt sie die .lpi Datei und konvertiert alle Units.<br />
<br />
Viele existierende Delphi Formulare können konvertiert werden um mit Lazarus zu funktionieren durch Verwendung des in die IDE eingebauten .dfm to .lfm form Umwandlers. Er ist zu finden im Werkzeuge Menü als "Convert DFM file to LFM". Bring up the file dialog, wählen sie die dfm Datei und der Umwandler wird den Rest erledigen.<br />
<br />
Wenn sie die ganze Unit konvertieren müssen (mit oder ohne ein Formular), enhält Lazarus auch ein eingebautes "Convert Delphi unit to Lazarus unit", welches das folgende für sie erledigt -<br />
<br />
# fixes the case of include filenames and uses sections.<br />
# konvertiert die .dfm Datei in eine .lfm Datei (gegenwärtig ohne Inhaltsprüfung, nur Formatierung)<br />
# erzeugt eine leere .lrs Datei (der Inhalt wird später erzeugt)<br />
# fügt die <div class="dir">{$mode delphi}</div> Direktive hinzu<br />
# ersetzt die windows Unit durch LCLIntf<br />
# adds LResources unit if needed (i.e., if unit.lrs is to be used; <div class="dir">uses LResources </div> can be in the implementation part)<br />
# entfernt die variants Unit<br />
# entfernt die <div class="dir">{$R *.dfm}</div> Direktive<br />
# fügt den initialization Abschnitt und die <div class="dir">{$i unit.lrs}</div> Direktive hinzu<br />
<br />
==== Auswahl des richtigen Compilermodus ====<br />
<br />
Der [[Free Pascal/de|Free Pascal]] Compiler unterstützt 5 unterschiedliche Pascal Modi. Zum Beispiel TP für Turbo Pascal, lässt sie Turbo Pascal Units kompilieren. Es gibt auch einen DELPHI Kompatibilitäts-Modus, der gesetzt werden kann, um bestehenden Code einfacher zu konvertieren. Lazarus bevorzugt den OBJFPC Modus, welcher fast dem DELPHI Modus gleicht, aber weniger mehrdeutig als die Delphi Syntax ist. Hier sind die wichtigen Punkte:<br />
<br />
Der Modus kann auf der Befehlszeile oder beim Start der Quelle gewählt werden. Die Verwendung der Befehlszeile hat den Vorteil, daß sie die Quelle nicht ändern müssen, aber den Nachteil, daß anderes erzählt werden muß.<br />
<br />
Die meisten Delphi Units können mit dem [[Free Pascal/de|Free Pascal]] Compiler kompiliert werden durch hinzufügen von <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
gleich nach dem Unit Namen.<br />
<br />
Für mehr Details über die [[Free Pascal/de|Free Pascal]] Modi siehe die [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Dokumentation].<br />
<br />
==== Cross-Plattform Überlegungen ====<br />
<br />
* Inline Assembler ist immer ein Problem, weil er den Code an die Intel Architektur bindet. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately TurboPower did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* Wenn sie Betriebssystem-spezifischen Code benötigen, dann können sie IFDEFs verwenden. Siehe unten für eine Liste der Makros.<br />
<br />
==== Hilfreiche Compiler Variablen ====<br />
<br />
Um Code zu schreiben, der sich auf verschiedenen Systemen unterschiedlich verhält, können sie die <div class="dir">{$IFDEF Name}</div> Anweisungen verwenden.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird. Hilfreich um Code zu schreiben, der mit der LCL und Delphi funktioniert.<br />
* <div class="dir">{$IfDef LCLGtk}</div>, <div class="dir">{$IfDef LCLWin32}</div>, <div class="dir">{$IfDef LCLQt}</div>, ...<br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird und das spezifische widgetset is currently used. Hilfreich um Code zu schreiben, der mit der LCL auf einer spezifischen Plattform funktioniert.<br />
* <div class="dir">{$IfDef FPC}</div><br />
Diese Variable ist definiert, wenn der FPC Compiler verwendet wird. Hilfreich um Code zu schreiben, der mit FPC und Delphi funktioniert.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Von FPC für das aktuelle Ziel OS definiert. Delphi definiert "Linux", "Win32" und "MSWindows". [[Free Pascal/de|Free Pascal]] läuft auf viel mehr Plattformen und daher wird empfohlen, allgemeinere Begriffe zu verwenden. Zum Beispiel ist "Unix" definiert für Linux, FreeBSD, NetBSD und OpenBSD, wo Lazarus bereits läuft.<br />
Verwenden sie<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
Für mehr Details siehe die [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Dokumentation].<br />
<br />
==== Finden eines fehlenden Bezeichners ====<br />
<br />
Es gibt Unterschiede darin, wie die LCL organisiert ist im Vergleich zur Delphi VCL. Wenn sie einen "not found" Compilerfehler erhalten über eine wichtige Klasse oder Bezeichner, stehen die Chancen gut, daß Sie die Klasse oder den Bezeichner in einer anderen Unit finden könne. Eine komplette Cross-Reference können Sie finden, indem Sie grep auf das Verzeichnis lazarus/docs/xml oder das Unterverezeichnis lcl anwenden.<br />
<br />
Zum Beispiel erzeugt der häufig verwendete TButton üblicherweise einen Fehler im Delphi Code, weil er sich in der Unit buttons.pp befindet. Das folgende Kommando findet die richtige Unit sehr schnell (im Lazarus Quellenverzeichnis):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
==== Wichtige Unit Unterschiede zwischen Lazarus und Delphi ====<br />
<br />
'''Bitte ergänzen sie diesen Abschnitt!'''<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
Die die LCL nicht Windows-spezifisch ist, ist der Code, der sich in der Delphi Windows Unit für den direkten Zugriff auf das Win32 API befindet, abstrahiert in separate Schnittstellen, auf welche mit der LCLIntf Unit Zugriff besteht. Beachten Sie, daß Lazarus nicht win32 emuliert, so daß mehrere Funktionen fehlen und einige nicht wie ihre win32-Gegenstücke funktionieren. Diese Funktionen existieren nur für die Delphi-Kompatibilität und sollten nur für Quick&Dirty-Portierungen benutzt werden. LCL beinhalte auch viele Typen nicht, so daß oftmals LCLType und manchmal VCLGlobals benötigt werden. LCLProc enthält auch ein paar Funktionen, die hilfreich sein können für maschinennahere Bearbeitung wie "FreeThenNil" wie in Delphi 5 und höher, "DeleteAmpersands" um zusätzliche Et-Zeichen aus Zeichenketten für Kontrollen zu entfernen (vs && etc). Die Interfaces-Unit muß in der .lpr Datei enthalten sein, um das passende widgetset zu initialisieren.<br />
<br />
* Messages->LMessages<br />
<br />
TControl-Messages für win32-Ereignis-Callbacks vom Format WM_CALLBACK und die Structs, die dazugehören, finden sich oftmals in der Messages-Unit in Delphi. In LCL befinden diese sich meistens in LMessages, üblicherweise mit einer Namensänderung von WM zu LM, zum Beispiel WM_MOUSEENTER wird LM_MOUSEENTER, und TWMMouse wird TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
Um einige Sachen zu vereinfachen und die Komplexität von Kreisabhängigkeiten zwischen Units zu verringern, wurden einige Typen in einee gemeinsamen Unit namens GraphType abstrahiert, die sich in Delphi in Graphics oder Controls befinden, bspw. das bvNone usw. von Panels. Deswegen müssen Sie diese Unit gelegentlich einbinden. Eine weitere Unit, leider inkompatibel zu Delphi, liefert zusätzliche Funktionalität, GraphMath. Sie ermöglicht TFloatPoints für präzise Berechnungen, verschiedene Routinen für den Umgang mit Beziers, Linien und Kreisbögen, sowie überladene Operatoren zur Benutzung mit TPoints und TRect, um Punkte derart zu addieren Point1 := Point2 + Point3 oder Rechtecke zu vergleichen if(rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
Aus Überlegungen für eine bessere Benennung wurde die Unit für TMaskEdit [MaskeDit |] anstelle des leicht unklareren Mask wie in vielen Delphi Versionen.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In vielen Delphi Versionen befindet sich TButton in StdCtrls, während TSpeedButton und TBitBtn sich in Buttons befinden. Für eine Stetigkeit und Einfachheit steckt die LCL alle Buttontypen in Buttons, was gelegentlich die Code-Konvertierung ins Leere laufen lassen kann -- es ist also eine gute Idee, diese einzubinden.<br />
<br />
==== Eigenschaften und Methoden Unterschiede Delphi -> FPC/LCL ====<br />
* TBitmap verfügt über einen Kanvas in der LCL<br />
<br />
==== Syntax Unterschiede ====<br />
<br />
'''Bitte fügen sie weitere Informationen zu diesem Thema hinzu!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though <div class="dir">{$Mode Delphi}</div> does allow more laziness like Delphi does. For this reason complying as much with the syntax rules of <div class="dir">{$Mode ObjFPC}</div> as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practices, and sometimes because Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
<br />
===== When assigning an event handling entry point, prefix it with an "@" =====<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ wird nicht benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ wird benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== Wenn sie eine Prozedurenvariable aufrufen verwenden sie diese Syntax: theprocname() =====<br />
<br />
In Delphi gibt es keinen Unterschied zwischen dem Ergebnis einer Funktion und einer Variablen, jedoch in FPC gibt es einen, so um eine Funktion aufzurufen, selbst wenn sie keine Parameter hat, müssen sie eine runde Klammer anhängen. Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//runde Klammer nicht benötigt</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//runde Klammer benötigt</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== When accessing values in a pointer to a record you must dereference first =====<br />
<br />
In Delphi it is not required to de-reference a pointer to a record to access values within it, it can, in fact, be treated just like the record itself, or any other object. In FPC it must be first de-referenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
===== When accessing chars of an indexed string Property of an object, it must be enclosed in parentheses =====<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parentheses, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
===== You must typecast pointers to actual type when using with var or function of that type =====<br />
<br />
In Delphi haben sie manchmal eine null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Ressourcen ====<br />
<br />
Delphi Ressourcendateien sind Win32 spezifisch und nicht kompatibel mit Lazarus, so daß sie sie neu erstellen und mit Lazres kompilieren müssen. Lazres ist im lazarus/tools Unterverzeichnis zu finden. Wenn sie die Lazarus Quellen heruntergeladen haben, müssen sie es erst kompilieren.<br />
* cd lazarus/tools<br />
* make install<br />
Um eine Ressource zu ihrer Anwendung hinzuzufügen:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Fügen sie die LResources Unit zu ihrem Uses Abschnitt hinzu<br />
* Nehmen sie die von ihnen erstellte .lrs Datei unter dem initialization Abschnitt auf<br />
Beispiel:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
=== Eine andere Methode um ein Delphi oder Kylix Projekt nach Lazarus zu konvertieren ===<br />
<br />
* Benennen sie alle .dfm oder .xfm Dateien in .lfm um. (Dies funktioniert nicht mit frühen Delphi Versionen da sie keine textbasierte .dfm Datei erstellen.)<br />
* Benennen sie die .dpr Datei in .lpr um.<br />
* Nehmen sie notwendige Änderungen in der .lpr Datei vor:<br />
# Fügen sie {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'Interfaces' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.res} Direktive aus oder löschen sie diese.<br />
* Nehmen sie notwendige Änderungen in allen .pas Unit Dateien vor:<br />
# Fügen sie die {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'LResources', und wenn das Formular Buttons hat, 'Buttons' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.dfm} oder {$R *.xfm} Direktive aus oder löschen sie diese.<br />
# Fügen sie einen 'Initialization' Abschnitt am Ende jeder Datei hinzu, und fügen die {$I unitname.lrs} Direktive darin hinzu.<br />
* Wählen sie Projekt -> Neues Projekt von Datei<br />
* Wählen sie die .lpr Datei<br />
* Im 'Erzeuge neues Projekt' Fenster wählen sie 'Anwendung'<br />
* Erzeugen sie das Projekt und nehmen sie weitere notwendige Korrekturen vor um eine ordentliche Kompilierung zu erhalten, an diesem Punkt wird die .lpi Datei automatisch generiert. Sie erhalten vielleicht 'Error reading Form' Meldungen. Klicken sie auf 'Continue Loading' falls dem so ist. <br />
* Speichern sie alles und sie haben ein Lazarus Projekt :-)<br />
<br />
== Hilfe erhalten ==<br />
<br />
Wenn sie während der Konvertierung auf ein Problem stoßen, das sie gerade nicht lösen können, gibt es eine große Auswahl von Orten, um Hilfe zu erhalten. Für reine Object Pascal und FPC Probleme, ist der beste Ort zu beginnen die Free Pascal [http://www.freepascal.org/docs-html/ Dokumentation] von Michaël Van Canneyt und Florian Klämpfl. Für mehr Lazarus orientierte Probleme ist die Lazarus Projekt Dokumentation in der [[Main Page/de|Lazarus-CCR Knowledgebase]] der nächste Ort zum nachschauen. Schließlich können sie eine Frage posten in einer der [http://www.freepascal.org/maillist.html Mailing Listen] für den Free Pascal Compiler oder den [http://community.freepascal.org:10000/bboard/ FPC Foren], wo eine Menge Experten eingeschrieben sind.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates betreibt eine schnelle [http://www.tamaracka.com/search.htm Such] Engine speziell für die Borland Usenet Archive. Mer Systems Inc. bietet eine ähnliche Such [http://www.mers.com/searchsite.html Engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Erstellen eines Lazarus Package für ihre Komponente(n) ===<br />
<br />
Das Erstellen eines Packages macht die Installation ihres konvertierten Codes viel einfacher... besonders wenn sie mehr als eine Komponente anbieten. Mattias Gärtner hat eine Übersicht über [[Lazarus Packages/de|Lazarus Packages]] geschrieben, die gelesen werden sollte bevor sie mit diesem Prozess beginnen.<br />
<br />
=== Dokumentation ===<br />
<br />
Der Zweck dieser Seite und dem Wiki Format ist, die Generierung einer professionellen Dokumenation zu einem einfachen und schnellen Prozess zu machen. Das Wiki macht es auch möglich, die Resultate ihres posting unverzüglich zu sehen und erlaubt ihnen, Änderungen in Echtzeit zu machen.<br />
<br />
Die Verwendung des Lazarus-CCR Wiki um eine schön anzuschauende Dokumentation zu erstellen ist sehr einfach. Wenn sie noch nie zuvor die Wiki Sprache verwendet haben, können sie sich damit vertraut machen in dem [[Sand Box]] Übungsbereich.<br />
<br />
=== Erzeugen einer Code Release Page ===<br />
<br />
Die Code Release Page enthält grundlegende Informationen über ihre Komponente, die ein potenzieller Nutzer wird wissen wollen, wie Lizenz, vorgesehene Plattform, Status (alpha, beta, stable...), wo sie herunterzuladen ist, wer sie geschrieben hat, ob Support verfügbar ist... etc.<br />
<br />
Die folgende Prozedur läßt sie eine Code Release Seite mit ihrem Browser erzeugen: <br />
<br />
* Gehen sie zu [[Release new component]]<br />
* Tippen sie den Namen ihrer Komponente in die Textbox und klicken auf ''Create Article''<br />
* Bearbeiten sie danach die Vorlage und vergessen sie nicht zu speichern.<br />
* Bearbeiten sie die [[Components and Code examples]] Seite und fügen den Link zu ihrer gerade erzeugten Seite hinzu im "Released Components" Abschnitt. Speichern sie die geänderte Seite.<br />
<br />
=== Einreichen der Komponente ===<br />
<br />
If you're a release technician on the project, uploaden sie ihre Komponente in das SourceForge File Release System und fügen sie sie zur Liste der release Packages hinzu. Sonst senden sie es zu einem der Projektadministratoren ([[User:Tom |Tom Lisjac]] oder [[User:Vincent |Vincent Snijders]]) und wir werden es zum Repository hinzufügen. Bevor wir es zu SourceForge hochladen, müssen sie eine ''Code Release Page'' erstellen, um ihre Komponente zu beschreiben. Sie können die [[Release new component]] Seite verwenden, um mit der Erzeugung einer solchen Seite zu beginnen.<br />
<br />
Wenn sie denken, daß sie die Entwicklung der Komponente fortsetzen müssen, we can also put it into SVN so you'll continue to have access to it. If we get tired from submitting your patches, we will give you write access to the SVN, so you can commit your patches yourself. For details see [[Using the Lazarus-ccr SVN repository]].<br />
<br />
== Mitwirkende und Änderungen ==<br />
<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide Version] konvertiert.<br />
* Anfangsversion von Tom Lisjac und Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux wurde in LCLIntf umbenannt, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003<br />
* Abschnitt 'Another method to convert a Delphi or Kylix project to Lazarus' hinzugefügt , [[User:Glober | George Lober]], 2/17/2006</div>MaDhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide/de&diff=16233Code Conversion Guide/de2007-01-19T10:44:46Z<p>MaD: /* Wichtige Unit Unterschiede zwischen Lazarus und Delphi */ auch hier: übersetzt</p>
<hr />
<div>{{Code Conversion Guide}}<br />
<br />
Diese Seite handelt darüber, wie man bestehenden Delphi oder Kylix Code konvertiert, um ihn mit dem [[Free Pascal/de|Free Pascal]] Compiler und der Lazarus IDE zum Laufen zu bringen. Obwohl Lazarus und der Free Pascal Compiler gemeinsame Aspekte mit Delphi und Kylix haben, sind sie keine Klone. Es gibt eine Anzahl von Bibliotheksaufrufen und Konventionsunterschieden... und in einigen Bereichen ist FPC erweitert und kann anspruchsvoller sein about correct syntax. Bitte schauen sie im [[Lazarus For Delphi Users/de|Lazarus für Delphi Benutzer]] Handbuch nach für eine Beschreibung von einigen der funktionellen Unterschiede. <br />
<br />
Der Zweck dieses Handbuchs ist es, einige der spezifischen Unterschiede zu dokumentieren, die häufig auftreten während des Codekonvertierungsprozesses, wenn existierender Code von Delphi nach Lazarus übersetzt wird.<br />
<br />
Dieses Dokument wurde im Wissensbasis Bereich des Wikis platziert, so daß es einfach erweitert werden kann von jedem, der auf ein einzigartiges Problem gestoßen ist und andere darauf aufmerksam machen möchte.<br />
<br />
== Auswahl einer Komponente oder Bibliothek für die Konvertierung ==<br />
<br />
=== Wo Code zum Konvertieren zu finden ist ===<br />
<br />
Im Internet ist eine MENGE von Code verfügbar, der konvertiert werden kann für die Verwendung mit FPC und Lazarus. Hier ist eine [[Page Of Code Sites|Seite]], die einfach ein Anfang ist. Bitte erweitern sie die Seite, wenn sie weitere Stellen kennen. TurboPower Software has recently released their entire commercial offering under the MPL. Eine Liste von verfügbaren Packages ist [http://sourceforge.net/users/tpsfadmin/ hier] zu finden.<br />
<br />
Um doppelten Aufwand zu vermeiden, sind bereits konvertierte Packages gelistet auf der [[Components and Code examples]] Seite. Wenn sie ein Package konvertiert haben oder daran arbeiten, dann fügen sie bitte eine Notiz auf der [[Current conversion projects]] Seite hinzu.<br />
<br />
=== Lizenzierung ===<br />
<br />
Lizenzen für existierenden Code reichen von Freeware/Public Domain bis zu eingeschränkten Versionen, welche Modifizierung, Weiterverteilung und kommerzielle Verwendung verbieten. Bevor sie irgendein Package konvertieren, ist es eine gute Idee, seine Lizenz zu überprüfen und sicherzustellen, daß sie kompatibel wird mit Lazarus und dem Free Pascal Compiler. Lizenzauswahl ist besonders wichtig bei Komponenten, seit das Ablegen auf einem Formular eine nicht gewollte oder inkompatible Lizenz für die gesamte Anwendung aufbürden kann.<br />
<br />
Wenn sie Komponenten konvertieren, respektieren sie bitte die Wünsche des Originalautors und belassen alle Copyright- und Lizenz-Header mit Email-Adressen und URl's. Es gehört zum guten Ton und ist oft hilfreich, um den Autor zu informieren, daß seine Komponente konvertiert wurde... besonders wenn sich die Komponente unter einer restriktiven Lizenz befindet. Neues Interesse an einer alten oder vergessenen Komponente kann manchmal die Autoren inspirieren, um ihr Original und die allzu restriktive Lizenzierung zu überarbeiten.<br />
<br />
Im Allgemeinen sind Public Domain (Freeware) und die LGPL/MPL Komponenten die flexibelsten zum Vertreiben. Für mehr Information ist die [http://www.opensource.org/docs/definition.php Open Source Definition] ein guter Platz zum starten. Dort gibt es auch verschiedene Vergleiche to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Suchen sie nach "open source license comparison"<br />
<br />
=== Abhängigkeiten ===<br />
<br />
Ein anderer Schritt bevor sie an einer Konvertierung arbeiten ist, daß sie überprüfen, daß der Code keine verborgenen Abhängigkeiten von anderen Packages enthält, die nicht verfügbar sein können oder einen beträchtlichen Konvertierungsaufwand darstellen. Einige Freeware Angebote sind gebunden an oder erweitern proprietäre Packages, die häufig nicht länger erhältlich sind oder mit ungeeigneten Lizenzen kommen.<br />
<br />
=== Compiler Probleme ===<br />
<br />
Siehe:<br />
* [http://www.freepascal.org/probs.html bekannte Probleme]<br />
* [http://www.freepascal.org/bugs/db.php3?statusfield=Unfixed Nichtbereinigte Bugs]<br />
<br />
=== Plattform und OS Probleme ===<br />
<br />
Lazarus und der Free Pascal Compiler sind [[Glossary#CrossPlatform|cross-platform]] und cross-architecture Entwicklungswerkzeuge. Im Gegensatz wurde der meiste existierende Delphi Code speziell vorgesehen, auf einem Intel Prozessor unter Win32 zu laufen. Wenn ihr Kandidat eine Menge von Win32 spezifischem Code hat, mag es weise sein, nach einer weniger plattformabhängigen Alternative zu suchen. Aber lassen sie sich davon nicht entmutigen. Es ist erstaunlich, was die LCL unterstützt!<br />
<br />
== Durchführen der Konvertierung ==<br />
<br />
=== Einrichten der Lazarus Umgebung für ein Konvertierungs-Projekt ===<br />
<br />
==== Erstellen eines Testprojekts ====<br />
* Platzieren sie den zu konvertierenden Code in ein Unterverzeichnis (z.B.: convertdir)<br />
* Holen sie Lazarus hervor<br />
* Datei -> Alles speichern in das convertdir Unterverzeichnis. Aussagekräftige Namen für Projekt und Units sind optional.<br />
* Öffnen sie die zu konvertierende "main" Unit in convertdir<br />
* Fügen sie sie zum Projekt hinzu: Projekt -> Datei im Editor ins Projekt aufnehmen<br />
* Starten sie Werkzeuge -> Schnelle Syntaxüberprüfung oder Start -> Alles neu erstellen um loszulegen.<br />
<br />
==== Initial items to watch out for ====<br />
* Dateinamen sind case sensitive with the 1.0.x series compilers. Wenn sie mit dieser Version arbeiten, schreiben sie alle Dateinamen klein. Sie werden "File not found" Fehler bekommen, wenn sie es nicht tun.<br />
<br />
==== Delphi VCL, Kylix CLX Quellen in Lazarus ====<br />
<br />
Während der Konvertierung von Delphi/Kylix Quellen ist es oft hilfreich, eine find declaration zu machen um zu sehen, was eine bestimmte Funktion macht. Die Lazarus IDE kann die Delphi/Kylix Quellen analysieren. Um dies zu tun werden einige Suchpfade und Compilereinstellungen benötigt. Sie können dies einfach einrichten unter<br />
<br />
Einstellungen -> CodeTools Defines Editor -> Vorlage einfügen<br />
<br />
=== Konvertierungsprobleme und Lösungen ===<br />
<br />
==== Delphi / Kylix Datei-Entsprechungen in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Beschreibung<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr (main project file)<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi (main project file)<br />
.ppu<br />
| class="code" |Pascal Unit Datei<br />
Formulardaten Datei<br />
Compilierte Unit Datei<br />
Projektdatei<br />
Ressourcendatei<br />
Projektoptionen Datei<br />
Lazarus Ressourcen Datei<br />
Lazarus Projekt Informations Datei<br />
FPC Unit Beschreibungsdatei<br />
|}<br />
<br />
==== Konvertierung von Delphi Projekten/Formularen/Units nach Lazarus ====<br />
<br />
Benennen sie die .dpr Datei in eine .lpr Datei um. Kommentieren sie die <div class="dir">{$R *.res}</div> Direktive aus oder entfernen sie und fügen eine <div class="dir">{$mode delphi}{$H+}</div> oder <div class="dir">{$mode objfpc}{$H+}</div> Direktive zur .lpr Datei hinzu. Die Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". Sie fragt nach einer .dpr (Delphi Project) Datei und konvertiert sie in eine .lpr; außerdem erzeugt sie die .lpi Datei und konvertiert alle Units.<br />
<br />
Viele existierende Delphi Formulare können konvertiert werden um mit Lazarus zu funktionieren durch Verwendung des in die IDE eingebauten .dfm to .lfm form Umwandlers. Er ist zu finden im Werkzeuge Menü als "Convert DFM file to LFM". Bring up the file dialog, wählen sie die dfm Datei und der Umwandler wird den Rest erledigen.<br />
<br />
Wenn sie die ganze Unit konvertieren müssen (mit oder ohne ein Formular), enhält Lazarus auch ein eingebautes "Convert Delphi unit to Lazarus unit", welches das folgende für sie erledigt -<br />
<br />
# fixes the case of include filenames and uses sections.<br />
# konvertiert die .dfm Datei in eine .lfm Datei (gegenwärtig ohne Inhaltsprüfung, nur Formatierung)<br />
# erzeugt eine leere .lrs Datei (der Inhalt wird später erzeugt)<br />
# fügt die <div class="dir">{$mode delphi}</div> Direktive hinzu<br />
# ersetzt die windows Unit durch LCLIntf<br />
# adds LResources unit if needed (i.e., if unit.lrs is to be used; <div class="dir">uses LResources </div> can be in the implementation part)<br />
# entfernt die variants Unit<br />
# entfernt die <div class="dir">{$R *.dfm}</div> Direktive<br />
# fügt den initialization Abschnitt und die <div class="dir">{$i unit.lrs}</div> Direktive hinzu<br />
<br />
==== Auswahl des richtigen Compilermodus ====<br />
<br />
Der [[Free Pascal/de|Free Pascal]] Compiler unterstützt 5 unterschiedliche Pascal Modi. Zum Beispiel TP für Turbo Pascal, lässt sie Turbo Pascal Units kompilieren. Es gibt auch einen DELPHI Kompatibilitäts-Modus, der gesetzt werden kann, um bestehenden Code einfacher zu konvertieren. Lazarus bevorzugt den OBJFPC Modus, welcher fast dem DELPHI Modus gleicht, aber weniger mehrdeutig als die Delphi Syntax ist. Hier sind die wichtigen Punkte:<br />
<br />
Der Modus kann auf der Befehlszeile oder beim Start der Quelle gewählt werden. Die Verwendung der Befehlszeile hat den Vorteil, daß sie die Quelle nicht ändern müssen, aber den Nachteil, daß anderes erzählt werden muß.<br />
<br />
Die meisten Delphi Units können mit dem [[Free Pascal/de|Free Pascal]] Compiler kompiliert werden durch hinzufügen von <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
gleich nach dem Unit Namen.<br />
<br />
Für mehr Details über die [[Free Pascal/de|Free Pascal]] Modi siehe die [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Dokumentation].<br />
<br />
==== Cross-Plattform Überlegungen ====<br />
<br />
* Inline Assembler ist immer ein Problem, weil er den Code an die Intel Architektur bindet. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately TurboPower did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* Wenn sie Betriebssystem-spezifischen Code benötigen, dann können sie IFDEFs verwenden. Siehe unten für eine Liste der Makros.<br />
<br />
==== Hilfreiche Compiler Variablen ====<br />
<br />
Um Code zu schreiben, der sich auf verschiedenen Systemen unterschiedlich verhält, können sie die <div class="dir">{$IFDEF Name}</div> Anweisungen verwenden.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird. Hilfreich um Code zu schreiben, der mit der LCL und Delphi funktioniert.<br />
* <div class="dir">{$IfDef LCLGtk}</div>, <div class="dir">{$IfDef LCLWin32}</div>, <div class="dir">{$IfDef LCLQt}</div>, ...<br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird und das spezifische widgetset is currently used. Hilfreich um Code zu schreiben, der mit der LCL auf einer spezifischen Plattform funktioniert.<br />
* <div class="dir">{$IfDef FPC}</div><br />
Diese Variable ist definiert, wenn der FPC Compiler verwendet wird. Hilfreich um Code zu schreiben, der mit FPC und Delphi funktioniert.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Von FPC für das aktuelle Ziel OS definiert. Delphi definiert "Linux", "Win32" und "MSWindows". [[Free Pascal/de|Free Pascal]] läuft auf viel mehr Plattformen und daher wird empfohlen, allgemeinere Begriffe zu verwenden. Zum Beispiel ist "Unix" definiert für Linux, FreeBSD, NetBSD und OpenBSD, wo Lazarus bereits läuft.<br />
Verwenden sie<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
Für mehr Details siehe die [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Dokumentation].<br />
<br />
==== Finden eines fehlenden Bezeichners ====<br />
<br />
Es gibt Unterschiede darin, wie die LCL organisiert ist im Vergleich zur Delphi VCL. Wenn sie einen "not found" Compilerfehler erhalten über eine wichtige Klasse oder Bezeichner, stehen die Chancen gut, daß Sie die Klasse oder den Bezeichner in einer anderen Unit finden könne. Eine komplette Cross-Reference können Sie finden, indem Sie grep auf das Verzeichnis lazarus/docs/xml oder das Unterverezeichnis lcl anwenden.<br />
<br />
Zum Beispiel erzeugt der häufig verwendete TButton üblicherweise einen Fehler im Delphi Code, weil er sich in der Unit buttons.pp befindet. Das folgende Kommando findet die richtige Unit sehr schnell (im Lazarus Quellenverzeichnis):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
==== Wichtige Unit Unterschiede zwischen Lazarus und Delphi ====<br />
<br />
'''Bitte ergänzen sie diesen Abschnitt!'''<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
Die die LCL nicht Windows-spezifisch ist, ist der Code, der sich in der Delphi Windows Unit für den direkten Zugriff auf das Win32 API befindet, abstrahiert in separate Schnittstellen, auf welche mit der LCLIntf Unit Zugriff besteht. Beachten Sie, daß Lazarus nicht win32 emuliert, so daß mehrere Funktionen fehlen und einige nicht wie ihre win32-Gegenstücke funktionieren. Diese Funktionen existieren nur für die Delphi-Kompatibilität und sollten nur für Quick&Dirty-Portierungen benutzt werden. LCL beinhalte auch viele Typen nicht, so daß oftmals LCLType und manchmal VCLGlobals benötigt werden. LCLProc enthält auch ein paar Funktionen, die hilfreich sein können für maschinennahere Bearbeitung wie "FreeThenNil" wie in Delphi 5 und höher, "DeleteAmpersands" um zusätzliche Et-Zeichen aus Zeichenketten für Kontrollen zu entfernen (vs && etc). Die Interfaces-Unit muß in der .lpr Datei enthalten sein, um das passende widgetset zu initialisieren.<br />
<br />
* Messages->LMessages<br />
<br />
TControl-Messages für win32-Ereignis-Callbacks vom Format WM_CALLBACK und die Structs, die dazugehören, finden sich oftmals in der Messages-Unit in Delphi. In LCL befinden diese sich meistens in LMessages, üblicherweise mit einer Namensänderung von WM zu LM, zum Beispiel WM_MOUSEENTER wird LM_MOUSEENTER, und TWMMouse wird TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
Um einige Sachen zu vereinfachen und die Komplexität von Kreisabhängigkeiten zwischen Units zu verringern, wurden einige Typen in einee gemeinsamen Unit namens GraphType abstrahiert, die sich in Delphi in Graphics oder Controls befinden, bspw. das bvNone usw. von Panels. Deswegen müssen Sie diese Unit gelegentlich einbinden. Eine weitere Unit, leider inkompatibel zu Delphi, liefert zusätzliche Funktionalität, GraphMath. Sie ermöglicht TFloatPoints für präzise Berechnungen, verschiedene Routinen für den Umgang mit Beziers, Linien und Kreisbögen, sowie überladene Operatoren zur Benutzung mit TPoints und TRect, um Punkte derart zu addieren Point1 := Point2 + Point3 oder Rechtecke zu vergleichen if(rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
Aus Überlegungen für eine bessere Benennung wurde die Unit für TMaskEdit [MaskeDit |] anstelle des leicht unklareren Mask wie in vielen Delphi Versionen.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In vielen Delphi Versionen befindet sich TButton in StdCtrls, während TSpeedButton und TBitBtn sich in Buttons befinden. Für eine Stetigkeit und Einfachheit steckt die LCL alle Buttontypen in Buttons, was gelegentlich die Code-Konvertierung ins Leere laufen lassen kann -- es ist also eine gute Idee, diese einzubinden.<br />
<br />
==== Eigenschaften und Methoden Unterschiede Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax Unterschiede ====<br />
<br />
'''Bitte fügen sie weitere Informationen zu diesem Thema hinzu!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though <div class="dir">{$Mode Delphi}</div> does allow more laziness like Delphi does. For this reason complying as much with the syntax rules of <div class="dir">{$Mode ObjFPC}</div> as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practices, and sometimes because Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
<br />
===== When assigning an event handling entry point, prefix it with an "@" =====<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ wird nicht benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ wird benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== Wenn sie eine Prozedurenvariable aufrufen verwenden sie diese Syntax: theprocname() =====<br />
<br />
In Delphi gibt es keinen Unterschied zwischen dem Ergebnis einer Funktion und einer Variablen, jedoch in FPC gibt es einen, so um eine Funktion aufzurufen, selbst wenn sie keine Parameter hat, müssen sie eine runde Klammer anhängen. Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//runde Klammer nicht benötigt</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//runde Klammer benötigt</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== When accessing values in a pointer to a record you must dereference first =====<br />
<br />
In Delphi it is not required to de-reference a pointer to a record to access values within it, it can, in fact, be treated just like the record itself, or any other object. In FPC it must be first de-referenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
===== When accessing chars of an indexed string Property of an object, it must be enclosed in parentheses =====<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parentheses, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
===== You must typecast pointers to actual type when using with var or function of that type =====<br />
<br />
In Delphi haben sie manchmal eine null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Ressourcen ====<br />
<br />
Delphi Ressourcendateien sind Win32 spezifisch und nicht kompatibel mit Lazarus, so daß sie sie neu erstellen und mit Lazres kompilieren müssen. Lazres ist im lazarus/tools Unterverzeichnis zu finden. Wenn sie die Lazarus Quellen heruntergeladen haben, müssen sie es erst kompilieren.<br />
* cd lazarus/tools<br />
* make install<br />
Um eine Ressource zu ihrer Anwendung hinzuzufügen:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Fügen sie die LResources Unit zu ihrem Uses Abschnitt hinzu<br />
* Nehmen sie die von ihnen erstellte .lrs Datei unter dem initialization Abschnitt auf<br />
Beispiel:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
=== Eine andere Methode um ein Delphi oder Kylix Projekt nach Lazarus zu konvertieren ===<br />
<br />
* Benennen sie alle .dfm oder .xfm Dateien in .lfm um. (Dies funktioniert nicht mit frühen Delphi Versionen da sie keine textbasierte .dfm Datei erstellen.)<br />
* Benennen sie die .dpr Datei in .lpr um.<br />
* Nehmen sie notwendige Änderungen in der .lpr Datei vor:<br />
# Fügen sie {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'Interfaces' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.res} Direktive aus oder löschen sie diese.<br />
* Nehmen sie notwendige Änderungen in allen .pas Unit Dateien vor:<br />
# Fügen sie die {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'LResources', und wenn das Formular Buttons hat, 'Buttons' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.dfm} oder {$R *.xfm} Direktive aus oder löschen sie diese.<br />
# Fügen sie einen 'Initialization' Abschnitt am Ende jeder Datei hinzu, und fügen die {$I unitname.lrs} Direktive darin hinzu.<br />
* Wählen sie Projekt -> Neues Projekt von Datei<br />
* Wählen sie die .lpr Datei<br />
* Im 'Erzeuge neues Projekt' Fenster wählen sie 'Anwendung'<br />
* Erzeugen sie das Projekt und nehmen sie weitere notwendige Korrekturen vor um eine ordentliche Kompilierung zu erhalten, an diesem Punkt wird die .lpi Datei automatisch generiert. Sie erhalten vielleicht 'Error reading Form' Meldungen. Klicken sie auf 'Continue Loading' falls dem so ist. <br />
* Speichern sie alles und sie haben ein Lazarus Projekt :-)<br />
<br />
== Hilfe erhalten ==<br />
<br />
Wenn sie während der Konvertierung auf ein Problem stoßen, das sie gerade nicht lösen können, gibt es eine große Auswahl von Orten, um Hilfe zu erhalten. Für reine Object Pascal und FPC Probleme, ist der beste Ort zu beginnen die Free Pascal [http://www.freepascal.org/docs-html/ Dokumentation] von Michaël Van Canneyt und Florian Klämpfl. Für mehr Lazarus orientierte Probleme ist die Lazarus Projekt Dokumentation in der [[Main Page/de|Lazarus-CCR Knowledgebase]] der nächste Ort zum nachschauen. Schließlich können sie eine Frage posten in einer der [http://www.freepascal.org/maillist.html Mailing Listen] für den Free Pascal Compiler oder den [http://community.freepascal.org:10000/bboard/ FPC Foren], wo eine Menge Experten eingeschrieben sind.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates betreibt eine schnelle [http://www.tamaracka.com/search.htm Such] Engine speziell für die Borland Usenet Archive. Mer Systems Inc. bietet eine ähnliche Such [http://www.mers.com/searchsite.html Engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Erstellen eines Lazarus Package für ihre Komponente(n) ===<br />
<br />
Das Erstellen eines Packages macht die Installation ihres konvertierten Codes viel einfacher... besonders wenn sie mehr als eine Komponente anbieten. Mattias Gärtner hat eine Übersicht über [[Lazarus Packages/de|Lazarus Packages]] geschrieben, die gelesen werden sollte bevor sie mit diesem Prozess beginnen.<br />
<br />
=== Dokumentation ===<br />
<br />
Der Zweck dieser Seite und dem Wiki Format ist, die Generierung einer professionellen Dokumenation zu einem einfachen und schnellen Prozess zu machen. Das Wiki macht es auch möglich, die Resultate ihres posting unverzüglich zu sehen und erlaubt ihnen, Änderungen in Echtzeit zu machen.<br />
<br />
Die Verwendung des Lazarus-CCR Wiki um eine schön anzuschauende Dokumentation zu erstellen ist sehr einfach. Wenn sie noch nie zuvor die Wiki Sprache verwendet haben, können sie sich damit vertraut machen in dem [[Sand Box]] Übungsbereich.<br />
<br />
=== Erzeugen einer Code Release Page ===<br />
<br />
Die Code Release Page enthält grundlegende Informationen über ihre Komponente, die ein potenzieller Nutzer wird wissen wollen, wie Lizenz, vorgesehene Plattform, Status (alpha, beta, stable...), wo sie herunterzuladen ist, wer sie geschrieben hat, ob Support verfügbar ist... etc.<br />
<br />
Die folgende Prozedur läßt sie eine Code Release Seite mit ihrem Browser erzeugen: <br />
<br />
* Gehen sie zu [[Release new component]]<br />
* Tippen sie den Namen ihrer Komponente in die Textbox und klicken auf ''Create Article''<br />
* Bearbeiten sie danach die Vorlage und vergessen sie nicht zu speichern.<br />
* Bearbeiten sie die [[Components and Code examples]] Seite und fügen den Link zu ihrer gerade erzeugten Seite hinzu im "Released Components" Abschnitt. Speichern sie die geänderte Seite.<br />
<br />
=== Einreichen der Komponente ===<br />
<br />
If you're a release technician on the project, uploaden sie ihre Komponente in das SourceForge File Release System und fügen sie sie zur Liste der release Packages hinzu. Sonst senden sie es zu einem der Projektadministratoren ([[User:Tom |Tom Lisjac]] oder [[User:Vincent |Vincent Snijders]]) und wir werden es zum Repository hinzufügen. Bevor wir es zu SourceForge hochladen, müssen sie eine ''Code Release Page'' erstellen, um ihre Komponente zu beschreiben. Sie können die [[Release new component]] Seite verwenden, um mit der Erzeugung einer solchen Seite zu beginnen.<br />
<br />
Wenn sie denken, daß sie die Entwicklung der Komponente fortsetzen müssen, we can also put it into SVN so you'll continue to have access to it. If we get tired from submitting your patches, we will give you write access to the SVN, so you can commit your patches yourself. For details see [[Using the Lazarus-ccr SVN repository]].<br />
<br />
== Mitwirkende und Änderungen ==<br />
<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide Version] konvertiert.<br />
* Anfangsversion von Tom Lisjac und Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux wurde in LCLIntf umbenannt, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003<br />
* Abschnitt 'Another method to convert a Delphi or Kylix project to Lazarus' hinzugefügt , [[User:Glober | George Lober]], 2/17/2006</div>MaDhttps://wiki.freepascal.org/index.php?title=Code_Conversion_Guide/de&diff=16232Code Conversion Guide/de2007-01-19T10:27:33Z<p>MaD: /* Finden eines fehlenden Bezeichners */ mehr übersetzt</p>
<hr />
<div>{{Code Conversion Guide}}<br />
<br />
Diese Seite handelt darüber, wie man bestehenden Delphi oder Kylix Code konvertiert, um ihn mit dem [[Free Pascal/de|Free Pascal]] Compiler und der Lazarus IDE zum Laufen zu bringen. Obwohl Lazarus und der Free Pascal Compiler gemeinsame Aspekte mit Delphi und Kylix haben, sind sie keine Klone. Es gibt eine Anzahl von Bibliotheksaufrufen und Konventionsunterschieden... und in einigen Bereichen ist FPC erweitert und kann anspruchsvoller sein about correct syntax. Bitte schauen sie im [[Lazarus For Delphi Users/de|Lazarus für Delphi Benutzer]] Handbuch nach für eine Beschreibung von einigen der funktionellen Unterschiede. <br />
<br />
Der Zweck dieses Handbuchs ist es, einige der spezifischen Unterschiede zu dokumentieren, die häufig auftreten während des Codekonvertierungsprozesses, wenn existierender Code von Delphi nach Lazarus übersetzt wird.<br />
<br />
Dieses Dokument wurde im Wissensbasis Bereich des Wikis platziert, so daß es einfach erweitert werden kann von jedem, der auf ein einzigartiges Problem gestoßen ist und andere darauf aufmerksam machen möchte.<br />
<br />
== Auswahl einer Komponente oder Bibliothek für die Konvertierung ==<br />
<br />
=== Wo Code zum Konvertieren zu finden ist ===<br />
<br />
Im Internet ist eine MENGE von Code verfügbar, der konvertiert werden kann für die Verwendung mit FPC und Lazarus. Hier ist eine [[Page Of Code Sites|Seite]], die einfach ein Anfang ist. Bitte erweitern sie die Seite, wenn sie weitere Stellen kennen. TurboPower Software has recently released their entire commercial offering under the MPL. Eine Liste von verfügbaren Packages ist [http://sourceforge.net/users/tpsfadmin/ hier] zu finden.<br />
<br />
Um doppelten Aufwand zu vermeiden, sind bereits konvertierte Packages gelistet auf der [[Components and Code examples]] Seite. Wenn sie ein Package konvertiert haben oder daran arbeiten, dann fügen sie bitte eine Notiz auf der [[Current conversion projects]] Seite hinzu.<br />
<br />
=== Lizenzierung ===<br />
<br />
Lizenzen für existierenden Code reichen von Freeware/Public Domain bis zu eingeschränkten Versionen, welche Modifizierung, Weiterverteilung und kommerzielle Verwendung verbieten. Bevor sie irgendein Package konvertieren, ist es eine gute Idee, seine Lizenz zu überprüfen und sicherzustellen, daß sie kompatibel wird mit Lazarus und dem Free Pascal Compiler. Lizenzauswahl ist besonders wichtig bei Komponenten, seit das Ablegen auf einem Formular eine nicht gewollte oder inkompatible Lizenz für die gesamte Anwendung aufbürden kann.<br />
<br />
Wenn sie Komponenten konvertieren, respektieren sie bitte die Wünsche des Originalautors und belassen alle Copyright- und Lizenz-Header mit Email-Adressen und URl's. Es gehört zum guten Ton und ist oft hilfreich, um den Autor zu informieren, daß seine Komponente konvertiert wurde... besonders wenn sich die Komponente unter einer restriktiven Lizenz befindet. Neues Interesse an einer alten oder vergessenen Komponente kann manchmal die Autoren inspirieren, um ihr Original und die allzu restriktive Lizenzierung zu überarbeiten.<br />
<br />
Im Allgemeinen sind Public Domain (Freeware) und die LGPL/MPL Komponenten die flexibelsten zum Vertreiben. Für mehr Information ist die [http://www.opensource.org/docs/definition.php Open Source Definition] ein guter Platz zum starten. Dort gibt es auch verschiedene Vergleiche to help clarify how the various types of licenses work and what impact they'll have on code they're linked to. Suchen sie nach "open source license comparison"<br />
<br />
=== Abhängigkeiten ===<br />
<br />
Ein anderer Schritt bevor sie an einer Konvertierung arbeiten ist, daß sie überprüfen, daß der Code keine verborgenen Abhängigkeiten von anderen Packages enthält, die nicht verfügbar sein können oder einen beträchtlichen Konvertierungsaufwand darstellen. Einige Freeware Angebote sind gebunden an oder erweitern proprietäre Packages, die häufig nicht länger erhältlich sind oder mit ungeeigneten Lizenzen kommen.<br />
<br />
=== Compiler Probleme ===<br />
<br />
Siehe:<br />
* [http://www.freepascal.org/probs.html bekannte Probleme]<br />
* [http://www.freepascal.org/bugs/db.php3?statusfield=Unfixed Nichtbereinigte Bugs]<br />
<br />
=== Plattform und OS Probleme ===<br />
<br />
Lazarus und der Free Pascal Compiler sind [[Glossary#CrossPlatform|cross-platform]] und cross-architecture Entwicklungswerkzeuge. Im Gegensatz wurde der meiste existierende Delphi Code speziell vorgesehen, auf einem Intel Prozessor unter Win32 zu laufen. Wenn ihr Kandidat eine Menge von Win32 spezifischem Code hat, mag es weise sein, nach einer weniger plattformabhängigen Alternative zu suchen. Aber lassen sie sich davon nicht entmutigen. Es ist erstaunlich, was die LCL unterstützt!<br />
<br />
== Durchführen der Konvertierung ==<br />
<br />
=== Einrichten der Lazarus Umgebung für ein Konvertierungs-Projekt ===<br />
<br />
==== Erstellen eines Testprojekts ====<br />
* Platzieren sie den zu konvertierenden Code in ein Unterverzeichnis (z.B.: convertdir)<br />
* Holen sie Lazarus hervor<br />
* Datei -> Alles speichern in das convertdir Unterverzeichnis. Aussagekräftige Namen für Projekt und Units sind optional.<br />
* Öffnen sie die zu konvertierende "main" Unit in convertdir<br />
* Fügen sie sie zum Projekt hinzu: Projekt -> Datei im Editor ins Projekt aufnehmen<br />
* Starten sie Werkzeuge -> Schnelle Syntaxüberprüfung oder Start -> Alles neu erstellen um loszulegen.<br />
<br />
==== Initial items to watch out for ====<br />
* Dateinamen sind case sensitive with the 1.0.x series compilers. Wenn sie mit dieser Version arbeiten, schreiben sie alle Dateinamen klein. Sie werden "File not found" Fehler bekommen, wenn sie es nicht tun.<br />
<br />
==== Delphi VCL, Kylix CLX Quellen in Lazarus ====<br />
<br />
Während der Konvertierung von Delphi/Kylix Quellen ist es oft hilfreich, eine find declaration zu machen um zu sehen, was eine bestimmte Funktion macht. Die Lazarus IDE kann die Delphi/Kylix Quellen analysieren. Um dies zu tun werden einige Suchpfade und Compilereinstellungen benötigt. Sie können dies einfach einrichten unter<br />
<br />
Einstellungen -> CodeTools Defines Editor -> Vorlage einfügen<br />
<br />
=== Konvertierungsprobleme und Lösungen ===<br />
<br />
==== Delphi / Kylix Datei-Entsprechungen in Lazarus ====<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi / Kylix || class="header" | Lazarus || class="header" | Beschreibung<br />
|- class="code"<br />
| class="code" |.pas<br />
.dfm / .xfm<br />
.dcu / .dpu<br />
.dpr (main project file)<br />
.res<br />
.dof / .kof<br />
---<br />
---<br />
---<br />
| class="code" |.pas, .pp<br />
.lfm<br />
.o<br />
.lpr<br />
---<br />
---<br />
.lrs<br />
.lpi (main project file)<br />
.ppu<br />
| class="code" |Pascal Unit Datei<br />
Formulardaten Datei<br />
Compilierte Unit Datei<br />
Projektdatei<br />
Ressourcendatei<br />
Projektoptionen Datei<br />
Lazarus Ressourcen Datei<br />
Lazarus Projekt Informations Datei<br />
FPC Unit Beschreibungsdatei<br />
|}<br />
<br />
==== Konvertierung von Delphi Projekten/Formularen/Units nach Lazarus ====<br />
<br />
Benennen sie die .dpr Datei in eine .lpr Datei um. Kommentieren sie die <div class="dir">{$R *.res}</div> Direktive aus oder entfernen sie und fügen eine <div class="dir">{$mode delphi}{$H+}</div> oder <div class="dir">{$mode objfpc}{$H+}</div> Direktive zur .lpr Datei hinzu. Die Lazarus IDE can assist in this conversion through the Tools menu item "Convert Delphi Project to Lazarus Project". Sie fragt nach einer .dpr (Delphi Project) Datei und konvertiert sie in eine .lpr; außerdem erzeugt sie die .lpi Datei und konvertiert alle Units.<br />
<br />
Viele existierende Delphi Formulare können konvertiert werden um mit Lazarus zu funktionieren durch Verwendung des in die IDE eingebauten .dfm to .lfm form Umwandlers. Er ist zu finden im Werkzeuge Menü als "Convert DFM file to LFM". Bring up the file dialog, wählen sie die dfm Datei und der Umwandler wird den Rest erledigen.<br />
<br />
Wenn sie die ganze Unit konvertieren müssen (mit oder ohne ein Formular), enhält Lazarus auch ein eingebautes "Convert Delphi unit to Lazarus unit", welches das folgende für sie erledigt -<br />
<br />
# fixes the case of include filenames and uses sections.<br />
# konvertiert die .dfm Datei in eine .lfm Datei (gegenwärtig ohne Inhaltsprüfung, nur Formatierung)<br />
# erzeugt eine leere .lrs Datei (der Inhalt wird später erzeugt)<br />
# fügt die <div class="dir">{$mode delphi}</div> Direktive hinzu<br />
# ersetzt die windows Unit durch LCLIntf<br />
# adds LResources unit if needed (i.e., if unit.lrs is to be used; <div class="dir">uses LResources </div> can be in the implementation part)<br />
# entfernt die variants Unit<br />
# entfernt die <div class="dir">{$R *.dfm}</div> Direktive<br />
# fügt den initialization Abschnitt und die <div class="dir">{$i unit.lrs}</div> Direktive hinzu<br />
<br />
==== Auswahl des richtigen Compilermodus ====<br />
<br />
Der [[Free Pascal/de|Free Pascal]] Compiler unterstützt 5 unterschiedliche Pascal Modi. Zum Beispiel TP für Turbo Pascal, lässt sie Turbo Pascal Units kompilieren. Es gibt auch einen DELPHI Kompatibilitäts-Modus, der gesetzt werden kann, um bestehenden Code einfacher zu konvertieren. Lazarus bevorzugt den OBJFPC Modus, welcher fast dem DELPHI Modus gleicht, aber weniger mehrdeutig als die Delphi Syntax ist. Hier sind die wichtigen Punkte:<br />
<br />
Der Modus kann auf der Befehlszeile oder beim Start der Quelle gewählt werden. Die Verwendung der Befehlszeile hat den Vorteil, daß sie die Quelle nicht ändern müssen, aber den Nachteil, daß anderes erzählt werden muß.<br />
<br />
Die meisten Delphi Units können mit dem [[Free Pascal/de|Free Pascal]] Compiler kompiliert werden durch hinzufügen von <br />
{$IFDEF FPC}<br />
{$MODE DELPHI}<br />
{$ENDIF}<br />
gleich nach dem Unit Namen.<br />
<br />
Für mehr Details über die [[Free Pascal/de|Free Pascal]] Modi siehe die [http://www.freepascal.org/docs-html/prog/progap4.html#progse62.html Free Pascal Dokumentation].<br />
<br />
==== Cross-Plattform Überlegungen ====<br />
<br />
* Inline Assembler ist immer ein Problem, weil er den Code an die Intel Architektur bindet. Some developers do algorithm prototypes in Pascal and ifdef the their optimized assembler. Fortunately TurboPower did this in numerous places with their code. If this is the case with the package you're converting, throw the switch back to Pascal.<br />
* Don't reference specific memory location like the BIOS data area. Find out what the code needs and try to find a cross platform alternative.<br />
* Don't do processor specific tricks (like using the Intel TSC) without enclosing your code in an ifdef for the platform the code needs... and providing an alternative for environments that don't have the hardware capability.<br />
* Wenn sie Betriebssystem-spezifischen Code benötigen, dann können sie IFDEFs verwenden. Siehe unten für eine Liste der Makros.<br />
<br />
==== Hilfreiche Compiler Variablen ====<br />
<br />
Um Code zu schreiben, der sich auf verschiedenen Systemen unterschiedlich verhält, können sie die <div class="dir">{$IFDEF Name}</div> Anweisungen verwenden.<br />
<br />
* <div class="dir">{$IfDef LCL}</div><br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird. Hilfreich um Code zu schreiben, der mit der LCL und Delphi funktioniert.<br />
* <div class="dir">{$IfDef LCLGtk}</div>, <div class="dir">{$IfDef LCLWin32}</div>, <div class="dir">{$IfDef LCLQt}</div>, ...<br />
Diese Variable ist definiert, wenn das LCL Package verwendet wird und das spezifische widgetset is currently used. Hilfreich um Code zu schreiben, der mit der LCL auf einer spezifischen Plattform funktioniert.<br />
* <div class="dir">{$IfDef FPC}</div><br />
Diese Variable ist definiert, wenn der FPC Compiler verwendet wird. Hilfreich um Code zu schreiben, der mit FPC und Delphi funktioniert.<br />
* <div class="dir">{$IfDef Unix}</div>, <div class="dir">{$IfDef Win32}</div>, ...<br />
Von FPC für das aktuelle Ziel OS definiert. Delphi definiert "Linux", "Win32" und "MSWindows". [[Free Pascal/de|Free Pascal]] läuft auf viel mehr Plattformen und daher wird empfohlen, allgemeinere Begriffe zu verwenden. Zum Beispiel ist "Unix" definiert für Linux, FreeBSD, NetBSD und OpenBSD, wo Lazarus bereits läuft.<br />
Verwenden sie<br />
{$IfDef Linux}<br />
{$Define Unix}<br />
{$EndIf}<br />
to work around this for Kylix.<br />
<br />
Für mehr Details siehe die [http://www.freepascal.org/docs-html/prog/prog.html#QQ2-23-21 Free Pascal Dokumentation].<br />
<br />
==== Finden eines fehlenden Bezeichners ====<br />
<br />
Es gibt Unterschiede darin, wie die LCL organisiert ist im Vergleich zur Delphi VCL. Wenn sie einen "not found" Compilerfehler erhalten über eine wichtige Klasse oder Bezeichner, stehen die Chancen gut, daß Sie die Klasse oder den Bezeichner in einer anderen Unit finden könne. Eine komplette Cross-Reference können Sie finden, indem Sie grep auf das Verzeichnis lazarus/docs/xml oder das Unterverezeichnis lcl anwenden.<br />
<br />
Zum Beispiel erzeugt der häufig verwendete TButton üblicherweise einen Fehler im Delphi Code, weil er sich in der Unit buttons.pp befindet. Das folgende Kommando findet die richtige Unit sehr schnell (im Lazarus Quellenverzeichnis):<br />
<br />
grep -in ' tbutton =' lcl/*<br />
<br />
==== Wichtige Unit Unterschiede zwischen Lazarus und Delphi ====<br />
<br />
'''Bitte ergänzen sie diesen Abschnitt!'''<br />
<br />
* Windows->Interfaces, LCLIntf, LCLType, LCLProc, VCLGlobals, ...)<br />
<br />
Die die LCL nicht Windows-spezifisch ist, ist der Code, der sich in der Delphi Windows Unit für den direkten Zugriff auf das Win32 API befindet, abstrahiert in separate Schnittstellen, auf welche Zugriff besteht mit der LCLIntf Unit. Beachten sie, daß Lazarus nicht win32 emuliert, so daß mehrere Funktionen fehlen und einige nicht wie ihre win32 Gegenstücke funktionieren. Diese Funktionen existieren nur für die Delphi Kompatibilität und sollten nur be used for quick & dirty porting. LCL also breaks out many of the types, so often LCLType, and sometimes VCLGlobals are required. LCLProc enthält auch ein paar Funktionen, die hilfreich sein können für lower level handling such as "FreeThenNil" as is in Delphi 5 und höher, "DeleteAmpersands" to remove additional ampersands from a string for controls(& vs && etc). Die Interfaces Unit muß in der .lpr Datei enthalten sein um das passende widgetset zu initialisieren.<br />
<br />
* Messages->LMessages<br />
<br />
TControl Messages for win32 event callbacks of the format WM_CALLBACK and the structs associated with them are often found in the Messages unit in Delphi. In the LCL these types of messages and there structs are usually found in LMessages, üblicherweise mit einer Namensänderung von WM zu LM, zum Beispiel WM_MOUSEENTER wird LM_MOUSEENTER, und TWMMouse wird TLMMouse.<br />
<br />
* Graphics, Controls->GraphTypes, GraphMath, Graphics, Controls<br />
<br />
To simplify some things and break complexity of circles between units, a few types have been abstracted into a shared unit called GraphType, which includes things, which in Delphi are located in Graphics or Controls, for instance the bvNone etc of panels. So sometimes you have to include it. Also a unit which, although incompatible with Delphi, adds other useful functionality is GraphMath, which adds a TFloatPoint for precision, misc routines for dealing with beziers, lines, and arcs, as well as some operator overloading for use with TPoints and TRect, such as for instance Point1 := Point2 + Point3, and comparing two rects like if (rect1 = rect2) then ...<br />
<br />
* Mask->MaskEdit<br />
<br />
For more intelligent naming considerations, the unit for TMaskEdit is called [MaskEdit|] instead of the slightly more nebulous Mask wie in vielen Delphi Versionen.<br />
<br />
* StdCtrls->StdCtrls,Buttons<br />
<br />
In vielen Delphi Versionen befindet sich TButton in StdCtrls, während TSpeedButton und TBitBtn sich in Buttons befinden. Für eine Stetigkeit und Einfachheit steckt die LCL alle Buttontypen in Buttons, which can occasionally break code conversion, so it is always a good idea to include.<br />
<br />
==== Eigenschaften und Methoden Unterschiede Delphi -> FPC/LCL ====<br />
* TBitmap contains a canvas in the LCL<br />
==== Syntax Unterschiede ====<br />
<br />
'''Bitte fügen sie weitere Informationen zu diesem Thema hinzu!'''<br />
<br />
Because of the inherent strictness in FPC, some syntax changes are necessary, even though <div class="dir">{$Mode Delphi}</div> does allow more laziness like Delphi does. For this reason complying as much with the syntax rules of <div class="dir">{$Mode ObjFPC}</div> as possible is highly recommended, even when the codebase is still going to be shared between Delphi and the LCL. Some of these are simply better coding practices, and sometimes because Delphi mode is not entirely accurate, or in a few instances Delphi acceptible code does not function as expected with FPC, even though it might compile. To that end even though not all such are strictly required, the following list of changes should be considered mandatory :<br />
<br />
<br />
===== When assigning an event handling entry point, prefix it with an "@" =====<br />
<br />
For instance, you might assign a button callback manually <br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">begin</div> <br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= SomeFunction; <div class="cmt">//@ wird nicht benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">begin</div><br />
<div class="key">if not</div> Assigned(MyButton.OnClick) <div class="key">then</div><br />
MyButton.OnClick:= @SomeFunction; <div class="cmt">//@ wird benötigt</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== Wenn sie eine Prozedurenvariable aufrufen verwenden sie diese Syntax: theprocname() =====<br />
<br />
In Delphi gibt es keinen Unterschied zwischen dem Ergebnis einer Funktion und einer Variablen, jedoch in FPC gibt es einen, so um eine Funktion aufzurufen, selbst wenn sie keine Parameter hat, müssen sie eine runde Klammer anhängen. Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div> <br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div> <br />
OnMyCallback; <div class="cmt">//runde Klammer nicht benötigt</div> <br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">With</div> (SomeObject) <div class="key">do begin</div><br />
<div class="key">If</div> Assigned(OnMyCallback) <div class="key">then</div><br />
OnMyCallback(); <div class="cmt">//runde Klammer benötigt</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
===== When accessing values in a pointer to a record you must dereference first =====<br />
<br />
In Delphi it is not required to de-reference a pointer to a record to access values within it, it can, in fact, be treated just like the record itself, or any other object. In FPC it must be first de-referenced. As an example,<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Function</div> GetSomeValue(ARecord: PMyRecord) <br />
<div class="symbol">:</div> Integer;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Assigned(ARecord) <div class="key">then</div><br />
Result<div class="symbol">:=</div> ARecord^.SomeValue<br />
<div class="key">else</div><br />
Result:= <div class="int">0</div>;<br />
<div class="key">end</div>; <br />
|}<br />
<br />
===== When accessing chars of an indexed string Property of an object, it must be enclosed in parentheses =====<br />
<br />
With Delphi it is possible to treat a Property exactly like some other const or var, even to accessing for instance individual chars of a string directly, while this is not always possible in FPC, specifically for indexed properties. Instead it must be enclosed in parentheses, to make distinct. While this may not always hold true it is probably a good practice to consider anyway. For example<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//no parenthesis needed</div><br />
MyChar:= MyString[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
| class="code" | <div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
<div class="key">Property</div> MyString: <div class="key">String</div> <div class="key">index</div> <div class="int">3</div><br />
<div class="key">read</div> GetMyString;<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">var</div><br />
MyChar<div class="symbol">:</div> char;<br />
<div class="key">begin</div><br />
<div class="key">If</div> Length(MyString)> <div class="int">2</div> <div class="key">then</div><br />
<div class="cmt">//parenthesis sometimes needed</div><br />
MyChar:= (MyString)[<div class="int">3</div>];<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
<br />
===== You must typecast pointers to actual type when using with var or function of that type =====<br />
<br />
In Delphi haben sie manchmal eine null pointer variable representing an object. While it might seem a complex situation, it is oddly quite common especially in large component packs as a method of preventing too many circular includes between objects in different units. In Delphi it is then possible to send this null pointer to a function expecting that object, without bothering to typecast to actual type, in fpc you must typecast. <br />
<br />
Zum Beispiel -<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi || class="header" | FPC<br />
|- class="code"<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div><br />
<div class="symbol">Application</div><br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> GetSomeObject;<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(MyComponent.SomeObject)<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
| class="code" |Unit 1<br />
<div class="key">Type</div> TSomeObject= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="key">Procedure</div> DoSomething(Value: TSomeObject);<br />
<div class="key">Function</div> GetSomeObject: TSomeObject;<br />
<div></div> <br />
<div class="symbol">Unit 2</div><br />
<div class="key">Type</div> TSomeComponent= <div class="key">class</div>(TComponent)<br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">Published</div><br />
SomeObject: Pointer<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">End</div>;<br />
<div></div> <br />
<div class="symbol">Application</div> <br />
<div class="key">var</div><br />
MyComponent: TSomeComponent<div class="symbol">;</div><br />
<div class="key">begin</div><br />
MyComponent.SomeObject<div class="symbol">:=</div> Pointer(GetSomeObject);<br />
<div class="cmt">//weiterer Code...</div><br />
DoSomething(TSomeObject(MyComponent.SomeObject))<div class="symbol">;</div><br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Ressourcen ====<br />
<br />
Delphi Ressourcendateien sind Win32 spezifisch und nicht kompatibel mit Lazarus, so daß sie sie neu erstellen und mit Lazres kompilieren müssen. Lazres ist im lazarus/tools Unterverzeichnis zu finden. Wenn sie die Lazarus Quellen heruntergeladen haben, müssen sie es erst kompilieren.<br />
* cd lazarus/tools<br />
* make install<br />
Um eine Ressource zu ihrer Anwendung hinzuzufügen:<br />
* lazres myresource.lrs mypix.xpm anotherpix.xpm<br />
* Fügen sie die LResources Unit zu ihrem Uses Abschnitt hinzu<br />
* Nehmen sie die von ihnen erstellte .lrs Datei unter dem initialization Abschnitt auf<br />
Beispiel:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> TForm1.LoadGlyph(<div class="key">const</div> GlyphName: <div class="key">String</div>): TBitMap;<br />
<div class="key">begin</div><br />
Result:= TPixmap.Create<div class="symbol">;</div><br />
Result.LoadFromLazarusResource(GlyphName)<div class="symbol">;</div><br />
<div class="key">end</div>; <br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">begin</div><br />
Speedbutton1.glyph:= LoadGlyph('mypix')<div class="symbol">;</div><br />
<div class="cmt">//weiterer Code...</div><br />
<div class="key">end</div>;<br />
<div></div> <br />
<div class="key">initialization</div><br />
<div class="dir">{$I unit1.lrs}</div><br />
<div class="dir">{$I myresource.lrs}</div><br />
<div class="key">end</div>.<br />
|}<br />
<br />
=== Eine andere Methode um ein Delphi oder Kylix Projekt nach Lazarus zu konvertieren ===<br />
<br />
* Benennen sie alle .dfm oder .xfm Dateien in .lfm um. (Dies funktioniert nicht mit frühen Delphi Versionen da sie keine textbasierte .dfm Datei erstellen.)<br />
* Benennen sie die .dpr Datei in .lpr um.<br />
* Nehmen sie notwendige Änderungen in der .lpr Datei vor:<br />
# Fügen sie {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'Interfaces' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.res} Direktive aus oder löschen sie diese.<br />
* Nehmen sie notwendige Änderungen in allen .pas Unit Dateien vor:<br />
# Fügen sie die {$mode delphi}{$H+} oder {$mode objfpc}{H+} Direktiven hinzu.<br />
# Fügen sie 'LResources', und wenn das Formular Buttons hat, 'Buttons' zum uses Abschnitt hinzu.<br />
# Kommentieren sie die {$R *.dfm} oder {$R *.xfm} Direktive aus oder löschen sie diese.<br />
# Fügen sie einen 'Initialization' Abschnitt am Ende jeder Datei hinzu, und fügen die {$I unitname.lrs} Direktive darin hinzu.<br />
* Wählen sie Projekt -> Neues Projekt von Datei<br />
* Wählen sie die .lpr Datei<br />
* Im 'Erzeuge neues Projekt' Fenster wählen sie 'Anwendung'<br />
* Erzeugen sie das Projekt und nehmen sie weitere notwendige Korrekturen vor um eine ordentliche Kompilierung zu erhalten, an diesem Punkt wird die .lpi Datei automatisch generiert. Sie erhalten vielleicht 'Error reading Form' Meldungen. Klicken sie auf 'Continue Loading' falls dem so ist. <br />
* Speichern sie alles und sie haben ein Lazarus Projekt :-)<br />
<br />
== Hilfe erhalten ==<br />
<br />
Wenn sie während der Konvertierung auf ein Problem stoßen, das sie gerade nicht lösen können, gibt es eine große Auswahl von Orten, um Hilfe zu erhalten. Für reine Object Pascal und FPC Probleme, ist der beste Ort zu beginnen die Free Pascal [http://www.freepascal.org/docs-html/ Dokumentation] von Michaël Van Canneyt und Florian Klämpfl. Für mehr Lazarus orientierte Probleme ist die Lazarus Projekt Dokumentation in der [[Main Page/de|Lazarus-CCR Knowledgebase]] der nächste Ort zum nachschauen. Schließlich können sie eine Frage posten in einer der [http://www.freepascal.org/maillist.html Mailing Listen] für den Free Pascal Compiler oder den [http://community.freepascal.org:10000/bboard/ FPC Foren], wo eine Menge Experten eingeschrieben sind.<br />
<br />
There are some outstanding search and knowledge bases online that can also be a great help for learning new techniques and solving problems. Tamarack Associates betreibt eine schnelle [http://www.tamaracka.com/search.htm Such] Engine speziell für die Borland Usenet Archive. Mer Systems Inc. bietet eine ähnliche Such [http://www.mers.com/searchsite.html Engine]. Another outstanding source of information along with a sitewide [http://www.efg2.com/Lab/search.htm search] capability is Earl F. Glynn's Computer Lab and Reference [http://www.efg2.com/ Library].<br />
<br />
== Packaging and Releasing your component ==<br />
<br />
=== Erstellen eines Lazarus Package für ihre Komponente(n) ===<br />
<br />
Das Erstellen eines Packages macht die Installation ihres konvertierten Codes viel einfacher... besonders wenn sie mehr als eine Komponente anbieten. Mattias Gärtner hat eine Übersicht über [[Lazarus Packages/de|Lazarus Packages]] geschrieben, die gelesen werden sollte bevor sie mit diesem Prozess beginnen.<br />
<br />
=== Dokumentation ===<br />
<br />
Der Zweck dieser Seite und dem Wiki Format ist, die Generierung einer professionellen Dokumenation zu einem einfachen und schnellen Prozess zu machen. Das Wiki macht es auch möglich, die Resultate ihres posting unverzüglich zu sehen und erlaubt ihnen, Änderungen in Echtzeit zu machen.<br />
<br />
Die Verwendung des Lazarus-CCR Wiki um eine schön anzuschauende Dokumentation zu erstellen ist sehr einfach. Wenn sie noch nie zuvor die Wiki Sprache verwendet haben, können sie sich damit vertraut machen in dem [[Sand Box]] Übungsbereich.<br />
<br />
=== Erzeugen einer Code Release Page ===<br />
<br />
Die Code Release Page enthält grundlegende Informationen über ihre Komponente, die ein potenzieller Nutzer wird wissen wollen, wie Lizenz, vorgesehene Plattform, Status (alpha, beta, stable...), wo sie herunterzuladen ist, wer sie geschrieben hat, ob Support verfügbar ist... etc.<br />
<br />
Die folgende Prozedur läßt sie eine Code Release Seite mit ihrem Browser erzeugen: <br />
<br />
* Gehen sie zu [[Release new component]]<br />
* Tippen sie den Namen ihrer Komponente in die Textbox und klicken auf ''Create Article''<br />
* Bearbeiten sie danach die Vorlage und vergessen sie nicht zu speichern.<br />
* Bearbeiten sie die [[Components and Code examples]] Seite und fügen den Link zu ihrer gerade erzeugten Seite hinzu im "Released Components" Abschnitt. Speichern sie die geänderte Seite.<br />
<br />
=== Einreichen der Komponente ===<br />
<br />
If you're a release technician on the project, uploaden sie ihre Komponente in das SourceForge File Release System und fügen sie sie zur Liste der release Packages hinzu. Sonst senden sie es zu einem der Projektadministratoren ([[User:Tom |Tom Lisjac]] oder [[User:Vincent |Vincent Snijders]]) und wir werden es zum Repository hinzufügen. Bevor wir es zu SourceForge hochladen, müssen sie eine ''Code Release Page'' erstellen, um ihre Komponente zu beschreiben. Sie können die [[Release new component]] Seite verwenden, um mit der Erzeugung einer solchen Seite zu beginnen.<br />
<br />
Wenn sie denken, daß sie die Entwicklung der Komponente fortsetzen müssen, we can also put it into SVN so you'll continue to have access to it. If we get tired from submitting your patches, we will give you write access to the SVN, so you can commit your patches yourself. For details see [[Using the Lazarus-ccr SVN repository]].<br />
<br />
== Mitwirkende und Änderungen ==<br />
<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=CodeConversionGuide Version] konvertiert.<br />
* Anfangsversion von Tom Lisjac und Mattias Gärtner - 9/22/2003 [[User:Tom | VlxAdmin]]<br />
* Moved Getting help from the main page. T. Lisjac - 9/24/2003 [[User:Tom | VlxAdmin]]<br />
* Added documentation templates, procedure and links. 9/25/2003 [[User:Tom | VlxAdmin]]<br />
* LCLLinux wurde in LCLIntf umbenannt, [[User:Jesusrmx | Jesus Reyes]], 9/27/2003<br />
* added more information on Unit changes, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Updated Syntax differences, including some examples, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* FPC 1.0.x doesn't support interfaces, [[User:Vincent | Vincent Snijders]] 9/28/2003<br />
* Fixed some of the examples per new WikiWord definition, 9/28/2003 [[User:Tom | VlxAdmin]]<br />
* Made code more consistant to remove last accidental Pascal WikiWord definitions, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 9/27/2003<br />
* Use tables for code examples for nice blocks, and easy side by side view of Delphi->FPC differences, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/17/2003<br />
* Use pascal stylesheet to make example code more readable, [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson AndrewJohnson] 10/18/2003<br />
* Abschnitt 'Another method to convert a Delphi or Kylix project to Lazarus' hinzugefügt , [[User:Glober | George Lober]], 2/17/2006</div>MaDhttps://wiki.freepascal.org/index.php?title=Lazarus_For_Delphi_Users/de&diff=16231Lazarus For Delphi Users/de2007-01-19T08:40:40Z<p>MaD: /* TEdit/TCustomEdit */</p>
<hr />
<div>{{Lazarus For Delphi Users}}<br />
<br />
Diese Zuschreibung ist für Leute gedacht, die an Lazarus interessiert sind und Delphi bereits kennen. Sie beschreibt die Unterschiede zwischen den beiden.<br />
<br />
== Delphi -> Lazarus ==<br />
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 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 />
<br />
=== Die größten Unterschiede ===<br />
Lazarus ist komplett Open Source, ist Plattform unabhä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 daß Lazarus gegenwärtig unter Linux, Free/Open/NetBSD, MacOSX und Win32 läuft.<br />
<br />
''' Lazarus ist nicht komplett, wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... . '''<br />
<br />
== Delphi IDE -> Lazarus IDE ==<br />
=== Projekte ===<br />
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 ist die .lpi Datei die wichtige Datei.<br />
<br />
Eine wichtige Regel: Es gibt ''immer'' ein Projekt. <br />
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 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.<br />
<br />
=== Quelltext Editor ===<br />
Beinahe alle Tasten und Abkürzungen (short cuts) können definiert werden unter Einstellungen -> Editoreinstellungen -> Tastaturbelegung.<br />
<br />
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:<br />
<br />
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 reisen ihre Kommentare. Unter Lazarus können sie eine find declaration sogar für Code in den Kommentaren 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 Kommentaren und Code zusammen zu halten. Zum Beispiel: Es wird die Zeile "c: char; // comment" nicht aufteilen.<br />
<br />
Delphi's "Code Completion" (Ctrl+Space) wird "Identifier Completion" genannt unter Lazarus. Der Lazarus Begriff "Codevervollständigung" ist ein Werkzeug, welches "Automatic Class Completion" (das gleiche wie unter Delphi), "Local Variable Completion" und "Event Assignment Completion" kombiniert. Alle von ihnen werden aufgerufen mit Ctrl+Shift+C und die IDE ermittelt über die Cursor Position, was gemeint ist.<br />
<br />
==== Beispiel für Local Variable Completion ====<br />
Gehen sie davon aus, daß sie gerade eine neue Methode erzeugt haben und die Anweisung schreiben "i:=3;"<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;<br />
<div class="key">begin</div><br />
i:= <div class="int" style="inline">3</div>;<br />
<div class="key">end</div>;<br />
|}<br />
<br />
Positionieren sie den Cursor über den Bezeichner "i" und drücken sie Ctrl+Shift+C und sie erhalten:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;<br />
<div class="key">var</div> i: Integer;<br />
<div class="key">begin</div><br />
i:= <div class="int">3</div>;<br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Beispiel für Event Assignment Completion ====<br />
Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können sie im Quelltext Editor erhalten.<br><br />
Zum Beispiel:<br />
: Button1.OnClick:=<br />
Positionieren sie den Cursor hinter den assign operator ":=" und drücken sie Ctrl+Shift+C.<br />
<br />
==== "Word Completion" Ctrl+W ====<br />
Es arbeitet ähnlich wie die "Identifier Completion", aber es funktioniert nicht nur mit Pascal Bezeichnern, sondern mit allen Wörtern. Es läßt sie alle Wörter in allen geöffneten Dateien wählen, die mit dem selben Buchstaben beginnen.<br />
<br />
==== Unterstützt Include Dateien ====<br />
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 unübersichtlich zu machen.<br />
Zum Beispiel: Method jumping, Class Completion, find declaration, .. arbeiten alle mit Include Dateien.<br />
<br />
Es gibt viele Optionen für die Code Features.<br />
<br />
=== Designer ===<br />
- Richtlinien<br />
==== Objektinspektor ====<br />
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 zur Beachtung für den Gebrauch :<br />
# Nach dem starten von Delphi gibt es ein Objekt-Treeview, welches zum navigieren und auswählen von Objecten unter Darstellung deren Hierarchie genutzt werden kann und so wahlweise die Dropdown-Liste des Objektinspektors ersetzt. In Lazarus ist dieses Treeview fester Bestandteil des Objektinspectors und es ersetzt die Dropdown-Liste völlig. Die Anzeige kann über das Kontextmenü "Komponentenbaum anzeigen" aktiviert bzw. deaktiviert werden.<br />
# 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 eine Schaltfläche auf der rechten Seite der ausgewählten drop-down, welche diese Aktion ebenfalls ausführt.<br />
# 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 Dropdown "none" auswählen.<br />
# Ähnlich wie bei Ereignissen, wird doppeltes Klicken normaler Eigenschaften wie boolean nicht den Wert ändern, sie müssen ihn aus einem drop down wählen. Und um diese zu öffnen mit einem zugeordneten Editorformular, müssen sie auf den '...' Button rechts vom edit/drop-down klicken.<br />
<br />
==== Packages ====<br />
Kann Lazarus Delphi-Packages installieren und verwenden?<br />
<br />
Nein, weil sie die Delphi Compiler Magie benötigen.<br />
<br />
Brauchen wir ein speziell für Lazarus erstelltes?<br />
<br />
Ja.<br />
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.<br />
Sie können es installieren, oder es jetzt in ihren Projekten verwenden. <br />
Es gibt einige Unterschiede zwischen Lazarus und Delphi Packages, daher lesen sie bitte <br />
<br />
- die docs/Packages.txt in den Lazarus Quellen.<br />
<br />
=== VCL -> LCL ===<br />
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 beinhaltet, 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 werden, welche in [[Free Pascal/de|Free Pascal]] enthalten ist.<br />
<br />
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 echten Klone. Änderungen müssen gemacht werden in Anwendungen, Komponenten und Bedienelementen wenn sie portiert werden.<br />
<br />
Das Folgende ist unvolständige Beschreibung der wichtigsten Unterschiede oder Inkompatibilitäten zwischen Delphi und Lazarus für Delphi-Benutzer zu liefern. 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 CVS 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 auffalen, dann bitten wir sie den vorliegenden Text entsprechend zu modifizieren oder neu Abschnitte anzufügen. Wir möchten diese Beschreibung so umfassend und aktuell wie möglich für alle Lazarus-User zur Verfügung stellen.<br />
<br />
==== TControl.Font/TControl.ParentFont ====<br />
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, welche sicherstellt, daß ein Bedienelement immer seiner parent's Schriftart folgt.<br />
<br />
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 spezifische Schriftarten für Schaltflächen des GTK Widget-Toolset benutzen. <br />
<br />
Das bedeutet, daß die meisten LCL Bedienelemente dem Desktop-Desing des Zielrechners entsprechen werden. Das look and feel ihrer Progammoberfläche kann sich also auf verschiedenen Zielrechnern auch entsprechend der Desktop-Einstellungen ändern.<br />
<br />
Wenn beispielsweise ein Label mit einer fetten/spezialfarbigen Schriftart benötigt wird, muß stattdessen ein TStaticText benutzt werden, da TLabel ein Interface spezifisches Bedienelement ist und alle Interfaces eine native Version bereitstellen werden, und die meisten werden Voreinstellungen haben, welche trotzdem benutzt werden.<br />
<br />
==== Bedienelemente ziehen und andocken ====<br />
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. <br />
<br />
Diese Funktionalität ist noch nicht implementiert/beendet in der LCL. 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 der exakt selben Art und Weise. <br />
<br />
Das bedeutet derzeit, daß kein Bedienelement die folgenden TControl Funktionen, Prozeduren, Eigenschaften oder Ereignisse erben/benutzen wird -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">Protected</div><br />
<div class="key">function</div> GetDockEdge(MousePos: TPoint): TAlign;<br />
<div class="key">function</div> GetDragImages: TDragImageList;<br />
<div class="key">function</div> GetFloating: Boolean;<br />
<div class="key">function</div> GetFloatingDockSiteClass: TWinControlClass;<br />
<div class="key">procedure</div> DoEndDrag(Target:TObject); X, Y: Integer);<br />
<div class="key">procedure</div> DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoEndDock(Target: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoDock(NewDockSite: TWinControl; <div class="key">var</div> ARect: TRect);<br />
<div class="key">procedure</div> DoStartDock(<div class="key">var</div> DragObject: TDragObject);<br />
<div class="key">procedure</div> DragCanceled;<br />
<div class="key">procedure</div> DragOver(Source: TObject; X, Y: Integer; State: TDragState;<br />
<div class="key">var</div> Accept: Boolean);<br />
<div class="key">procedure</div> DoEndDrag(Target: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoStartDrag(<div class="key">var</div> DragObject: TDragObject);<br />
<div class="key">procedure</div> DrawDragDockImage(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> EraseDragDockImage(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> PositionDockRect(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> SetDragMode(Value: TDragMode);<br />
<div class="key">property</div> DragKind: TDragKind;<br />
<div class="key">property</div> DragCursor: TCursor;<br />
<div class="key">property</div> DragMode: TDragMode;<br />
<div class="key">property</div> OnDragDrop: TDragDropEvent;<br />
<div class="key">property</div> OnDragOver: TDragOverEvent;<br />
<div class="key">property</div> OnEndDock: TEndDragEvent;<br />
<div class="key">property</div> OnEndDrag: TEndDragEvent;<br />
<div class="key">property</div> OnStartDock: TStartDockEvent;<br />
<div class="key">property</div> OnStartDrag: TStartDragEvent;<br />
<div class="key">public</div><br />
<div class="key">function</div> Dragging: Boolean;<br />
<div class="key">function</div> ManualDock(NewDockSite: TWinControl; DropControl: TControl;<br />
<div class="key"> </div>ControlSide: TAlign): Boolean;<br />
<div class="key">function</div> ManualFloat(ScreenPos: TRect): Boolean;<br />
<div class="key">function</div> ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;<br />
<div class="key"> </div>DropControl: TControl; ControlSide: TAlign): Boolean;<br />
<div class="key">procedure</div> BeginDrag(Immediate: Boolean; Threshold: Integer);<br />
<div class="key">procedure</div> Dock(NewDockSite: TWinControl; ARect: TRect);<br />
<div class="key">procedure</div> DragDrop(Source: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> EndDrag(Drop: Boolean);<br />
<div class="key">property</div> DockOrientation: TDockOrientation;<br />
<div class="key">property</div> Floating: Boolean;<br />
<div class="key">property</div> FloatingDockSiteClass: TWinControlClass;<br />
<div class="key">property</div> HostDockSite: TWinControl;<br />
<div class="key">property</div> LRDockWidth: Integer;<br />
<div class="key">property</div> TBDockHeight: Integer;<br />
<div class="key">property</div> UndockHeight: Integer;<br />
<div class="key">property</div> UndockWidth: Integer; <br />
|}<br />
<br />
daß die folgenden Klassen nicht existieren/nicht verwendet werden können -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | TDragImageList = <div class="key">class</div>(TCustomImageList)<br />
TDockZone = <div class="key">class</div><br />
TDockTree = <div class="key">class</div>(TInterfacedObject, IDockManager)<br />
TDragObject = <div class="key">class</div>(TObject)<br />
TBaseDragControlObject = <div class="key">class</div>(TDragObject)<br />
TDragControlObject = <div class="key">class</div>(TBaseDragControlObject)<br />
TDragDockObject = <div class="key">class</div>(TBaseDragControlObject) <br />
|}<br />
und daß die folgenen Funktionen auch nicht benutzbar/inkompatibel sind -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> FindDragTarget(<div class="key">const</div> Pos: TPoint;<br />
<div class="key"> </div>AllowDisabled: Boolean) : TControl;<br />
<div class="key">procedure</div> CancelDrag;<br />
<div class="key">function</div> IsDragObject(sender: TObject): Boolean;<br />
|}<br />
<br />
==== TEdit/TCustomEdit ====<br />
Die Edit-Bedienelemente, welche grundsätzlich gleich in der LCL wie in der VCL funktionieren, besitzen einige Besonderheiten, die bei einer Konvertierung beachtet werden sollten -<br />
# Wegen Restriktionen in den Interfaces, arbeitet TEdit.PasswordChar noch nicht mit allen Interfaces (obwohl es mit der Zeit möglich ist), anstelle von TCustomEdit.EchoMode sollte emPassword benutzt werden, falls der Text verborgen werden muß.<br />
# On Drag/Dock Ereignisse sind noch nicht implementiert. Für mehr Informationen schauen Sie bitte im vorherigen Abschnitt [LazarusFor_Delphi_Users/de#Control Dragging/Docking|Bedienelemente ziehen/andocken] nach.<br />
# Font-Eigenschaften werden üblicherweise ignoriert für die Interface-Konsistenz, für eine detaillierte Beschreibung schauen Sie bitte [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]] an.<br />
<br />
=== (optional) TSplitter -> TPairSplitter ===<br />
'''Bitte verbessern sie mich'''<br />
<br />
Es gibt jetzt ein TSplitter Bedienelement in der LCL, so daß kein Bedarf zum konvertieren besteht.<br />
<br />
Nichtsdestoweniger, wenn sie es doch wollen, hier ist es beschrieben:<br />
<br />
Das folgende basiert lose auf den Fragen von [[User:Vincent | Vincent Snijders]] in der mailing Liste, und Antworten von [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson]:<br />
<br />
Das in Delphi enthaltene "Splitting"-Control welches 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.<br />
<br />
In der LCL gibt es dafür allerdings ein eigenes Control, den TPairSplitter, welcher den selben Zweck erfüllt, wie der TSplitter allerdings zu diesem nicht kompatible ist, so sind also, wenn sie ihr Programm von einem TSplitter auf einen TPairsplitter ändern wollen, einige Anpassungen nötig.<br />
<br />
;Was sind nun genau die Unterschiede?<br />
<br />
Der größte Unterschied ist, das ein TSplitter keine "Kinder" besitzt. Stattdessen wird es zwischen zwei Controls positioniert, welche mittels Align ausgerichtet sind. So erlaubt er wärend der Laufzeit die dynamische Größenannpassung dieser Controls. Um dies zu ermöglichen muss links und rechts ein mittels Align ausgerichtetes Control vorhanden sein. (Beispielsweise ein left-aligned Panel + ein left-aligned TSplitter + ein client-aligned Panel).<br />
<br />
In der LCL ist der TPairSplitter ein spezielles Control mit zwei Panels. Er kann nur nützlich werden, wenn die zu verändernden Kontrols auf dem beiden Panels liegen. Er vergrößert bzw. verkleinert also die beiden Panel, unabhängig davon, ob sie Komponenten enthalten oder nicht.<br />
<br />
Der andere entscheidende Unterschied ist, das der TSplitter der VCL seine Position relativ zu den anderen Komponenten verändert, abhängig von seiner split-Position.<br />
In der LCL dagegen besitzt der TPairSplitter durch die Panels eine absolute Position, wie andere Controls auch, welche sich nach den Eigenschaften top und left richtet. So verändert sich die Position nicht automatisch, wenn die Splitt-Position verändert wird. Ist dies erwünscht, ist es nötig, einen entsprechenden Callback zu setzen und die entsprechenden Einstellungen zu setzen.<br />
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 des Formulars die neue Position zu setzen:<br />
<br />
PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; <br />
<br />
;Wie kann ich nun existierenden Code, der TSplitter verwendet, zu TPairSplitter konvertieren?<br />
<br />
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 - <br />
{| class="code"<br />
|- <br />
| class="header" | VCL || class="header" | LCL<br />
|- class="code"<br />
| class="code" |<div class="key">var</div><br />
BottomPanel: TPanel<div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter: TSplitter<div class="symbol">;</div><br />
LeftPanel: TPanel<div class="symbol">;</div><br />
HorizontalSplitter: TSplitter<div class="symbol">;</div><br />
<div></div><br />
MainPanel: TPanel<div class="symbol">;</div><br />
<div class="key">begin</div><br />
BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (BottomPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Height:= <div class="int">75</div><div class="symbol">;</div><br />
Align:= alBottom<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (VerticalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alBottom<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
HorizontalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (HorizontalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
align:= alLeft<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (LeftPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Width:= <div class="int">125</div><div class="symbol">;</div><br />
Align:= alLeft<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
MainPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (MainPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Caption:= <div class="str">'Hello'</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">var</div><br />
BottomPanel: TPanel<div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter: TPairSplitter<div class="symbol">;</div><br />
LeftPanel: TPanel<div class="symbol">;</div><br />
HorizontalSplitter: TPairSplitter<div class="symbol">;</div><br />
<div></div><br />
MainPanel: TPanel<div class="symbol">;</div><br />
<div class="key">begin</div><br />
VerticalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (VerticalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Width:= Self.Width<div class="symbol">;</div><br />
Height:= Self.Height<div class="symbol">;</div><br />
SplitterType:= pstVertical<div class="symbol">;</div><br />
Position:= Height - <div class="int">75</div><div class="symbol">;</div><br />
Sides[<div class="int">0</div>].Width:= Width<div class="symbol">;</div><br />
Sides[<div class="int">0</div>].Height:= Position<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
HorizontalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (HorizontalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= VerticalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div><br />
Width:= Self.Width<div class="symbol">;</div><br />
Height:= VerticalSplitter.Position<div class="symbol">;</div><br />
align:= alClient<div class="symbol">;</div><br />
SplitterType:= pstHorizontal<div class="symbol">;</div><br />
Position:= <div class="int">125</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (LeftPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= HorizontalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
MainPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (MainPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= HorizontalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Caption:= <div class="str">'Hello'</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (BottomPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= VerticalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
|}<br />
<br />
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.<br />
<br />
So the above example would be something like -<br />
<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi DFM <div style="font-weight: normal">(exteranous Werte wurden entfernt)</div><br />
| class="header" | Lazarus LFM <div style="font-weight: normal">(most width, height etc removed)</div><br />
|- class="code"<br />
| class="code" |<div class="key">object</div>VerticalSplitter: TSplitter<br />
Height <div class="symbol">=</div> <div class="int">3</div><br />
Cursor <div class="symbol">=</div> crVSplit<br />
Align <div class="symbol">=</div> alBottom<br />
<div class="key">end</div><br />
<div class="key">object</div> HorizontalSplitter: TSplitter<br />
Width <div class="symbol">=</div> <div class="int">3</div><br />
Align <div class="symbol">=</div> alLeft<br />
<div class="key">end</div><br />
<div class="key">object</div> BottomPanel: TPanel<br />
Height <div class="symbol">=</div> <div class="int">75</div><br />
Align <div class="symbol">=</div> alBottom<br />
<div class="key">end</div><br />
<div class="key">object</div> LeftPanel: TPanel<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
Align <div class="symbol">=</div> alLeft<br />
<div class="key">end</div><br />
<div class="key">object</div> MainPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
<div class="key">end</div> <br />
| class="code" |<div class="key">object</div> VerticalSplitter: TPairSplitter<br />
Align <div class="symbol">=</div> alClient<br />
SplitterType <div class="symbol">=</div> pstVertical<br />
Position <div class="symbol">=</div> <div class="int">225</div><br />
Height <div class="symbol">=</div> <div class="int">300</div><br />
Width <div class="symbol">=</div> <div class="int">400</div><br />
<div class="key">object</div> Pairsplitterside1: TPairSplitterIde<br />
<div class="key">object</div> HorizontalSplitter: TPairSplitter<br />
Align <div class="symbol">=</div> alClient<br />
Position <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">object</div> Pairsplitterside3: TPairSplitterIde<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">object</div> LeftPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">object</div> Pairsplitterside4: TPairSplitterIde<br />
<div class="key">object</div> MainPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">object</div> Pairsplitterside2: TPairSplitterIde<br />
<div class="key">object</div> BottomPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
Height <div class="symbol">=</div> <div class="int">75</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
|}<br />
<br />
=== TCustomTreeView/TTreeView ===<br />
Beide, VCL und die LCL, bieten eine TCustomTreeView/TTreeView Komponente, die für Baumstrukturen-Listen von Daten mit mehrfachen Knoten und fortgeschrittene Auswahl- und Bilderlisten benutzt wird, und während aktuelle Features vergleichbar sind, sind nicht alle Eigenschaften völlig kompatibel. Hauptsächliche Unterschieder sind wie folgt -<br />
<br />
'''Unvollständige Liste, also update to include TCustomTreeView Mark functions and protected methods '''<br />
<br />
# Die LCL bietet TCustomTreeView.Options, eine Reihe von Optionen, welche im Bedienelement eingestellt werden können, um sein Verhalten und Erscheinungbild ändern. Diese Optionen sind :<br />
#* tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL<br />
#* tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand<br />
#* tvoAutoInsertMark - Update the Drag preview on mouse move.<br />
#* tvoAutoItemHeight - Passt die Item Höhen automatisch an.<br />
#* tvoHideSelection - Markiert das gewählte Item nicht.<br />
#* tvoHotTrack - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack<br />
#* tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes<br />
#* tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly<br />
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect<br />
#* tvoRowSelect - Erlaubt das Auswählen von Zeilen, entsprechend der Ermöglichung von TCustomTreeView.RowSelect<br />
#* tvoShowButtons - Zeigt Schaltflächen, entsprechend der Ermöglichung von TCustomTreeView.ShowButtons<br />
#* tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines<br />
#* tvoShowRoot - show root note, equivalent to enabling TCustomTreeView.ShowRoot<br />
#* tvoShowSeparators - zeigt Begrenzungszeichen<br />
#* tvoToolTips - show tooltips for individual nodes<br />
# Die LCL bietet zusätzliche Eigenschaften:<br />
#* TCustomTreeView.OnSelectionChange Ereignis<br />
#* TCustomTreeView.DefaultItems, für die Standardanzahl von Items<br />
#* TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes<br />
# Während die meisten On Drag/Dock Ereignisse in der LCL verfügbar sind, sie funktionieren nicht. Für mehr Informationen schauen sie bitte den früheren Abschnitt über Control Dragging/Docking an.<br />
<br />
== Mitwirkende und Änderungen ==<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusForDelphiUsers Version] konvertiert.<br />
* Initial import and formatting - [[User:Tom | VlxAdmin]] 9/26/2003<br />
* Begin VCL -> LCL with a section on TSplitter -> TPairSplitter - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003<br />
* Add TControl.Font/TControl.ParentFont to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003<br />
* Update TEdit/TCustomEdit section in VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Add Control Dragging/Docking to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added "Object Inspector" to Delphi IDE -> Lazarus IDE - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added initial "TCustomTreeView/TTreeView" to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added introduction to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Fixed some typos - [[User:Vincent | Vincent]] 10/2/2003<br />
* Fixed Typo [[User:Kirkpatc]] 20 May 2004</div>MaDhttps://wiki.freepascal.org/index.php?title=Lazarus_For_Delphi_Users/de&diff=16230Lazarus For Delphi Users/de2007-01-19T08:23:28Z<p>MaD: /* Bedienelemente ziehen und andocken */ extrem holprige Übersetzung geglättet</p>
<hr />
<div>{{Lazarus For Delphi Users}}<br />
<br />
Diese Zuschreibung ist für Leute gedacht, die an Lazarus interessiert sind und Delphi bereits kennen. Sie beschreibt die Unterschiede zwischen den beiden.<br />
<br />
== Delphi -> Lazarus ==<br />
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 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 />
<br />
=== Die größten Unterschiede ===<br />
Lazarus ist komplett Open Source, ist Plattform unabhä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 daß Lazarus gegenwärtig unter Linux, Free/Open/NetBSD, MacOSX und Win32 läuft.<br />
<br />
''' Lazarus ist nicht komplett, wie es dieser Text ist. Wir suchen ständig neue Entwickler, Package-Entwickler, Portierer, Dokumentations-Schreiber, ... . '''<br />
<br />
== Delphi IDE -> Lazarus IDE ==<br />
=== Projekte ===<br />
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 ist die .lpi Datei die wichtige Datei.<br />
<br />
Eine wichtige Regel: Es gibt ''immer'' ein Projekt. <br />
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 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.<br />
<br />
=== Quelltext Editor ===<br />
Beinahe alle Tasten und Abkürzungen (short cuts) können definiert werden unter Einstellungen -> Editoreinstellungen -> Tastaturbelegung.<br />
<br />
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:<br />
<br />
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 reisen ihre Kommentare. Unter Lazarus können sie eine find declaration sogar für Code in den Kommentaren 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 Kommentaren und Code zusammen zu halten. Zum Beispiel: Es wird die Zeile "c: char; // comment" nicht aufteilen.<br />
<br />
Delphi's "Code Completion" (Ctrl+Space) wird "Identifier Completion" genannt unter Lazarus. Der Lazarus Begriff "Codevervollständigung" ist ein Werkzeug, welches "Automatic Class Completion" (das gleiche wie unter Delphi), "Local Variable Completion" und "Event Assignment Completion" kombiniert. Alle von ihnen werden aufgerufen mit Ctrl+Shift+C und die IDE ermittelt über die Cursor Position, was gemeint ist.<br />
<br />
==== Beispiel für Local Variable Completion ====<br />
Gehen sie davon aus, daß sie gerade eine neue Methode erzeugt haben und die Anweisung schreiben "i:=3;"<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;<br />
<div class="key">begin</div><br />
i:= <div class="int" style="inline">3</div>;<br />
<div class="key">end</div>;<br />
|}<br />
<br />
Positionieren sie den Cursor über den Bezeichner "i" und drücken sie Ctrl+Shift+C und sie erhalten:<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">procedure</div> TForm1.DoSomething;<br />
<div class="key">var</div> i: Integer;<br />
<div class="key">begin</div><br />
i:= <div class="int">3</div>;<br />
<div class="key">end</div>;<br />
|}<br />
<br />
==== Beispiel für Event Assignment Completion ====<br />
Ein nettes Feature des Objektinspektors ist die automatische Erzeugung von Methoden. Das selbe können sie im Quelltext Editor erhalten.<br><br />
Zum Beispiel:<br />
: Button1.OnClick:=<br />
Positionieren sie den Cursor hinter den assign operator ":=" und drücken sie Ctrl+Shift+C.<br />
<br />
==== "Word Completion" Ctrl+W ====<br />
Es arbeitet ähnlich wie die "Identifier Completion", aber es funktioniert nicht nur mit Pascal Bezeichnern, sondern mit allen Wörtern. Es läßt sie alle Wörter in allen geöffneten Dateien wählen, die mit dem selben Buchstaben beginnen.<br />
<br />
==== Unterstützt Include Dateien ====<br />
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 unübersichtlich zu machen.<br />
Zum Beispiel: Method jumping, Class Completion, find declaration, .. arbeiten alle mit Include Dateien.<br />
<br />
Es gibt viele Optionen für die Code Features.<br />
<br />
=== Designer ===<br />
- Richtlinien<br />
==== Objektinspektor ====<br />
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 zur Beachtung für den Gebrauch :<br />
# Nach dem starten von Delphi gibt es ein Objekt-Treeview, welches zum navigieren und auswählen von Objecten unter Darstellung deren Hierarchie genutzt werden kann und so wahlweise die Dropdown-Liste des Objektinspektors ersetzt. In Lazarus ist dieses Treeview fester Bestandteil des Objektinspectors und es ersetzt die Dropdown-Liste völlig. Die Anzeige kann über das Kontextmenü "Komponentenbaum anzeigen" aktiviert bzw. deaktiviert werden.<br />
# 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 eine Schaltfläche auf der rechten Seite der ausgewählten drop-down, welche diese Aktion ebenfalls ausführt.<br />
# 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 Dropdown "none" auswählen.<br />
# Ähnlich wie bei Ereignissen, wird doppeltes Klicken normaler Eigenschaften wie boolean nicht den Wert ändern, sie müssen ihn aus einem drop down wählen. Und um diese zu öffnen mit einem zugeordneten Editorformular, müssen sie auf den '...' Button rechts vom edit/drop-down klicken.<br />
<br />
==== Packages ====<br />
Kann Lazarus Delphi-Packages installieren und verwenden?<br />
<br />
Nein, weil sie die Delphi Compiler Magie benötigen.<br />
<br />
Brauchen wir ein speziell für Lazarus erstelltes?<br />
<br />
Ja.<br />
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.<br />
Sie können es installieren, oder es jetzt in ihren Projekten verwenden. <br />
Es gibt einige Unterschiede zwischen Lazarus und Delphi Packages, daher lesen sie bitte <br />
<br />
- die docs/Packages.txt in den Lazarus Quellen.<br />
<br />
=== VCL -> LCL ===<br />
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 beinhaltet, 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 werden, welche in [[Free Pascal/de|Free Pascal]] enthalten ist.<br />
<br />
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 echten Klone. Änderungen müssen gemacht werden in Anwendungen, Komponenten und Bedienelementen wenn sie portiert werden.<br />
<br />
Das Folgende ist unvolständige Beschreibung der wichtigsten Unterschiede oder Inkompatibilitäten zwischen Delphi und Lazarus für Delphi-Benutzer zu liefern. 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 CVS 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 auffalen, dann bitten wir sie den vorliegenden Text entsprechend zu modifizieren oder neu Abschnitte anzufügen. Wir möchten diese Beschreibung so umfassend und aktuell wie möglich für alle Lazarus-User zur Verfügung stellen.<br />
<br />
==== TControl.Font/TControl.ParentFont ====<br />
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, welche sicherstellt, daß ein Bedienelement immer seiner parent's Schriftart folgt.<br />
<br />
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 spezifische Schriftarten für Schaltflächen des GTK Widget-Toolset benutzen. <br />
<br />
Das bedeutet, daß die meisten LCL Bedienelemente dem Desktop-Desing des Zielrechners entsprechen werden. Das look and feel ihrer Progammoberfläche kann sich also auf verschiedenen Zielrechnern auch entsprechend der Desktop-Einstellungen ändern.<br />
<br />
Wenn beispielsweise ein Label mit einer fetten/spezialfarbigen Schriftart benötigt wird, muß stattdessen ein TStaticText benutzt werden, da TLabel ein Interface spezifisches Bedienelement ist und alle Interfaces eine native Version bereitstellen werden, und die meisten werden Voreinstellungen haben, welche trotzdem benutzt werden.<br />
<br />
==== Bedienelemente ziehen und andocken ====<br />
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. <br />
<br />
Diese Funktionalität ist noch nicht implementiert/beendet in der LCL. 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 der exakt selben Art und Weise. <br />
<br />
Das bedeutet derzeit, daß kein Bedienelement die folgenden TControl Funktionen, Prozeduren, Eigenschaften oder Ereignisse erben/benutzen wird -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" |<div class="key">Protected</div><br />
<div class="key">function</div> GetDockEdge(MousePos: TPoint): TAlign;<br />
<div class="key">function</div> GetDragImages: TDragImageList;<br />
<div class="key">function</div> GetFloating: Boolean;<br />
<div class="key">function</div> GetFloatingDockSiteClass: TWinControlClass;<br />
<div class="key">procedure</div> DoEndDrag(Target:TObject); X, Y: Integer);<br />
<div class="key">procedure</div> DockTrackNoTarget(Source: TDragDockObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoEndDock(Target: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoDock(NewDockSite: TWinControl; <div class="key">var</div> ARect: TRect);<br />
<div class="key">procedure</div> DoStartDock(<div class="key">var</div> DragObject: TDragObject);<br />
<div class="key">procedure</div> DragCanceled;<br />
<div class="key">procedure</div> DragOver(Source: TObject; X, Y: Integer; State: TDragState;<br />
<div class="key">var</div> Accept: Boolean);<br />
<div class="key">procedure</div> DoEndDrag(Target: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> DoStartDrag(<div class="key">var</div> DragObject: TDragObject);<br />
<div class="key">procedure</div> DrawDragDockImage(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> EraseDragDockImage(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> PositionDockRect(DragDockObject: TDragDockObject);<br />
<div class="key">procedure</div> SetDragMode(Value: TDragMode);<br />
<div class="key">property</div> DragKind: TDragKind;<br />
<div class="key">property</div> DragCursor: TCursor;<br />
<div class="key">property</div> DragMode: TDragMode;<br />
<div class="key">property</div> OnDragDrop: TDragDropEvent;<br />
<div class="key">property</div> OnDragOver: TDragOverEvent;<br />
<div class="key">property</div> OnEndDock: TEndDragEvent;<br />
<div class="key">property</div> OnEndDrag: TEndDragEvent;<br />
<div class="key">property</div> OnStartDock: TStartDockEvent;<br />
<div class="key">property</div> OnStartDrag: TStartDragEvent;<br />
<div class="key">public</div><br />
<div class="key">function</div> Dragging: Boolean;<br />
<div class="key">function</div> ManualDock(NewDockSite: TWinControl; DropControl: TControl;<br />
<div class="key"> </div>ControlSide: TAlign): Boolean;<br />
<div class="key">function</div> ManualFloat(ScreenPos: TRect): Boolean;<br />
<div class="key">function</div> ReplaceDockedControl(Control: TControl; NewDockSite: TWinControl;<br />
<div class="key"> </div>DropControl: TControl; ControlSide: TAlign): Boolean;<br />
<div class="key">procedure</div> BeginDrag(Immediate: Boolean; Threshold: Integer);<br />
<div class="key">procedure</div> Dock(NewDockSite: TWinControl; ARect: TRect);<br />
<div class="key">procedure</div> DragDrop(Source: TObject; X, Y: Integer);<br />
<div class="key">procedure</div> EndDrag(Drop: Boolean);<br />
<div class="key">property</div> DockOrientation: TDockOrientation;<br />
<div class="key">property</div> Floating: Boolean;<br />
<div class="key">property</div> FloatingDockSiteClass: TWinControlClass;<br />
<div class="key">property</div> HostDockSite: TWinControl;<br />
<div class="key">property</div> LRDockWidth: Integer;<br />
<div class="key">property</div> TBDockHeight: Integer;<br />
<div class="key">property</div> UndockHeight: Integer;<br />
<div class="key">property</div> UndockWidth: Integer; <br />
|}<br />
<br />
daß die folgenden Klassen nicht existieren/nicht verwendet werden können -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | TDragImageList = <div class="key">class</div>(TCustomImageList)<br />
TDockZone = <div class="key">class</div><br />
TDockTree = <div class="key">class</div>(TInterfacedObject, IDockManager)<br />
TDragObject = <div class="key">class</div>(TObject)<br />
TBaseDragControlObject = <div class="key">class</div>(TDragObject)<br />
TDragControlObject = <div class="key">class</div>(TBaseDragControlObject)<br />
TDragDockObject = <div class="key">class</div>(TBaseDragControlObject) <br />
|}<br />
und daß die folgenen Funktionen auch nicht benutzbar/inkompatibel sind -<br />
{| class="code" <br />
|- class="code"<br />
| class="code" | <div class="key">function</div> FindDragTarget(<div class="key">const</div> Pos: TPoint;<br />
<div class="key"> </div>AllowDisabled: Boolean) : TControl;<br />
<div class="key">procedure</div> CancelDrag;<br />
<div class="key">function</div> IsDragObject(sender: TObject): Boolean;<br />
|}<br />
<br />
==== TEdit/TCustomEdit ====<br />
Die Edit Bedienelemente, welche grundsätzlich gleich in der LCL wie in der VCL funktionieren, haben einige Themen, die bei einer Konvertierung beachtet werden sollten -<br />
# Wegen Restriktionen in den Interfaces, arbeitet TEdit.PasswordChar noch nicht mit allen Interfaces (obwohl es mit der Zeit möglich ist), anstelle von TCustomEdit.EchoMode sollte emPassword benutzt werden, falls der Text verborgen werden muß.<br />
# On Drag/Dock Ereignisse sind noch nicht implementiert. Für mehr Informationen schauen sie bitte im vorherigen Abschnitt [LazarusFor_Delphi_Users/de#Control Dragging/Docking|Bedienelemente ziehen/andocken] nach.<br />
# Font Eigenschaften werden üblicherweise ignoriert für die Interface Konsistenz, für eine detaillierte Beschreibung schauen sie bitte [[#TControl.Font/TControl.ParentFont | TControl.Font/TControl.ParentFont]] an.<br />
<br />
=== (optional) TSplitter -> TPairSplitter ===<br />
'''Bitte verbessern sie mich'''<br />
<br />
Es gibt jetzt ein TSplitter Bedienelement in der LCL, so daß kein Bedarf zum konvertieren besteht.<br />
<br />
Nichtsdestoweniger, wenn sie es doch wollen, hier ist es beschrieben:<br />
<br />
Das folgende basiert lose auf den Fragen von [[User:Vincent | Vincent Snijders]] in der mailing Liste, und Antworten von [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson]:<br />
<br />
Das in Delphi enthaltene "Splitting"-Control welches 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.<br />
<br />
In der LCL gibt es dafür allerdings ein eigenes Control, den TPairSplitter, welcher den selben Zweck erfüllt, wie der TSplitter allerdings zu diesem nicht kompatible ist, so sind also, wenn sie ihr Programm von einem TSplitter auf einen TPairsplitter ändern wollen, einige Anpassungen nötig.<br />
<br />
;Was sind nun genau die Unterschiede?<br />
<br />
Der größte Unterschied ist, das ein TSplitter keine "Kinder" besitzt. Stattdessen wird es zwischen zwei Controls positioniert, welche mittels Align ausgerichtet sind. So erlaubt er wärend der Laufzeit die dynamische Größenannpassung dieser Controls. Um dies zu ermöglichen muss links und rechts ein mittels Align ausgerichtetes Control vorhanden sein. (Beispielsweise ein left-aligned Panel + ein left-aligned TSplitter + ein client-aligned Panel).<br />
<br />
In der LCL ist der TPairSplitter ein spezielles Control mit zwei Panels. Er kann nur nützlich werden, wenn die zu verändernden Kontrols auf dem beiden Panels liegen. Er vergrößert bzw. verkleinert also die beiden Panel, unabhängig davon, ob sie Komponenten enthalten oder nicht.<br />
<br />
Der andere entscheidende Unterschied ist, das der TSplitter der VCL seine Position relativ zu den anderen Komponenten verändert, abhängig von seiner split-Position.<br />
In der LCL dagegen besitzt der TPairSplitter durch die Panels eine absolute Position, wie andere Controls auch, welche sich nach den Eigenschaften top und left richtet. So verändert sich die Position nicht automatisch, wenn die Splitt-Position verändert wird. Ist dies erwünscht, ist es nötig, einen entsprechenden Callback zu setzen und die entsprechenden Einstellungen zu setzen.<br />
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 des Formulars die neue Position zu setzen:<br />
<br />
PairSplitter.Position := PairSplitter.Width - PairSplitter.Position; <br />
<br />
;Wie kann ich nun existierenden Code, der TSplitter verwendet, zu TPairSplitter konvertieren?<br />
<br />
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 - <br />
{| class="code"<br />
|- <br />
| class="header" | VCL || class="header" | LCL<br />
|- class="code"<br />
| class="code" |<div class="key">var</div><br />
BottomPanel: TPanel<div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter: TSplitter<div class="symbol">;</div><br />
LeftPanel: TPanel<div class="symbol">;</div><br />
HorizontalSplitter: TSplitter<div class="symbol">;</div><br />
<div></div><br />
MainPanel: TPanel<div class="symbol">;</div><br />
<div class="key">begin</div><br />
BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (BottomPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Height:= <div class="int">75</div><div class="symbol">;</div><br />
Align:= alBottom<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (VerticalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alBottom<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
HorizontalSplitter:= TSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (HorizontalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
align:= alLeft<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (LeftPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Width:= <div class="int">125</div><div class="symbol">;</div><br />
Align:= alLeft<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
MainPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (MainPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Caption:= <div class="str">'Hello'</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div class="key">end</div>; <br />
| class="code" | <div class="key">var</div><br />
BottomPanel: TPanel<div class="symbol">;</div><br />
<div></div><br />
VerticalSplitter: TPairSplitter<div class="symbol">;</div><br />
LeftPanel: TPanel<div class="symbol">;</div><br />
HorizontalSplitter: TPairSplitter<div class="symbol">;</div><br />
<div></div><br />
MainPanel: TPanel<div class="symbol">;</div><br />
<div class="key">begin</div><br />
VerticalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (VerticalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= Self<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Width:= Self.Width<div class="symbol">;</div><br />
Height:= Self.Height<div class="symbol">;</div><br />
SplitterType:= pstVertical<div class="symbol">;</div><br />
Position:= Height - <div class="int">75</div><div class="symbol">;</div><br />
Sides[<div class="int">0</div>].Width:= Width<div class="symbol">;</div><br />
Sides[<div class="int">0</div>].Height:= Position<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
HorizontalSplitter:= TPairSplitter.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (HorizontalSplitter) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= VerticalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div><br />
Width:= Self.Width<div class="symbol">;</div><br />
Height:= VerticalSplitter.Position<div class="symbol">;</div><br />
align:= alClient<div class="symbol">;</div><br />
SplitterType:= pstHorizontal<div class="symbol">;</div><br />
Position:= <div class="int">125</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
LeftPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (LeftPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= HorizontalSplitter.Sides[<div class="int">0</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
MainPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (MainPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= HorizontalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
Caption:= <div class="str">'Hello'</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div></div><br />
BottomPanel:= TPanel.Create(Self)<div class="symbol">;</div><br />
<div class="key">with</div> (BottomPanel) <div class="key">do</div><br />
<div class="key">begin</div><br />
Parent:= VerticalSplitter.Sides[<div class="int">1</div>]<div class="symbol">;</div><br />
Align:= alClient<div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
<div class="key">end</div><div class="symbol">;</div><br />
|}<br />
<br />
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.<br />
<br />
So the above example would be something like -<br />
<br />
{| class="code"<br />
|- <br />
| class="header" | Delphi DFM <div style="font-weight: normal">(exteranous Werte wurden entfernt)</div><br />
| class="header" | Lazarus LFM <div style="font-weight: normal">(most width, height etc removed)</div><br />
|- class="code"<br />
| class="code" |<div class="key">object</div>VerticalSplitter: TSplitter<br />
Height <div class="symbol">=</div> <div class="int">3</div><br />
Cursor <div class="symbol">=</div> crVSplit<br />
Align <div class="symbol">=</div> alBottom<br />
<div class="key">end</div><br />
<div class="key">object</div> HorizontalSplitter: TSplitter<br />
Width <div class="symbol">=</div> <div class="int">3</div><br />
Align <div class="symbol">=</div> alLeft<br />
<div class="key">end</div><br />
<div class="key">object</div> BottomPanel: TPanel<br />
Height <div class="symbol">=</div> <div class="int">75</div><br />
Align <div class="symbol">=</div> alBottom<br />
<div class="key">end</div><br />
<div class="key">object</div> LeftPanel: TPanel<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
Align <div class="symbol">=</div> alLeft<br />
<div class="key">end</div><br />
<div class="key">object</div> MainPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
<div class="key">end</div> <br />
| class="code" |<div class="key">object</div> VerticalSplitter: TPairSplitter<br />
Align <div class="symbol">=</div> alClient<br />
SplitterType <div class="symbol">=</div> pstVertical<br />
Position <div class="symbol">=</div> <div class="int">225</div><br />
Height <div class="symbol">=</div> <div class="int">300</div><br />
Width <div class="symbol">=</div> <div class="int">400</div><br />
<div class="key">object</div> Pairsplitterside1: TPairSplitterIde<br />
<div class="key">object</div> HorizontalSplitter: TPairSplitter<br />
Align <div class="symbol">=</div> alClient<br />
Position <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">object</div> Pairsplitterside3: TPairSplitterIde<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">object</div> LeftPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
Width <div class="symbol">=</div> <div class="int">125</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">object</div> Pairsplitterside4: TPairSplitterIde<br />
<div class="key">object</div> MainPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">object</div> Pairsplitterside2: TPairSplitterIde<br />
<div class="key">object</div> BottomPanel: TPanel<br />
Align <div class="symbol">=</div> alClient<br />
Height <div class="symbol">=</div> <div class="int">75</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
<div class="key">end</div><br />
|}<br />
<br />
=== TCustomTreeView/TTreeView ===<br />
Beide, VCL und die LCL, bieten eine TCustomTreeView/TTreeView Komponente, die für Baumstrukturen-Listen von Daten mit mehrfachen Knoten und fortgeschrittene Auswahl- und Bilderlisten benutzt wird, und während aktuelle Features vergleichbar sind, sind nicht alle Eigenschaften völlig kompatibel. Hauptsächliche Unterschieder sind wie folgt -<br />
<br />
'''Unvollständige Liste, also update to include TCustomTreeView Mark functions and protected methods '''<br />
<br />
# Die LCL bietet TCustomTreeView.Options, eine Reihe von Optionen, welche im Bedienelement eingestellt werden können, um sein Verhalten und Erscheinungbild ändern. Diese Optionen sind :<br />
#* tvoAllowMultiselect - enables multi node select mode, equivalent to enabling TCustomTreeView.MultiSelect in the D6 VCL<br />
#* tvoAutoExpand - Auto Expand nodes, equivalent to enabling TCustomTreeView.AutoExpand<br />
#* tvoAutoInsertMark - Update the Drag preview on mouse move.<br />
#* tvoAutoItemHeight - Passt die Item Höhen automatisch an.<br />
#* tvoHideSelection - Markiert das gewählte Item nicht.<br />
#* tvoHotTrack - use Hot Tracking, equivalent to enabling TCustomTreeview.HotTrack<br />
#* tvoKeepCollapsedNodes - When shrinking/folding nodes, keep the child nodes<br />
#* tvoReadOnly - make Treeview read only, equivalent to enabling TCustomTreeview.ReadOnly<br />
#* tvoRightClickSelect - allow using Mouse Right Clicks to select nodes, equivalent to enabling TCustomTreeView.RightClickSelect<br />
#* tvoRowSelect - Erlaubt das Auswählen von Zeilen, entsprechend der Ermöglichung von TCustomTreeView.RowSelect<br />
#* tvoShowButtons - Zeigt Schaltflächen, entsprechend der Ermöglichung von TCustomTreeView.ShowButtons<br />
#* tvoShowLines - show node lines, equivalent to enabling TCustomTreeView.ShowLines<br />
#* tvoShowRoot - show root note, equivalent to enabling TCustomTreeView.ShowRoot<br />
#* tvoShowSeparators - zeigt Begrenzungszeichen<br />
#* tvoToolTips - show tooltips for individual nodes<br />
# Die LCL bietet zusätzliche Eigenschaften:<br />
#* TCustomTreeView.OnSelectionChange Ereignis<br />
#* TCustomTreeView.DefaultItems, für die Standardanzahl von Items<br />
#* TCustomTreeView.ExpandSignType to determine sign used on expandable/collapsible nodes<br />
# Während die meisten On Drag/Dock Ereignisse in der LCL verfügbar sind, sie funktionieren nicht. Für mehr Informationen schauen sie bitte den früheren Abschnitt über Control Dragging/Docking an.<br />
<br />
== Mitwirkende und Änderungen ==<br />
Diese Seite wurde von der epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusForDelphiUsers Version] konvertiert.<br />
* Initial import and formatting - [[User:Tom | VlxAdmin]] 9/26/2003<br />
* Begin VCL -> LCL with a section on TSplitter -> TPairSplitter - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003<br />
* Add TControl.Font/TControl.ParentFont to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 9/30/2003<br />
* Update TEdit/TCustomEdit section in VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Add Control Dragging/Docking to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added "Object Inspector" to Delphi IDE -> Lazarus IDE - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added initial "TCustomTreeView/TTreeView" to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Added introduction to VCL -> LCL - [http://lazarus-ccr.sourceforge.net/index.php?wiki=AndrewJohnson Andrew Johnson] 10/1/2003<br />
* Fixed some typos - [[User:Vincent | Vincent]] 10/2/2003<br />
* Fixed Typo [[User:Kirkpatc]] 20 May 2004</div>MaD