Difference between revisions of "Extending the IDE/de"

From Lazarus wiki
Jump to navigationJump to search
(→‎Config files: translated)
m (Fixed syntax highlighting; deleted category included in page template)
 
(48 intermediate revisions by 5 users not shown)
Line 3: Line 3:
 
= Erweitern der IDE =
 
= Erweitern der IDE =
  
== Einleitung ==
+
== Überblick ==
  
 
Die IDE unterstützt verschiedene Erweiterungen:
 
Die IDE unterstützt verschiedene Erweiterungen:
Line 13: Line 13:
 
; Eigenschafts-Editoren : Stellen die Editierfähigkeiten im Objektinspektor zur Verfügung.
 
; Eigenschafts-Editoren : Stellen die Editierfähigkeiten im Objektinspektor zur Verfügung.
  
; Experten : Das sind alle anderen Typen von Editoren. Sie registrieren neue Menüpunkte, Tatenkürzel oder erweitern andere Merkmale der IDE.
+
; Experten : Das sind alle anderen Typen von Editoren. Sie registrieren neue Menüpunkte, Tastenkürzel oder erweitern andere Merkmale der IDE.
  
  
Line 29: Line 29:
 
Ein einzelner Menüpunkt wie 'View Object Inspector' wird '''TIDEMenuCommand''' genannt. Sie können einen erzeugen mit dem Befehl '''RegisterIDEMenuCommand''', der in zwei Formen mit Unmengen von Parametern vorkommen kann:
 
Ein einzelner Menüpunkt wie 'View Object Inspector' wird '''TIDEMenuCommand''' genannt. Sie können einen erzeugen mit dem Befehl '''RegisterIDEMenuCommand''', der in zwei Formen mit Unmengen von Parametern vorkommen kann:
  
<Delphi>function RegisterIDEMenuCommand(Parent: TIDEMenuSection;
+
<syntaxhighlight lang=pascal>function RegisterIDEMenuCommand(Parent: TIDEMenuSection;
 
                                 const Name, Caption: string;
 
                                 const Name, Caption: string;
 
                                 const OnClickMethod: TNotifyEvent = nil;
 
                                 const OnClickMethod: TNotifyEvent = nil;
Line 41: Line 41:
 
                                 const Command: TIDECommand = nil;
 
                                 const Command: TIDECommand = nil;
 
                                 const ResourceName: String = ''
 
                                 const ResourceName: String = ''
                                 ): TIDEMenuCommand; overload;</Delphi>
+
                                 ): TIDEMenuCommand; overload;</syntaxhighlight>
  
 
Der Unterschied zwischen diesen beiden Formen liegt nur darin, wie Sie die 'parent menu section' angeben. Geben Sie diesen Menüabschnitt direkt an oder oder indirekt mittels eines Pfades. Viele Standardmenüs finden Sie in der Unit ''MenuIntf''. Zum Beispiel den Abschnitt '''mnuTools''', der das Menü ''Tools'' aus dem IDE-Hauptmenü liefert. Es enthält einen Abschnitt '''itmSecondaryTools''', das ist der empfohlene Abschnitt für "Third party tools".  
 
Der Unterschied zwischen diesen beiden Formen liegt nur darin, wie Sie die 'parent menu section' angeben. Geben Sie diesen Menüabschnitt direkt an oder oder indirekt mittels eines Pfades. Viele Standardmenüs finden Sie in der Unit ''MenuIntf''. Zum Beispiel den Abschnitt '''mnuTools''', der das Menü ''Tools'' aus dem IDE-Hauptmenü liefert. Es enthält einen Abschnitt '''itmSecondaryTools''', das ist der empfohlene Abschnitt für "Third party tools".  
  
 
Das folgende Beispiel registriert einen neuen Menübefehl mit dem Namen 'MyTool', der Beschriftung 'Start my tool' und führt beim Klicken die Prozedur ''StartMyTool'' aus:
 
Das folgende Beispiel registriert einen neuen Menübefehl mit dem Namen 'MyTool', der Beschriftung 'Start my tool' und führt beim Klicken die Prozedur ''StartMyTool'' aus:
<Delphi>procedure StartMyTool;
+
<syntaxhighlight lang=pascal>procedure StartMyTool;
 
begin
 
begin
 
   ...wird ausgeführt, wenn der Menüpunkt angeklickt wird...
 
   ...wird ausgeführt, wenn der Menüpunkt angeklickt wird...
Line 54: Line 54:
 
begin
 
begin
 
   RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool','Start my tool',nil,@StartMyTool);
 
   RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool','Start my tool',nil,@StartMyTool);
end;</Delphi>
+
end;</syntaxhighlight>
  
 
Falls Sie statt der Prozedur eine Methode aufrufen wollen, dann verwenden Sie den '''OnClickMethod''' Parameter.
 
Falls Sie statt der Prozedur eine Methode aufrufen wollen, dann verwenden Sie den '''OnClickMethod''' Parameter.
Line 60: Line 60:
 
Dieser Menüpunkt hat kein Tastenkürzel. Wenn Sie ein Tastenkürzel brauchen, dann erzeugen Sie einen '''TIDECommand''' und übergeben das Kürzel im '''Command''' Parameter. Zum Beispiel:
 
Dieser Menüpunkt hat kein Tastenkürzel. Wenn Sie ein Tastenkürzel brauchen, dann erzeugen Sie einen '''TIDECommand''' und übergeben das Kürzel im '''Command''' Parameter. Zum Beispiel:
  
<Delphi>uses ... IDECommands, MenuIntf;
+
<syntaxhighlight lang=pascal>uses ... IDECommands, MenuIntf;
 
...
 
...
 
var
 
var
Line 72: Line 72:
 
   CmdMyTool := RegisterIDECommand(Cat,'Start my tool', 'Starts my tool to do some stuff', Key, nil, @StartMyTool);
 
   CmdMyTool := RegisterIDECommand(Cat,'Start my tool', 'Starts my tool to do some stuff', Key, nil, @StartMyTool);
 
   RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool', 'Start my tool', nil, nil, CmdMyTool);
 
   RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool', 'Start my tool', nil, nil, CmdMyTool);
end;</Delphi>
+
end;</syntaxhighlight>
  
 
= Konfigurationsdateien =
 
= Konfigurationsdateien =
Line 80: Line 80:
 
Alle Konfigurationsdateien der IDE werden in einem einzigen Verzeichnis als xml-Dateien gespeichert. Auch Packages können dort ihre eigenen Dateien ablegen. Das primäre Konfigurationsverzeichnis kann ermittelt werden mit:
 
Alle Konfigurationsdateien der IDE werden in einem einzigen Verzeichnis als xml-Dateien gespeichert. Auch Packages können dort ihre eigenen Dateien ablegen. Das primäre Konfigurationsverzeichnis kann ermittelt werden mit:
  
<Delphi>uses LazIDEIntf;
+
<syntaxhighlight lang=pascal>uses LazIDEIntf;
 
...
 
...
   Directory := LazarusIDE.GetPrimaryConfigPath;</Delphi>
+
   Directory := LazarusIDE.GetPrimaryConfigPath;</syntaxhighlight>
  
 
Packages erzeugen ihre eigenen xml-Dateien mit:
 
Packages erzeugen ihre eigenen xml-Dateien mit:
  
<Delphi>uses
+
<syntaxhighlight lang=pascal>uses
 
   ..., LCLProc, BaseIDEIntf, LazConfigStorage;
 
   ..., LCLProc, BaseIDEIntf, LazConfigStorage;
  
Line 145: Line 145:
 
     end;
 
     end;
 
   end;
 
   end;
end;</Delphi>
+
end;</syntaxhighlight>
  
 
= Komponenten =
 
= Komponenten =
Line 154: Line 154:
 
* '''Speichern:''' Hier können Sie Ihre Komponente oder Ihr Package unter einen Namen Ihrer Wahl speichern.
 
* '''Speichern:''' Hier können Sie Ihre Komponente oder Ihr Package unter einen Namen Ihrer Wahl speichern.
 
* '''Hinzufügen:''' Hier erscheint ein Fenster mit mehreren Tabs. Die wichtisten im Überblick: Im Tab ''Neue Datei'' können Sie zum Beispiel Units und Formulardateien für Ihr Projekt erstellen. Eine bereits vorhandene Unit können Sie im Reiter ''Neue Unit'' einbinden. Wenn Sie Ihre Komponente auf eine bereits existierende Komponente aufbauen wollen, können Sie diese im Tab ''Neue Komponente'' auswählen.
 
* '''Hinzufügen:''' Hier erscheint ein Fenster mit mehreren Tabs. Die wichtisten im Überblick: Im Tab ''Neue Datei'' können Sie zum Beispiel Units und Formulardateien für Ihr Projekt erstellen. Eine bereits vorhandene Unit können Sie im Reiter ''Neue Unit'' einbinden. Wenn Sie Ihre Komponente auf eine bereits existierende Komponente aufbauen wollen, können Sie diese im Tab ''Neue Komponente'' auswählen.
* '''Einstellungen:''' In diesem Dialog können Sie neben der Berschreibung Ihrer Komponente und ihrer Versionierung auch den Package-Typ einstellen sowie Sprachregelungen treffen.
+
* '''Einstellungen:''' In diesem Dialog können Sie neben der Beschreibung Ihrer Komponente und ihrer Versionierung auch den Package-Typ einstellen sowie Sprachregelungen treffen.
 
* '''Installieren:''' Wenn Ihre Komponente fertig erstellt ist, können Sie sie über diesen Knopf in die IDE einbinden.
 
* '''Installieren:''' Wenn Ihre Komponente fertig erstellt ist, können Sie sie über diesen Knopf in die IDE einbinden.
 
* '''Compilereinstellungen:''' Hier lässt sich festlegen, mit welchen Optionen und Compiler-Argumenten Ihr Package kompiliert werden soll.
 
* '''Compilereinstellungen:''' Hier lässt sich festlegen, mit welchen Optionen und Compiler-Argumenten Ihr Package kompiliert werden soll.
Line 166: Line 166:
 
# Klicken Sie auf Ok - und schon können Sie in der Unit meinbutton.pas den TButton an Ihre Bedürfnisse anpassen.
 
# Klicken Sie auf Ok - und schon können Sie in der Unit meinbutton.pas den TButton an Ihre Bedürfnisse anpassen.
  
=== Einer neuen Komponente ein Icon für die Komponentenpalette verpassen ===
+
=== Einer neuen Komponente ein Icon für die Komponentenpalette geben ===
  
Zum Beispiel wollen wir TMyButton ein Icon verpassen. Erzeugen sie eine Bilddatei in den Formaten .bmp, .xpm oder .png mit dem selben Namen wie die Komponentenklasse, z.B. ''tmybutton.png'' und speichern sie diese im Package-Quelltextverzeichnis. The image can be created by any graphic program (e.g. gimp) and should be no bigger than 24x24 pixel.
+
Zum Beispiel wollen wir TMyButton ein Icon geben. Erzeugen sie eine Bilddatei im Format .bmp, .xpm oder .png mit dem selben Namen wie die Komponentenklasse, z.B. ''tmybutton.png'' und speichern sie diese im Package-Quelltextverzeichnis. Das Bild kann mit einem beliebigen Grafikprogramm (z.B. Gimp) erzeugt werden und sollte nicht größer sein als 24x24 Pixel. Konvertieren Sie das Bild in eine .lrs Datei mit dem 'lazres' Werkzeug, das Sie im Verzeichnis 'lazarus/tools' finden:
Then convert the image to a .lrs file with the lazres tool, which can be found in the lazarus/tools directory:
 
 
   ~/lazarus/tools/lazres mybutton.lrs tmybutton.png
 
   ~/lazarus/tools/lazres mybutton.lrs tmybutton.png
  
This creates an pascal include file, which is used in the initialization section of mybutton.pas:
+
Das erzeugt eine Pascal Include Datei, die im Initialisierungs-Abschnitt von mybutton.pas verwendet wird:
  
 
   initialization
 
   initialization
 
     {$I mybutton.lrs}
 
     {$I mybutton.lrs}
  
Installieren sie das Package.
+
Installieren Sie das Package.
 +
 
 +
===Eine Komponente aus der Palette verstecken===
 +
 
 +
Package IDEIntf, unit componentreg:
 +
IDEComponentPalette.FindComponent('TButton').Visible:=false;
  
 
== Komponenten-Editoren schreiben ==
 
== Komponenten-Editoren schreiben ==
  
ToDo
+
Ein Komponenten-Editor verarbeitet Dinge wie einen Doppelklick auf eine Komponente im Designer oder das Hinzufügen von Menüpunkten bei einem Rechtsklick auf eine Komponente. Einen Komponenten-Editor zu schreiben ist einfach. Siehe die Unit ''componenteditors.pas'' vom Package ''IDEIntf'' für zahlreiche Beispiele. Um beispielweise beim Doppelklick einen Editor anzuzeigen, siehe: TCheckListBoxComponentEditor.
Hinweis: siehe componenteditors.pas für Beispiele
 
  
 
== Eigenschafts-Editoren schreiben ==
 
== Eigenschafts-Editoren schreiben ==
  
ToDo
+
Jeder Eigenschaftstyp (integer, string, TFont, ...) im Objektinspektor benötigt einen Eigenschafts-Editor. Wenn Ihre Komponente eine Eigenschaft 'Password' vom Typ ''string'' hat, können Sie einen Eigenschafts-Editor definieren für Ihre besondere Komponenten-Klasse, mit genau diesem Typ. Die Unit ''propedits.pp'' aus dem Package ''IDEIntf'' enthält viele der Standard-Eigenschafts-Editoren, die von der IDE selbst verwendet werden. Zum Beispiel ist der ''TStringPropertyEditor'' der vorgegebene Editor für alle Strings, während ''TComponentNamePropertyEditor'' spezieller ist und nur ''TComponent.Name'' bearbeitet.
Hinweis: siehe propedits.pp für Beispiele
+
 
 +
=Designer=
 +
 
 +
== Einen Designer-Mediator schreiben ==
 +
 
 +
Der Standard-Designer erlaubt es, die Steuerelemente der LCL visuell zu bearbeiten, wo hingegen alle anderen nur als Symbole angezeigt werden. Um Steuerelemente (die nicht aus der LCL stammen) ebenfalls visuell bearbeiten zu können, sollten Sie einen '''Designer-Mediator''' erzeugen. Dieser kann dazu verwendet werden, Webseiten zu entwerfen, UML Diagramme oder andere Widgetsets wie [[fpGUI]].
 +
Es gibt ein ausführliches Beispiel unter: in examples/designnonlcl/.
 +
 
 +
*Installieren Sie das Beispielspackage examples/designnonlcl/notlcldesigner.lpk und starten Sie die IDE neu. Dadurch werden der Designer-Mediator für TMyWidget-Komponenten registriert und die neuen Komponenten TMyButton, TMyGroupBox zur Komponentenpalette hinzugefügt.
 +
*Öffnen Sie das Beispielsprojekt examples/designnonlcl/project/NonLCL1.lpi.
 +
*Öffnen Sie die unit1.pas und zeigen Sie das Formular im Designer an (mit F12). Sie sollten jetzt die Komponenten als rote Rechtecke dargestellt sehen, die Sie genau so wie LCL-Steuerelemente auswählen, verschieben oder in der Größe verändern können.
  
== Register event handlers ==
+
== Einen neuen einzigartigen Komponentennamen erzeugen ==
  
There are several events in the IDE, for which plugins can add their own handlers.
+
<syntaxhighlight lang=pascal>
 +
uses FormEditingIntf;
  
=== Designerereignisse ===
+
...
  
In propedits.pp there is a "GlobalDesignHook" object, which maintains several events for designing. Each event calls a list of handlers. The default handlers are added by the IDE. You can add your own handlers with the AddHandlerXXX and RemoveHandlerXXX methods. They will be called before the default handlers.
+
NewName:=FormEditingHook.CreateUniqueComponentName(AComponent);
  
Examples:
+
// Or if you need to create the name before creating the component:
  
  Adding your handler (this is normally done in the constructor of your object):
+
NewName:=FormEditingHook.CreateUniqueComponentName(ComponentClassName,OwnerComponent);
 +
// ComponentClassName will be used as prefix, without a leading T.
 +
// OwnerComponent is the new owner of the new component.
 +
</syntaxhighlight>
 +
 
 +
== Eine Komponente im Designer/Objektinspektor auswählen ==
 +
 
 +
<syntaxhighlight lang=pascal>uses propedits;
 +
..
 +
GlobalDesignHook.SelectOnlyThis(AComponent);</syntaxhighlight>
 +
 
 +
= Ereignis-Handler =
 +
 
 +
Es gibt einige Ereignisse in der IDE, für die Plugins ihre eigenen Handler hinzufügen können.
 +
 
 +
== Designerereignisse ==
 +
 
 +
In propedits.pp gibt es ein "GlobalDesignHook" Objekt, das verschiedene Ereignisse zum Entwurf verwaltet. Jedes Ereignis ruft eine List von Handlern auf. Die Vorgabe-Handler werden von der IDE angefügt. Sie können eigene Handler mit den Methoden ''AddHandlerXXX'' und ''RemoveHandlerXXX'' anfügen. Diese werden aufgerufen vor den Vorgabe-Handlern.
 +
 
 +
Beispiele:
 +
 
 +
  Einfügen Ihres Handlers (das geschieht normalerweise im Konstruktor Ihres Objekts):
 
     GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);<br>   
 
     GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);<br>   
   Removing your handler:
+
   Entfernen Ihrer Handlers:
 
     GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);<br>
 
     GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);<br>
   You can remove all handlers at once. For example, it is a good idea to add
+
   Sie können alle Handler auf einmal entfernen. Zum Beispiel, ist es eine gute Idee,
   this line in the destructor of object:
+
   diese Zeile im Destruktor des Objekts anzufügen:
 
     GlobalDesignHook.RemoveAllHandlersForObject(Self);
 
     GlobalDesignHook.RemoveAllHandlersForObject(Self);
  
The handlers of GlobalDesignHook:
+
Die Handler von GlobalDesignHook:
  
 
   // lookup root
 
   // lookup root
Line 248: Line 283:
 
   RefreshPropertyValues
 
   RefreshPropertyValues
  
=== Projektereignisse ===
+
==Benachrichtigt werden, wenn ein Formular im Designer modifiziert wurde==
 +
 
 +
Jedes LCL-Formular hat einen Designer des Typs TIDesigner. Die IDE erzeugt Designer der Type TComponentEditorDesigner, die in der IDEIntf Unit componenteditors definiert ist.
 +
Ein Beispiel:
 +
 
 +
<syntaxhighlight lang=pascal>procedure TYourAddOn.OnDesignerModified(Sender: TObject);
 +
var
 +
  IDEDesigner: TComponentEditorDesigner;
 +
begin
 +
  IDEDesigner:=TComponentEditorDesigner(Sender);
 +
  ...
 +
end;
 +
 
 +
procedure TYourAddOn.ConnectDesignerForm(Form1: TCustomForm);
 +
var
 +
  IDEDesigner: TComponentEditorDesigner;
 +
begin
 +
  IDEDesigner:=TComponentEditorDesigner(Form1.Designer);
 +
  IDEDesigner.AddHandlerModified(@OnDesignerModified);
 +
end;</syntaxhighlight>
 +
 
 +
==Projektereignisse==
  
 
Diese Ereignisse sind definiert in der Unit LazIDEIntf.
 
Diese Ereignisse sind definiert in der Unit LazIDEIntf.
  
  LazarusIDE.AddHandlerOnProjectClose
 
  LazarusIDE.AddHandlerOnProjectOpened
 
  LazarusIDE.AddHandlerOnSavedAll
 
  LazarusIDE.AddHandlerOnSavingAll
 
  
 +
*'''LazarusIDE.AddHandlerOnProjectClose''': wird aufgerufen bevor ein Projekt geschlossen wird
 +
*'''LazarusIDE.AddHandlerOnProjectOpened''': wird aufgerufen nachdem das Projekt vollständig geöffnet wurde (wenn beispielsweise alle erforderlichen Packages geladen und die Units im Quelltext-Editor geöffnet wurden)
 +
*'''LazarusIDE.AddHandlerOnSavingAll''': wird aufgerufen bevor die IDE alles speichert
 +
*'''LazarusIDE.AddHandlerOnSavedAll''': wird aufgerufen nachdem die IDE alles gespeichert hat
 +
*'''LazarusIDE.AddHandlerOnProjectBuilding''': wird aufgerufen bevor die IDE das Projekt erstellt
 +
*'''LazarusIDE.AddHandlerOnProjectDependenciesCompiling''': wird aufgerufen bevor die IDE die Packageabhängigkeiten eines Projekts kompiliert
 +
*'''LazarusIDE.AddHandlerOnProjectDependenciesCompiled''': wird aufgerufen nachdem die IDE die Packageabhängigkeiten eines Projekts kompiliert hat
 +
 +
==Andere IDE Ereignisse==
 +
 +
*'''LazarusIDE.AddHandlerOnIDERestoreWindows''': wird aufgerufen, wenn die IDE ihre Fernster wiederherstellt (bevor das erste Projekt geöffnet wird)
 +
*'''LazarusIDE.AddHandlerOnIDEClose''': wird aufgerufen, wenn die IDE beendet wird (nach closequery, also keine Interaktivität mehr)
 +
*'''LazarusIDE.AddHandlerOnQuickSyntaxCheck''': wird aufgerufen, wenn der Menüpunkt oder das Tastenkürzel für die Schnelle Syntaxüberprüfung aussgeführt wird
 +
 +
= Projekt =
 
== Aktuelles Projekt ==
 
== Aktuelles Projekt ==
  
The current main project can be obtained by LazarusIDE.ActiveProject. (unit LazIDEIntf)
+
Das aktuelle Hauptprojekt erhalten Sie mit LazarusIDE.ActiveProject. (unit LazIDEIntf)
  
 
== Alle Units des aktuellen Projekts ==
 
== Alle Units des aktuellen Projekts ==
  
To iterate through all pascal units of the current main project of the IDE you can use for example:
+
Um alle Pascal-Units des aktuellen Hauptprojektes der IDE zu durchlaufen benutzen Sie zum Beispiel:
  
<Delphi>
+
<syntaxhighlight lang=pascal>
 
uses LCLProc, FileUtil, LazIDEIntf, ProjectIntf;
 
uses LCLProc, FileUtil, LazIDEIntf, ProjectIntf;
  
Line 285: Line 352:
 
     end;
 
     end;
 
end;
 
end;
</Delphi>
+
</syntaxhighlight>
  
 
== Die .lpr, .lpi und .lps Datei eines Projekts ==
 
== Die .lpr, .lpi und .lps Datei eines Projekts ==
  
<Delphi>
+
<syntaxhighlight lang=pascal>
 
uses LCLProc, FileUtil, ProjectIntf, LazIDEIntf;
 
uses LCLProc, FileUtil, ProjectIntf, LazIDEIntf;
 
var
 
var
Line 307: Line 374:
 
     DebugLn(['Project has lpr file: ',LazProject.MainFile.Filename]);
 
     DebugLn(['Project has lpr file: ',LazProject.MainFile.Filename]);
 
end;
 
end;
</Delphi>
+
</syntaxhighlight>
  
== The executable / target file name of a project ==
+
== Der Name der ausführbaren Ziel-Datei eines Projekts ==
  
Es gibt ein Makro $(TargetFile), welches in Pfaden und externen Werkzeugen verwendet werden kann.
+
Es gibt ein Makro $(TargetFile), das in Pfaden und externen Werkzeugen verwendet werden kann.
You can query the macro in code:
+
Beispiel:
  
<Delphi>
+
<syntaxhighlight lang=pascal>
 
uses MacroIntf;
 
uses MacroIntf;
  
Line 323: Line 390:
 
     raise Exception.Create('unable to retrieve target file of project');
 
     raise Exception.Create('unable to retrieve target file of project');
 
end;
 
end;
</Delphi>
+
</syntaxhighlight>
 +
 
 +
Für weitere Makros siehe: [[IDE Macros in paths and filenames/de|IDE Makros in Pfaden und Dateinamen]].
 +
 
 +
==Hinzufügen Ihres eigenen Projekttyps==
  
== Add your own file type ==
+
Sie können Menüpunkte zum Dialog 'Neu ...' hinzufügen:
  
Sie können Einträge hinzufügen zum 'Neu ...' Dialog:
+
*Siehe die Unit ProjectIntf aus dem Package IDEIntf.
 +
*Siehe die [[Project Templates]]
  
*See the unit ProjectIntf of the package IDEIntf.
+
==Hinzufügen Ihres eigenen Dateityps==
*Choose a base class TFileDescPascalUnit for normal units or TFileDescPascalUnitWithResource for a new form/datamodule.
 
  
=== Add a new file type ===
+
Sie können Einträge hinzufügen zum Dialog 'Neu ...':
 +
 
 +
*Siehe die Unit ProjectIntf aus dem Package IDEIntf.
 +
*Wählen Sie eine Basisklasse TFileDescPascalUnit für normale Units oder TFileDescPascalUnitWithResource für ein neues Formular/Datenmodul.
 +
 
 +
===Hinzufügen eines neuen Dateityps===
  
 
Dieses Beispiel entstammt der ide/mainintf.pas Datei und registriert eine einfache Textdatei:
 
Dieses Beispiel entstammt der ide/mainintf.pas Datei und registriert eine einfache Textdatei:
  
<Delphi>
+
 
uses ProjectIntf;
+
<syntaxhighlight lang=pascal>uses ProjectIntf;
 
...
 
...
 
   { TFileDescText }
 
   { TFileDescText }
  
   TFileDescText = class(TProjectFileDescriptor)
+
   TFileDescMyText = class(TProjectFileDescriptor)
 
   public
 
   public
 
     constructor Create; override;
 
     constructor Create; override;
Line 348: Line 424:
 
   end;
 
   end;
 
...
 
...
{ TFileDescText }
 
  
constructor TFileDescText.Create;
+
procedure Register;
 +
 
 +
implementation
 +
 
 +
procedure Register;
 +
begin
 +
  RegisterProjectFileDescriptor(TFileDescMyText.Create,FileDescGroupName);
 +
end;
 +
 
 +
{ TFileDescMyText }
 +
 
 +
constructor TFileDescMyText.Create;
 
begin
 
begin
 
   inherited Create;
 
   inherited Create;
   Name:=FileDescNameText;
+
   Name:='MyText'; // do not translate this
 
   DefaultFilename:='text.txt';
 
   DefaultFilename:='text.txt';
 
   AddToProject:=false;
 
   AddToProject:=false;
Line 360: Line 446:
 
function TFileDescText.GetLocalizedName: string;
 
function TFileDescText.GetLocalizedName: string;
 
begin
 
begin
   Result:='Text';
+
   Result:='My Text'; // replace this with a resourcestring
 
end;
 
end;
  
 
function TFileDescText.GetLocalizedDescription: string;
 
function TFileDescText.GetLocalizedDescription: string;
 
begin
 
begin
   Result:=lisNewDlgCreateANewEmptyTextFile;
+
   Result:='An empty text file';
end;
+
end;</syntaxhighlight>
</Delphi>
+
 
 +
===Hinzufügen eines neuen Formulartyps===
  
=== Add a new form type ===
+
Diese Beispiel ist aus 'ide/mainintf.pas' und registriert das normale Formular:
  
This example is from the ide/mainintf.pas and registers the normal form:
 
  
<Delphi>
+
<syntaxhighlight lang=pascal>uses ProjectIntf;
uses ProjectIntf;
 
  
 
...
 
...
   TFileDescPascalUnitWithForm = class(TFileDescPascalUnitWithResource)
+
   TFileDescPascalUnitWithMyForm = class(TFileDescPascalUnitWithResource)
 
   public
 
   public
 
     constructor Create; override;
 
     constructor Create; override;
Line 386: Line 471:
 
...
 
...
  
{ TFileDescPascalUnitWithForm }
+
procedure Register;
 +
 
 +
implementation
  
constructor TFileDescPascalUnitWithForm.Create;
+
procedure Register;
 +
begin
 +
  RegisterProjectFileDescriptor(TFileDescPascalUnitWithMyForm.Create,FileDescGroupName);
 +
end;
 +
 
 +
{ TFileDescPascalUnitWithMyForm }
 +
 
 +
constructor TFileDescPascalUnitWithMyForm.Create;
 
begin
 
begin
 
   inherited Create;
 
   inherited Create;
   Name:=FileDescNameLCLForm;
+
   Name:='MyForm'; // do not translate this
   ResourceClass:=TForm;
+
   ResourceClass:=TMyForm;
 
   UseCreateFormStatements:=true;
 
   UseCreateFormStatements:=true;
 
end;
 
end;
  
function TFileDescPascalUnitWithForm.GetInterfaceUsesSection: string;
+
function TFileDescPascalUnitWithMyForm.GetInterfaceUsesSection: string;
 
begin
 
begin
   Result:='Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs';
+
   Result:='Classes, SysUtils, MyWidgetSet';
 
end;
 
end;
  
 
function TFileDescPascalUnitWithForm.GetLocalizedName: string;
 
function TFileDescPascalUnitWithForm.GetLocalizedName: string;
 
begin
 
begin
   Result:='Form';
+
   Result:='MyForm'; // replace this with a resourcestring
 
end;
 
end;
  
 
function TFileDescPascalUnitWithForm.GetLocalizedDescription: string;
 
function TFileDescPascalUnitWithForm.GetLocalizedDescription: string;
 
begin
 
begin
   Result:=lisNewDlgCreateANewUnitWithALCLForm;
+
   Result:='Create a new MyForm from example package NotLCLDesigner';
 +
end;</syntaxhighlight>
 +
 
 +
=Packages=
 +
 
 +
==Suche in allen Packages==
 +
 
 +
Durchsuche alle Packages die in der IDE geladen sind (seit Version 0.9.29):
 +
 
 +
<syntaxhighlight lang=pascal>uses PackageIntf;
 +
...
 +
for i:=0 to PackageEditingInterface.GetPackageCount-1 do
 +
  writeln(PackageEditingInterface.GetPackages(i).Name);</syntaxhighlight>
 +
 
 +
==Suche ein Package mit einem bestimmten Namen==
 +
 
 +
<syntaxhighlight lang=pascal>uses PackageIntf;
 +
...
 +
var
 +
  Pkg: TIDEPackage;
 +
begin
 +
  Pkg:=PackageEditingInterface.FindPackageWithName('LCL');
 +
  if Pkg<>nil then
 +
    ...
 +
end;</syntaxhighlight>
 +
 
 +
Anmerkung: 'FindPackageWithName' öffnet nicht den Package-Editor. Benutzen Sie dazu 'DoOpenPackageWithName'.
 +
 
 +
==Installieren von Packages==
 +
 
 +
'''Anmerkung''': Installieren Sie nur Packages mit IDE-Plugins. Andere Packages zu installieren, kann die IDE instabil machen.
 +
 
 +
<syntaxhighlight lang=pascal>
 +
uses PackageIntf, contnrs;
 +
 
 +
  PkgList:=TObjectList.create(true);
 +
  try
 +
    Pkg:=TLazPackageID.Create;
 +
    Pkg.Name:='Cody';
 +
    PkgList.Add(Pkg);
 +
    // überprüft, ob die IDE die Datei 'cody.lpk' und alle Abhängigkeiten finden kann
 +
    // Die IDE gibt einige Warnungen/Bestätigungen aus, falls ihr irgendetwas seltsam vorkommt.
 +
    if not PackageEditingInterface.CheckInstallPackageList(PkgList,[]) then
 +
      exit;
 +
    // in diesem Beispiel haben wir bereits überprüft, deshalb Warnungen überspringen
 +
    // und die IDE neu erstellen
 +
    if PackageEditingInterface.InstallPackages(PkgList,[piiifSkipChecks,piiifRebuildIDE])<>mrOK then
 +
      exit;
 +
  finally
 +
    PkgList.Free;
 +
  end;
 +
</syntaxhighlight>
 +
 
 +
=Fenster=
 +
 
 +
Grundsätzlich gibt es vier Typen von IDE Fenstern:
 +
 
 +
*die IDE Hauptleiste ist in Application.MainForm. Sie ist immer präsent.
 +
*schwebende/andockbare Fenster (wie die Quelltext-Editoren, der Objektinspektor und die Meldungen)
 +
*die modalen Formulare, wie der Suchen-Dialog, Einstellungen-Dialog und Rückfragen.
 +
*Hints und Vervollständigungs-Formulare
 +
 
 +
==Hinzufügen eines neuen andockbaren IDE-Fensters==
 +
 
 +
Was ist ein andockbares IDE-Fenster:
 +
Fenster wie der Quelltext-Editor oder der Objektinspektor sind schwebende Fenster, die angedockt werden können, wenn das Package 'docking' installiert ist. Sein Status, seine Position und Größe werden gespeichert und beim nächsten Start der IDE wieder abgerufen. Um ein Fenster wiederherstellen zu können, braucht die IDE einen Creator wie er in der Unit '''IDEWindowIntf''' des Packages 'IDEIntf' definiert ist. Jedes andockbare Fenster benötigt einen einzigartigen Namen. Verwenden Sie keine allgemeinen Namen wie 'FileBrowser' weil dies sehr leicht zu Konflikten mit anderen Packages führen kann. Und verwenden Sie keine Kurznamen wie 'XYZ', weil der Creator verantwortlich ist für alle Formulare, die mit diesem Namen beginnen.
 +
 
 +
===Wie registriert man ein andockbares IDE-Fenster===
 +
 
 +
Vergessen Sie nicht, einen langen, uniquen Namen zu verwenden, der ein gültiger Pascal-Bezeichner ist. Ihr Fenster kann einen beliebigen Titel haben.
 +
 
 +
<syntaxhighlight lang=pascal>uses SysUtils, IDEWindowIntf;
 +
...
 +
var MyIDEWindow: TMyIDEWindow = nil;
 +
 
 +
procedure CreateMyIDEWindow(Sender: TObject; aFormName: string; var AForm: TCustomForm; DoDisableAutoSizing: boolean);
 +
begin
 +
  // check the name
 +
  if CompareText(aFormName,MyIDEWindowName)<>0 then exit;
 +
  // create the form if not already done and disable autosizing
 +
  IDEWindowCreators.CreateForm(MyIDEWindow,TMyIDEWindowm,DoDisableAutosizing,Application);
 +
  ... init the window ...
 +
  AForm:=MyIDEWindow;
 
end;
 
end;
</Delphi>
 
  
== CodeTools in der IDE ==
+
procedure Register;
 +
begin
 +
  IDEWindowCreators.Add('MyIDEWindow',@CreateMyIDEWindow,nil,'100','50%','+300','+20%');
 +
  // the default boundsrect of the form is:
 +
  // Left=100, Top=50% of Screen.Height, Width=300, Height=20% of Screen.Height
 +
  // when the IDE needs an instance of this window it calls the procedure CreateMyIDEWindow.
 +
end;</syntaxhighlight>
 +
 
 +
===Anzeigen eines IDE-Fensters===
  
Before using the codetools you should commit the current changes of the source editor to the codetool buffers:
+
'''Benutzen Sie nicht Show'''. Nehmen Sie stattdessen:
  
<Delphi>
+
<syntaxhighlight lang=pascal>IDEWindowCreators.ShowForm(MyIDEWindow,false);</syntaxhighlight>
 +
 
 +
Das wird auch mit Docking funktionieren. Das Docking-System wird das Formular in eine Docking-Site einschließen. Der Parameter 'BringToFront' befiehlt dem Docking-System, dieses Formular und all seine Eltern-Sites sichtbar zu machen und die Site der obersten Ebene in den Vordergrund zu bringen.
 +
 
 +
===Anmerkungen über IDEWindowCreators und SimpleLayoutStorage===
 +
 
 +
Das IDEWindowCreators.SimpleLayoutStorage speichert einfach das BoundsRect und den WindowState von allen Formularen, die einmal geöffnet wurden. Es stellt ein Fallback dar, falls kein Dockmaster installiert ist. Es speichert des Zustand sogar wenn ein DockMaster installiert ist, sodass auch beim Deinstallieren des Dockmasters die Formulargrößen wiederhergestellt werden können.
 +
 
 +
Die IDEWindowCreators werden bei allen andockbaren Formularen eingesetzt, um sich selbst zu registrieren und die Formulare anzuzeigen. Beim Anzeigen eines Formulars überprüft der Creator ob ein IDEDockMaster installiert ist und überträgt ihm die Aufgabe des Anzeigens. Ist kein IDEDockMaster installiert wird das Formular einfach angezeigt. Der IDEDockMaster kann die Informationen in den IDEWindowCreators benutzen, um benannte Formulare zu erzeugen und um festzustellen, wo ein Formular beim ersten Anzeigen zu platzieren ist. Für weitere Details siehe die Packages '''AnchorDockingDsgn''' und '''EasyDockMgDsgn'''.
 +
 
 +
=CodeTools in der IDE=
 +
 
 +
Die CodeTools sind ein Package das eine große Anzahl von Funktionen zum Parsen, Untersuchen und Ändern von Pascal-Quelltexten zur Verfügung stellt, daneben auch einige grundlegende Funktionen für andere Sprachen. Sie können sie auch ohne die IDE einsetzen. Es wird empfohlen, dass Sie zuerst über die CodeTools im Allgemeinen nachlesen, bevor Sie sie in der IDE benutzen: [[Codetools/de|CodeTools (deutsch)]].
 +
 
 +
Bevor Sie irgendeine der Codetools-Funktionen in der IDE aufrufen, sollten Sie die letzten Änderungen im Quelltexteditor in den Codetools-Puffern speichern:
 +
 
 +
<syntaxhighlight lang=pascal>
 
uses LazIDEIntf;
 
uses LazIDEIntf;
 
...
 
...
 
   // save changes in source editor to codetools
 
   // save changes in source editor to codetools
 
   LazarusIDE.SaveSourceEditorChangesToCodeCache(-1); // -1: commit all source editors
 
   LazarusIDE.SaveSourceEditorChangesToCodeCache(-1); // -1: commit all source editors
</Delphi>
+
</syntaxhighlight>
  
== Hinzufügen einer resource Direktive zu einer Datei ==
+
==Hinzufügen einer resource Direktive zu einer Datei==
  
 
Dies fügt eine {$R example.res} Direktive zu einer Pascal Unit hinzu:
 
Dies fügt eine {$R example.res} Direktive zu einer Pascal Unit hinzu:
  
<Delphi>
+
<syntaxhighlight lang=pascal>
 
procedure AddResourceDirectiveToPascalSource(const Filename: string);
 
procedure AddResourceDirectiveToPascalSource(const Filename: string);
 
var
 
var
Line 446: Line 645:
 
     LazarusIDE.DoJumpToCodeToolBossError;
 
     LazarusIDE.DoJumpToCodeToolBossError;
 
end;
 
end;
</Delphi>
+
</syntaxhighlight>
  
The codetools provides also functions like FindResourceDirective and RemoveDirective.
+
Die Codetools stellen auch Funktionen wie FindResourceDirective und RemoveDirective zur Verfügung.
  
 +
==Die Suchpfade für Units und Include-Dateien ermitteln==
  
  Adding your handler (this is normally done in the constructor of your object):
+
In der IDE gibt es viele unterschiedliche Suchpfade von Projekten, Packages, dem FPC und Lazarus Verzeichnis und es gibt viele Arten von Pfaden: vor und nach dem Auflösen von Makros, mit oder ohne geerbte Suchpfade, als relative oder absolute Pfade. Alle Dateien in einem Verzeichnis teilen sich den selben Bestand an Suchpfaden. Sie erhalten die Suchpfade für jedes Verzeichnis voll aufgelöst durch eine Abfrage der Codetools:
    GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);<br> 
+
 
  Removing your handler:
+
<syntaxhighlight lang=pascal>
    GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);<br>
+
uses CodeToolManager;
  You can remove all handlers at once. For example, it is a good idea to add
+
...
  this line in the destructor of object:
+
 
    GlobalDesignHook.RemoveAllHandlersForObject(Self);
+
Dir:=''; // das leere Verzeichnis ist für neue Dateien und hat die selben Einstellungen wie das Projektverzeichnis
 +
 
 +
// ermittelt die Suchpfade für Include-Dateien:
 +
Path:=CodeToolBoss.GetIncludePathForDirectory(Dir);
 +
 
 +
// ermittelt die Suchpfade für Units:
 +
// Dieser Suchpfad wird an den Compiler übergeben.
 +
// Er enthält die Package-Ausgabe-Verzeichnisse, aber nicht die Package-Quell-Verzeichnisse.
 +
Path:=CodeToolBoss.GetUnitPathForDirectory(Dir);
 +
 
 +
// zusätzliche Unit-Suchpfade nur für die IDE können auftreten (werden nicht an den Compiler übergeben)
 +
Path:=CodeToolBoss.GetSrcPathForDirectory(Dir);
 +
 
 +
// der vollständige Suchpfad enthält auch alle Package-Quell-Pfade für Units:
 +
Path:=CodeToolBoss.GetCompleteSrcPathForDirectory(Dir);
 +
</syntaxhighlight>
 +
 
 +
=Quelltext-Editor=
 +
 
 +
==Aktiver Quelltext-Editor==
 +
 
 +
<syntaxhighlight lang=pascal>
 +
uses SrcEditorIntf;
 +
...
 +
Editor:=SourceEditorManagerIntf.ActiveEditor;
 +
if Editor=nil then exit;
 +
Filename:=Editor.FileName;
 +
ScreenPos:=Editor.CursorScreenXY;
 +
TextPos:=Editor.CursorTextXY;
 +
</syntaxhighlight>
 +
 
 +
=SynEdit=
 +
 
 +
==Die Einstellungen für einen TSynEdit holen==
 +
 
 +
Wenn Sie einen TSynEdit in einem Dialog haben und Sie wollen die selbe Schriftart und die selben Einstellungen wie im Quelltext-Editor verwenden::
 +
 
 +
<syntaxhighlight lang=pascal>
 +
uses SrcEditorIntf;
 +
...
 +
SourceEditorManagerIntf.GetEditorControlSettings(ASynEdit);
 +
</syntaxhighlight>
 +
 
 +
==Die Einstellungen für einen SynEdit-Highlighter holen==
 +
 
 +
Wenn Sie einen Dialog haben, der einen TSynEdit mit einem Highlighter enthält, können Sie die selben Farben wie der Highlighter des Quelltext-Editors für diese Sprache verwenden:
  
Die Handlers des GlobalDesignHook:
+
<syntaxhighlight lang=pascal>
 +
uses SrcEditorIntf;
 +
...
 +
SourceEditorManagerIntf.GetHighlighterSettings(ASynHighlighter);
 +
</syntaxhighlight>
  
  // lookup root
+
Siehe für ein Beispiel auch: TSQLStringsPropertyEditorDlg.Create in der Unit [http://svn.freepascal.org/svn/lazarus/trunk/components/sqldb/sqlstringspropertyeditordlg.pas SQLStringsPropertyEditorDlg].
  ChangeLookupRoot
 
    Called when the "LookupRoot" changed.
 
    The "LookupRoot" is the owner object of the currently selected components.
 
    Normally this is a TForm.<br>
 
  // Methoden
 
  CreateMethod
 
  GetMethodName
 
  GetMethods
 
  MethodExists
 
  RenameMethod
 
  ShowMethod
 
    Called
 
  MethodFromAncestor
 
  ChainCall<br>
 
  // Komponenten
 
  GetComponent
 
  GetComponentName
 
  GetComponentNames
 
  GetRootClassName
 
  ComponentRenamed
 
    Called when a component was renamed
 
  ComponentAdded
 
    Called when a new component was added to the LookupRoot
 
  ComponentDeleting
 
    Called before a component is freed.
 
  DeleteComponent
 
    Called by the IDE to delete a component.
 
  GetSelectedComponents
 
    Get the current selection of components.<br>
 
  // persistente Objekte
 
  GetObject
 
  GetObjectName
 
  GetObjectNames<br>
 
  // modifing
 
  Modified
 
  Revert
 
  RefreshPropertyValues
 
  
== Hilfe ==
+
=Hilfe=
  
=== Hilfe für die Quellen hinzufügen ===
+
==Hilfe für die Quellen hinzufügen==
  
 
Erzeugen sie zuerst eine THelpDatabase:
 
Erzeugen sie zuerst eine THelpDatabase:
<delphi>
+
<syntaxhighlight lang=pascal>HelpDB := TFPDocHTMLHelpDatabase(
  HelpDB:=TFPDocHTMLHelpDatabase(
+
  HelpDatabases.CreateHelpDatabase('EinNameIhrerWahlFürDieDatenbank',
    HelpDatabases.CreateHelpDatabase('EinNameIhrerWahlFürDieDatenbank',
+
                                    TFPDocHTMLHelpDatabase,true));
                                            TFPDocHTMLHelpDatabase,true));
+
   HelpDB.DefaultBaseURL := 'http://ihre.hilfe.org/';
   HelpDB.DefaultBaseURL:='http://ihre.hilfe.org/';
 
  
   FPDocNode:=THelpNode.CreateURL(HelpDB,
+
   FPDocNode := THelpNode.CreateURL(HelpDB,
                  'Package1 - A new package',
+
                                  'Package1 - A new package',
                  'file://index.html');
+
                                  'file://index.html');
   HelpDB.TOCNode:=THelpNode.Create(HelpDB,FPDocNode);// einmal als Inhaltsverzeichnis
+
   HelpDB.TOCNode := THelpNode.Create(HelpDB,FPDocNode);// einmal als Inhaltsverzeichnis
   DirectoryItem:=THelpDBISourceDirectory.Create(FPDocNode,'$(PkgDir)/lcl',
+
   DirectoryItem := THelpDBISourceDirectory.Create(FPDocNode,'$(PkgDir)/lcl',
                                  '*.pp;*.pas',false);// und einmal als normale Seite
+
                                  '*.pp;*.pas',false);// und einmal als normale Seite
   HelpDB.RegisterItem(DirectoryItem);
+
   HelpDB.RegisterItem(DirectoryItem);</syntaxhighlight>
</delphi>
 
  
=== Zeilen zum Nachrichtenfenster hinzufügen ===
+
==Zeilen zum Nachrichtenfenster hinzufügen==
  
<Delphi>
+
<syntaxhighlight lang=pascal>
 
unit IDEMsgIntf;
 
unit IDEMsgIntf;
 
...
 
...
Line 532: Line 742:
 
   IDEMessagesWindow.EndBlock;
 
   IDEMessagesWindow.EndBlock;
 
end;
 
end;
</Delphi>
+
</syntaxhighlight>
 +
 
 +
==Überblick über die verschiedenen Elemente der Hilfe==
 +
 
 +
[[Creating IDE Help/de|Hilfe für die IDE erzeugen]]

Latest revision as of 22:22, 14 February 2020

Deutsch (de) English (en) español (es) français (fr) 日本語 (ja) русский (ru) slovenčina (sk) 中文(中国大陆)‎ (zh_CN)

Erweitern der IDE

Überblick

Die IDE unterstützt verschiedene Erweiterungen:

Komponenten
Komponenten werden in der Palette installiert. Z.B. TButton erzeugt Buttons.
Komponenten-Editoren
Komponenteneditoren werden benutzt, wenn Sie auf eine Komponente im Designer doppelklicken oder um einige extra Items im Popupmenü des Designers hinzuzufügen, indem man auf eine Komponente rechtsklickt.
Eigenschafts-Editoren
Stellen die Editierfähigkeiten im Objektinspektor zur Verfügung.
Experten
Das sind alle anderen Typen von Editoren. Sie registrieren neue Menüpunkte, Tastenkürzel oder erweitern andere Merkmale der IDE.


Es gibt 2 Möglichkeiten, Ihre eigenen Plugins in Lazarus zu integrieren:

  1. Erstellen Sie ein Package, installieren Sie es und registrieren Sie das Plugin mit der Prozedur 'Register' in einer Unit.
  2. Erweitern Sie den Lazarus Code und senden Sie Ihr SVN diff an die Lazarus-Mailing-Liste.

Menüpunkte

Sie können neue Menüpunkte anfügen, bestehende Menüpunkte verstecken oder verschieben und Untermenüs oder Abschnitte hinzufügen. Für Ihre eigenen Formulare können Sie das TMainMenu/TPopupMenu registrieren, sodass andere Packages darauf zugreifen und Ihr Formular erweitern können. Die Unit MenuIntf des IDEIntf-Packages enthält die gesamte Registrierung für Menüs und viele Standard-Menüpunkte der IDE selbst.

Einen Menüpunkt hinzufügen

Ein einzelner Menüpunkt wie 'View Object Inspector' wird TIDEMenuCommand genannt. Sie können einen erzeugen mit dem Befehl RegisterIDEMenuCommand, der in zwei Formen mit Unmengen von Parametern vorkommen kann:

function RegisterIDEMenuCommand(Parent: TIDEMenuSection;
                                const Name, Caption: string;
                                const OnClickMethod: TNotifyEvent = nil;
                                const OnClickProc: TNotifyProcedure = nil;
                                const Command: TIDECommand = nil;
                                const ResourceName: String = ''
                                ): TIDEMenuCommand; overload;
function RegisterIDEMenuCommand(const Path, Name, Caption: string;
                                const OnClickMethod: TNotifyEvent = nil;
                                const OnClickProc: TNotifyProcedure = nil;
                                const Command: TIDECommand = nil;
                                const ResourceName: String = ''
                                ): TIDEMenuCommand; overload;

Der Unterschied zwischen diesen beiden Formen liegt nur darin, wie Sie die 'parent menu section' angeben. Geben Sie diesen Menüabschnitt direkt an oder oder indirekt mittels eines Pfades. Viele Standardmenüs finden Sie in der Unit MenuIntf. Zum Beispiel den Abschnitt mnuTools, der das Menü Tools aus dem IDE-Hauptmenü liefert. Es enthält einen Abschnitt itmSecondaryTools, das ist der empfohlene Abschnitt für "Third party tools".

Das folgende Beispiel registriert einen neuen Menübefehl mit dem Namen 'MyTool', der Beschriftung 'Start my tool' und führt beim Klicken die Prozedur StartMyTool aus:

procedure StartMyTool;
begin
  ...wird ausgeführt, wenn der Menüpunkt angeklickt wird...
end;

procedure Register;
begin
  RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool','Start my tool',nil,@StartMyTool);
end;

Falls Sie statt der Prozedur eine Methode aufrufen wollen, dann verwenden Sie den OnClickMethod Parameter.

Dieser Menüpunkt hat kein Tastenkürzel. Wenn Sie ein Tastenkürzel brauchen, dann erzeugen Sie einen TIDECommand und übergeben das Kürzel im Command Parameter. Zum Beispiel:

uses ... IDECommands, MenuIntf;
...
var
  Key: TIDEShortCut;
  Cat: TIDECommandCategory;
  CmdMyTool: TIDECommand;
begin
  // register IDE shortcut and menu item
  Key := IDEShortCut(VK_UNKNOWN,[],VK_UNKNOWN,[]);
  Cat := IDECommandList.FindCategoryByName(CommandCategoryToolMenuName);
  CmdMyTool := RegisterIDECommand(Cat,'Start my tool', 'Starts my tool to do some stuff', Key, nil, @StartMyTool);
  RegisterIDEMenuCommand(itmSecondaryTools, 'MyTool', 'Start my tool', nil, nil, CmdMyTool);
end;

Konfigurationsdateien

Laden/Speichern von Einstellungen

Alle Konfigurationsdateien der IDE werden in einem einzigen Verzeichnis als xml-Dateien gespeichert. Auch Packages können dort ihre eigenen Dateien ablegen. Das primäre Konfigurationsverzeichnis kann ermittelt werden mit:

uses LazIDEIntf;
...
  Directory := LazarusIDE.GetPrimaryConfigPath;

Packages erzeugen ihre eigenen xml-Dateien mit:

uses
  ..., LCLProc, BaseIDEIntf, LazConfigStorage;

const
  Version = 1;
var
  Config: TConfigStorage;
  SomeValue: String;
  SomeInteger: Integer;
  SomeBoolean: Boolean;
  FileVersion: LongInt;
begin
  SomeValue:='Default';
  SomeInteger:=3;
  SomeBoolean:=true;

  // speichere die Einstellungen
  try
    Config:=GetIDEConfigStorage('mysettings.xml',false);
    try
      // store the version number so future extensions can handle old config files
      Config.SetDeleteValue('Path/To/The/Version',Version,0);
      // store string variable "SomeValue"
      // if SomeValue has the default value the entry is not stored,
      // so only the differences to the default are stored.
      // This way the xml is kept short and defaults may change in future.
      Config.SetDeleteValue('Path/To/Some/Value',SomeValue,'Default');
      Config.SetDeleteValue('Path/To/Some/Integer',SomeInteger,3);
      Config.SetDeleteValue('Path/To/Some/Boolean',SomeBoolean,true);
      // there are more overloads for SetDeleteValue, find out with Ctrl+Space
    finally
      Config.Free;
    end;

  except
    on E: Exception do begin
      DebugLn(['Saving mysettings.xml failed: ',E.Message]);
    end;
  end;

  // lade die Einstellungen
  try
    Config:=GetIDEConfigStorage('mysettings.xml',true);
    try
      // read the version of the config
      FileVersion:=Config.GetValue('Path/To/The/Version',0);
      // read a string variable "SomeValue". If the entry does not exist, use
      // the Default
      SomeValue:=Config.GetValue('Path/To/Some/Value','Default');
      SomeInteger:=Config.GetValue('Path/To/Some/Integer',3);
      SomeBoolean:=Config.GetValue('Path/To/Some/Boolean',true);
    finally
      Config.Free;
    end;
  except
    on E: Exception do begin
      DebugLn(['Loading mysettings.xml failed: ',E.Message]);
    end;
  end;
end;

Komponenten

Komponenten schreiben

Sie können mit dem Lazarus Package-Editor eine neue, eigene Komponente erstellen. Sie erreichen den Editor über die Menüführung "Datei --> Neu --> Package, Standard Package". Es öffnet sich ein Fenster mit dem Datei- und Komponentenbaum Ihres Packages. Über die dort angezeigten Schaltflächen können Sie Ihr Package einrichten:

  • Speichern: Hier können Sie Ihre Komponente oder Ihr Package unter einen Namen Ihrer Wahl speichern.
  • Hinzufügen: Hier erscheint ein Fenster mit mehreren Tabs. Die wichtisten im Überblick: Im Tab Neue Datei können Sie zum Beispiel Units und Formulardateien für Ihr Projekt erstellen. Eine bereits vorhandene Unit können Sie im Reiter Neue Unit einbinden. Wenn Sie Ihre Komponente auf eine bereits existierende Komponente aufbauen wollen, können Sie diese im Tab Neue Komponente auswählen.
  • Einstellungen: In diesem Dialog können Sie neben der Beschreibung Ihrer Komponente und ihrer Versionierung auch den Package-Typ einstellen sowie Sprachregelungen treffen.
  • Installieren: Wenn Ihre Komponente fertig erstellt ist, können Sie sie über diesen Knopf in die IDE einbinden.
  • Compilereinstellungen: Hier lässt sich festlegen, mit welchen Optionen und Compiler-Argumenten Ihr Package kompiliert werden soll.

Hinweis: Detailierte Informationen zum Package-Editor finden Sie hier.

Beispiel: Eine von TButton abgeleitete Komponente erstellen:

  1. Öffnen Sie den Package-Editor wie oben geschrieben
  2. Klicken Sie auf "Hinzufügen --> Neue Komponente"
  3. Wählen Sie als Basisklasse "TButton", und füllen die Felder wie folgt aus: Neuer Klassenname: TMeinButton, Palettenseite: Misc, Unit Dateiname: meinbutton.pas (diese Datei wird erstellt), Unit Name: MeinButton
  4. Klicken Sie auf Ok - und schon können Sie in der Unit meinbutton.pas den TButton an Ihre Bedürfnisse anpassen.

Einer neuen Komponente ein Icon für die Komponentenpalette geben

Zum Beispiel wollen wir TMyButton ein Icon geben. Erzeugen sie eine Bilddatei im Format .bmp, .xpm oder .png mit dem selben Namen wie die Komponentenklasse, z.B. tmybutton.png und speichern sie diese im Package-Quelltextverzeichnis. Das Bild kann mit einem beliebigen Grafikprogramm (z.B. Gimp) erzeugt werden und sollte nicht größer sein als 24x24 Pixel. Konvertieren Sie das Bild in eine .lrs Datei mit dem 'lazres' Werkzeug, das Sie im Verzeichnis 'lazarus/tools' finden:

 ~/lazarus/tools/lazres mybutton.lrs tmybutton.png

Das erzeugt eine Pascal Include Datei, die im Initialisierungs-Abschnitt von mybutton.pas verwendet wird:

 initialization
   {$I mybutton.lrs}

Installieren Sie das Package.

Eine Komponente aus der Palette verstecken

Package IDEIntf, unit componentreg:

IDEComponentPalette.FindComponent('TButton').Visible:=false;

Komponenten-Editoren schreiben

Ein Komponenten-Editor verarbeitet Dinge wie einen Doppelklick auf eine Komponente im Designer oder das Hinzufügen von Menüpunkten bei einem Rechtsklick auf eine Komponente. Einen Komponenten-Editor zu schreiben ist einfach. Siehe die Unit componenteditors.pas vom Package IDEIntf für zahlreiche Beispiele. Um beispielweise beim Doppelklick einen Editor anzuzeigen, siehe: TCheckListBoxComponentEditor.

Eigenschafts-Editoren schreiben

Jeder Eigenschaftstyp (integer, string, TFont, ...) im Objektinspektor benötigt einen Eigenschafts-Editor. Wenn Ihre Komponente eine Eigenschaft 'Password' vom Typ string hat, können Sie einen Eigenschafts-Editor definieren für Ihre besondere Komponenten-Klasse, mit genau diesem Typ. Die Unit propedits.pp aus dem Package IDEIntf enthält viele der Standard-Eigenschafts-Editoren, die von der IDE selbst verwendet werden. Zum Beispiel ist der TStringPropertyEditor der vorgegebene Editor für alle Strings, während TComponentNamePropertyEditor spezieller ist und nur TComponent.Name bearbeitet.

Designer

Einen Designer-Mediator schreiben

Der Standard-Designer erlaubt es, die Steuerelemente der LCL visuell zu bearbeiten, wo hingegen alle anderen nur als Symbole angezeigt werden. Um Steuerelemente (die nicht aus der LCL stammen) ebenfalls visuell bearbeiten zu können, sollten Sie einen Designer-Mediator erzeugen. Dieser kann dazu verwendet werden, Webseiten zu entwerfen, UML Diagramme oder andere Widgetsets wie fpGUI. Es gibt ein ausführliches Beispiel unter: in examples/designnonlcl/.

  • Installieren Sie das Beispielspackage examples/designnonlcl/notlcldesigner.lpk und starten Sie die IDE neu. Dadurch werden der Designer-Mediator für TMyWidget-Komponenten registriert und die neuen Komponenten TMyButton, TMyGroupBox zur Komponentenpalette hinzugefügt.
  • Öffnen Sie das Beispielsprojekt examples/designnonlcl/project/NonLCL1.lpi.
  • Öffnen Sie die unit1.pas und zeigen Sie das Formular im Designer an (mit F12). Sie sollten jetzt die Komponenten als rote Rechtecke dargestellt sehen, die Sie genau so wie LCL-Steuerelemente auswählen, verschieben oder in der Größe verändern können.

Einen neuen einzigartigen Komponentennamen erzeugen

uses FormEditingIntf;

...

NewName:=FormEditingHook.CreateUniqueComponentName(AComponent);

// Or if you need to create the name before creating the component:

NewName:=FormEditingHook.CreateUniqueComponentName(ComponentClassName,OwnerComponent);
// ComponentClassName will be used as prefix, without a leading T.
// OwnerComponent is the new owner of the new component.

Eine Komponente im Designer/Objektinspektor auswählen

uses propedits;
..
GlobalDesignHook.SelectOnlyThis(AComponent);

Ereignis-Handler

Es gibt einige Ereignisse in der IDE, für die Plugins ihre eigenen Handler hinzufügen können.

Designerereignisse

In propedits.pp gibt es ein "GlobalDesignHook" Objekt, das verschiedene Ereignisse zum Entwurf verwaltet. Jedes Ereignis ruft eine List von Handlern auf. Die Vorgabe-Handler werden von der IDE angefügt. Sie können eigene Handler mit den Methoden AddHandlerXXX und RemoveHandlerXXX anfügen. Diese werden aufgerufen vor den Vorgabe-Handlern.

Beispiele:

 Einfügen Ihres Handlers (das geschieht normalerweise im Konstruktor Ihres Objekts):
   GlobalDesignHook.AddHandlerComponentAdded(@YourOnComponentAdded);
Entfernen Ihrer Handlers: GlobalDesignHook.RemoveHandlerComponentAdded(@YourOnComponentAdded);
Sie können alle Handler auf einmal entfernen. Zum Beispiel, ist es eine gute Idee, diese Zeile im Destruktor des Objekts anzufügen: GlobalDesignHook.RemoveAllHandlersForObject(Self);

Die Handler von GlobalDesignHook:

 // lookup root
 ChangeLookupRoot
   Called when the "LookupRoot" changed.
   The "LookupRoot" is the owner object of the currently selected components.
   Normally this is a TForm.
// methods CreateMethod GetMethodName GetMethods MethodExists RenameMethod ShowMethod Called MethodFromAncestor ChainCall
// components GetComponent GetComponentName GetComponentNames GetRootClassName ComponentRenamed Called when a component was renamed ComponentAdded Called when a new component was added to the LookupRoot ComponentDeleting Called before a component is freed. DeleteComponent Called by the IDE to delete a component. GetSelectedComponents Get the current selection of components.
// persistent objects GetObject GetObjectName GetObjectNames
// modifing Modified Revert RefreshPropertyValues

Benachrichtigt werden, wenn ein Formular im Designer modifiziert wurde

Jedes LCL-Formular hat einen Designer des Typs TIDesigner. Die IDE erzeugt Designer der Type TComponentEditorDesigner, die in der IDEIntf Unit componenteditors definiert ist. Ein Beispiel:

procedure TYourAddOn.OnDesignerModified(Sender: TObject);
var
  IDEDesigner: TComponentEditorDesigner;
begin
  IDEDesigner:=TComponentEditorDesigner(Sender);
  ...
end;

procedure TYourAddOn.ConnectDesignerForm(Form1: TCustomForm);
var
  IDEDesigner: TComponentEditorDesigner;
begin
  IDEDesigner:=TComponentEditorDesigner(Form1.Designer);
  IDEDesigner.AddHandlerModified(@OnDesignerModified);
end;

Projektereignisse

Diese Ereignisse sind definiert in der Unit LazIDEIntf.


  • LazarusIDE.AddHandlerOnProjectClose: wird aufgerufen bevor ein Projekt geschlossen wird
  • LazarusIDE.AddHandlerOnProjectOpened: wird aufgerufen nachdem das Projekt vollständig geöffnet wurde (wenn beispielsweise alle erforderlichen Packages geladen und die Units im Quelltext-Editor geöffnet wurden)
  • LazarusIDE.AddHandlerOnSavingAll: wird aufgerufen bevor die IDE alles speichert
  • LazarusIDE.AddHandlerOnSavedAll: wird aufgerufen nachdem die IDE alles gespeichert hat
  • LazarusIDE.AddHandlerOnProjectBuilding: wird aufgerufen bevor die IDE das Projekt erstellt
  • LazarusIDE.AddHandlerOnProjectDependenciesCompiling: wird aufgerufen bevor die IDE die Packageabhängigkeiten eines Projekts kompiliert
  • LazarusIDE.AddHandlerOnProjectDependenciesCompiled: wird aufgerufen nachdem die IDE die Packageabhängigkeiten eines Projekts kompiliert hat

Andere IDE Ereignisse

  • LazarusIDE.AddHandlerOnIDERestoreWindows: wird aufgerufen, wenn die IDE ihre Fernster wiederherstellt (bevor das erste Projekt geöffnet wird)
  • LazarusIDE.AddHandlerOnIDEClose: wird aufgerufen, wenn die IDE beendet wird (nach closequery, also keine Interaktivität mehr)
  • LazarusIDE.AddHandlerOnQuickSyntaxCheck: wird aufgerufen, wenn der Menüpunkt oder das Tastenkürzel für die Schnelle Syntaxüberprüfung aussgeführt wird

Projekt

Aktuelles Projekt

Das aktuelle Hauptprojekt erhalten Sie mit LazarusIDE.ActiveProject. (unit LazIDEIntf)

Alle Units des aktuellen Projekts

Um alle Pascal-Units des aktuellen Hauptprojektes der IDE zu durchlaufen benutzen Sie zum Beispiel:

uses LCLProc, FileUtil, LazIDEIntf, ProjectIntf;

procedure ListProjectUnits;
var
  LazProject: TLazProject;
  i: Integer;
  LazFile: TLazProjectFile;
begin
  LazProject:=LazarusIDE.ActiveProject;
  if LazProject<>nil then
    for i:=0 to LazProject.FileCount-1 do
    begin
      LazFile:=LazProject.Files[i];
      if LazFile.IsPartOfProject
      and FilenameIsPascalUnit(LazFile.Filename)
      then
        debugln(LazFile.Filename);
    end;
end;

Die .lpr, .lpi und .lps Datei eines Projekts

uses LCLProc, FileUtil, ProjectIntf, LazIDEIntf;
var
  LazProject: TLazProject;
begin
  LazProject:=LazarusIDE.ActiveProject;
  // jedes Projekt hat eine .lpi Datei:
  DebugLn(['Project'' lpi file: ',LazProject.ProjectInfoFile]);

  // if the project session information is stored in a separate .lps file:
  if LazProject.SessionStorage<>pssNone then
    DebugLn(['Project'' lps file: ',LazProject.ProjectSessionFile]);

  // If the project has a .lpr file it is the main source file:
  if (LazProject.MainFile<>nil)
  and (CompareFileExt(LazProject.MainFile.Filename,'lpr')=0) then
    DebugLn(['Project has lpr file: ',LazProject.MainFile.Filename]);
end;

Der Name der ausführbaren Ziel-Datei eines Projekts

Es gibt ein Makro $(TargetFile), das in Pfaden und externen Werkzeugen verwendet werden kann. Beispiel:

uses MacroIntf;

function MyGetProjectTargetFile: string;
begin
  Result:='$(TargetFile)';
  if not IDEMacros.SubstituteMacros(Result) then
    raise Exception.Create('unable to retrieve target file of project');
end;

Für weitere Makros siehe: IDE Makros in Pfaden und Dateinamen.

Hinzufügen Ihres eigenen Projekttyps

Sie können Menüpunkte zum Dialog 'Neu ...' hinzufügen:

Hinzufügen Ihres eigenen Dateityps

Sie können Einträge hinzufügen zum Dialog 'Neu ...':

  • Siehe die Unit ProjectIntf aus dem Package IDEIntf.
  • Wählen Sie eine Basisklasse TFileDescPascalUnit für normale Units oder TFileDescPascalUnitWithResource für ein neues Formular/Datenmodul.

Hinzufügen eines neuen Dateityps

Dieses Beispiel entstammt der ide/mainintf.pas Datei und registriert eine einfache Textdatei:


uses ProjectIntf;
...
  { TFileDescText }

  TFileDescMyText = class(TProjectFileDescriptor)
  public
    constructor Create; override;
    function GetLocalizedName: string; override;
    function GetLocalizedDescription: string; override;
  end;
...

procedure Register;

implementation

procedure Register;
begin
  RegisterProjectFileDescriptor(TFileDescMyText.Create,FileDescGroupName);
end;

{ TFileDescMyText }

constructor TFileDescMyText.Create;
begin
  inherited Create;
  Name:='MyText'; // do not translate this
  DefaultFilename:='text.txt';
  AddToProject:=false;
end;

function TFileDescText.GetLocalizedName: string;
begin
  Result:='My Text'; // replace this with a resourcestring
end;

function TFileDescText.GetLocalizedDescription: string;
begin
  Result:='An empty text file';
end;

Hinzufügen eines neuen Formulartyps

Diese Beispiel ist aus 'ide/mainintf.pas' und registriert das normale Formular:


uses ProjectIntf;

...
  TFileDescPascalUnitWithMyForm = class(TFileDescPascalUnitWithResource)
  public
    constructor Create; override;
    function GetInterfaceUsesSection: string; override;
    function GetLocalizedName: string; override;
    function GetLocalizedDescription: string; override;
  end;
...

procedure Register;

implementation

procedure Register;
begin
  RegisterProjectFileDescriptor(TFileDescPascalUnitWithMyForm.Create,FileDescGroupName);
end;

{ TFileDescPascalUnitWithMyForm }

constructor TFileDescPascalUnitWithMyForm.Create;
begin
  inherited Create;
  Name:='MyForm'; // do not translate this
  ResourceClass:=TMyForm;
  UseCreateFormStatements:=true;
end;

function TFileDescPascalUnitWithMyForm.GetInterfaceUsesSection: string;
begin
  Result:='Classes, SysUtils, MyWidgetSet';
end;

function TFileDescPascalUnitWithForm.GetLocalizedName: string;
begin
  Result:='MyForm'; // replace this with a resourcestring
end;

function TFileDescPascalUnitWithForm.GetLocalizedDescription: string;
begin
  Result:='Create a new MyForm from example package NotLCLDesigner';
end;

Packages

Suche in allen Packages

Durchsuche alle Packages die in der IDE geladen sind (seit Version 0.9.29):

uses PackageIntf;
...
for i:=0 to PackageEditingInterface.GetPackageCount-1 do
  writeln(PackageEditingInterface.GetPackages(i).Name);

Suche ein Package mit einem bestimmten Namen

uses PackageIntf;
...
var
  Pkg: TIDEPackage;
begin
  Pkg:=PackageEditingInterface.FindPackageWithName('LCL');
  if Pkg<>nil then 
    ...
end;

Anmerkung: 'FindPackageWithName' öffnet nicht den Package-Editor. Benutzen Sie dazu 'DoOpenPackageWithName'.

Installieren von Packages

Anmerkung: Installieren Sie nur Packages mit IDE-Plugins. Andere Packages zu installieren, kann die IDE instabil machen.

uses PackageIntf, contnrs;

  PkgList:=TObjectList.create(true);
  try
    Pkg:=TLazPackageID.Create;
    Pkg.Name:='Cody';
    PkgList.Add(Pkg);
    // überprüft, ob die IDE die Datei 'cody.lpk' und alle Abhängigkeiten finden kann
    // Die IDE gibt einige Warnungen/Bestätigungen aus, falls ihr irgendetwas seltsam vorkommt.
    if not PackageEditingInterface.CheckInstallPackageList(PkgList,[]) then
      exit;
    // in diesem Beispiel haben wir bereits überprüft, deshalb Warnungen überspringen
    // und die IDE neu erstellen
    if PackageEditingInterface.InstallPackages(PkgList,[piiifSkipChecks,piiifRebuildIDE])<>mrOK then
      exit;
  finally
    PkgList.Free;
  end;

Fenster

Grundsätzlich gibt es vier Typen von IDE Fenstern:

  • die IDE Hauptleiste ist in Application.MainForm. Sie ist immer präsent.
  • schwebende/andockbare Fenster (wie die Quelltext-Editoren, der Objektinspektor und die Meldungen)
  • die modalen Formulare, wie der Suchen-Dialog, Einstellungen-Dialog und Rückfragen.
  • Hints und Vervollständigungs-Formulare

Hinzufügen eines neuen andockbaren IDE-Fensters

Was ist ein andockbares IDE-Fenster: Fenster wie der Quelltext-Editor oder der Objektinspektor sind schwebende Fenster, die angedockt werden können, wenn das Package 'docking' installiert ist. Sein Status, seine Position und Größe werden gespeichert und beim nächsten Start der IDE wieder abgerufen. Um ein Fenster wiederherstellen zu können, braucht die IDE einen Creator wie er in der Unit IDEWindowIntf des Packages 'IDEIntf' definiert ist. Jedes andockbare Fenster benötigt einen einzigartigen Namen. Verwenden Sie keine allgemeinen Namen wie 'FileBrowser' weil dies sehr leicht zu Konflikten mit anderen Packages führen kann. Und verwenden Sie keine Kurznamen wie 'XYZ', weil der Creator verantwortlich ist für alle Formulare, die mit diesem Namen beginnen.

Wie registriert man ein andockbares IDE-Fenster

Vergessen Sie nicht, einen langen, uniquen Namen zu verwenden, der ein gültiger Pascal-Bezeichner ist. Ihr Fenster kann einen beliebigen Titel haben.

uses SysUtils, IDEWindowIntf;
...
var MyIDEWindow: TMyIDEWindow = nil; 

procedure CreateMyIDEWindow(Sender: TObject; aFormName: string; var AForm: TCustomForm; DoDisableAutoSizing: boolean);
begin
  // check the name
  if CompareText(aFormName,MyIDEWindowName)<>0 then exit;
  // create the form if not already done and disable autosizing
  IDEWindowCreators.CreateForm(MyIDEWindow,TMyIDEWindowm,DoDisableAutosizing,Application);
  ... init the window ...
  AForm:=MyIDEWindow;
end;

procedure Register;
begin
  IDEWindowCreators.Add('MyIDEWindow',@CreateMyIDEWindow,nil,'100','50%','+300','+20%');
  // the default boundsrect of the form is:
  // Left=100, Top=50% of Screen.Height, Width=300, Height=20% of Screen.Height
  // when the IDE needs an instance of this window it calls the procedure CreateMyIDEWindow.
end;

Anzeigen eines IDE-Fensters

Benutzen Sie nicht Show. Nehmen Sie stattdessen:

IDEWindowCreators.ShowForm(MyIDEWindow,false);

Das wird auch mit Docking funktionieren. Das Docking-System wird das Formular in eine Docking-Site einschließen. Der Parameter 'BringToFront' befiehlt dem Docking-System, dieses Formular und all seine Eltern-Sites sichtbar zu machen und die Site der obersten Ebene in den Vordergrund zu bringen.

Anmerkungen über IDEWindowCreators und SimpleLayoutStorage

Das IDEWindowCreators.SimpleLayoutStorage speichert einfach das BoundsRect und den WindowState von allen Formularen, die einmal geöffnet wurden. Es stellt ein Fallback dar, falls kein Dockmaster installiert ist. Es speichert des Zustand sogar wenn ein DockMaster installiert ist, sodass auch beim Deinstallieren des Dockmasters die Formulargrößen wiederhergestellt werden können.

Die IDEWindowCreators werden bei allen andockbaren Formularen eingesetzt, um sich selbst zu registrieren und die Formulare anzuzeigen. Beim Anzeigen eines Formulars überprüft der Creator ob ein IDEDockMaster installiert ist und überträgt ihm die Aufgabe des Anzeigens. Ist kein IDEDockMaster installiert wird das Formular einfach angezeigt. Der IDEDockMaster kann die Informationen in den IDEWindowCreators benutzen, um benannte Formulare zu erzeugen und um festzustellen, wo ein Formular beim ersten Anzeigen zu platzieren ist. Für weitere Details siehe die Packages AnchorDockingDsgn und EasyDockMgDsgn.

CodeTools in der IDE

Die CodeTools sind ein Package das eine große Anzahl von Funktionen zum Parsen, Untersuchen und Ändern von Pascal-Quelltexten zur Verfügung stellt, daneben auch einige grundlegende Funktionen für andere Sprachen. Sie können sie auch ohne die IDE einsetzen. Es wird empfohlen, dass Sie zuerst über die CodeTools im Allgemeinen nachlesen, bevor Sie sie in der IDE benutzen: CodeTools (deutsch).

Bevor Sie irgendeine der Codetools-Funktionen in der IDE aufrufen, sollten Sie die letzten Änderungen im Quelltexteditor in den Codetools-Puffern speichern:

uses LazIDEIntf;
...
  // save changes in source editor to codetools
  LazarusIDE.SaveSourceEditorChangesToCodeCache(-1); // -1: commit all source editors

Hinzufügen einer resource Direktive zu einer Datei

Dies fügt eine {$R example.res} Direktive zu einer Pascal Unit hinzu:

procedure AddResourceDirectiveToPascalSource(const Filename: string);
var
  ExpandedFilename: String;
  CodeBuf: TCodeBuffer;
begin
  // make sure the filename is trimmed and contains a full path
  ExpandedFilename:=CleanAndExpandFilename(Filename);
  
  // save changes in source editor to codetools
  LazarusIDE.SaveSourceEditorChangesToCodeCache(-1);

  // die Datei laden
  CodeBuf:=CodeToolBoss.LoadFile(ExpandedFilename,true,false);

  // die resource Direktive hinzufügen
  if not CodeToolBoss.AddResourceDirective(CodeBuf,'example.res') then
    LazarusIDE.DoJumpToCodeToolBossError;
end;

Die Codetools stellen auch Funktionen wie FindResourceDirective und RemoveDirective zur Verfügung.

Die Suchpfade für Units und Include-Dateien ermitteln

In der IDE gibt es viele unterschiedliche Suchpfade von Projekten, Packages, dem FPC und Lazarus Verzeichnis und es gibt viele Arten von Pfaden: vor und nach dem Auflösen von Makros, mit oder ohne geerbte Suchpfade, als relative oder absolute Pfade. Alle Dateien in einem Verzeichnis teilen sich den selben Bestand an Suchpfaden. Sie erhalten die Suchpfade für jedes Verzeichnis voll aufgelöst durch eine Abfrage der Codetools:

uses CodeToolManager;
...

Dir:=''; // das leere Verzeichnis ist für neue Dateien und hat die selben Einstellungen wie das Projektverzeichnis

// ermittelt die Suchpfade für Include-Dateien:
Path:=CodeToolBoss.GetIncludePathForDirectory(Dir);

// ermittelt die Suchpfade für Units:
// Dieser Suchpfad wird an den Compiler übergeben.
// Er enthält die Package-Ausgabe-Verzeichnisse, aber nicht die Package-Quell-Verzeichnisse.
Path:=CodeToolBoss.GetUnitPathForDirectory(Dir);

// zusätzliche Unit-Suchpfade nur für die IDE können auftreten (werden nicht an den Compiler übergeben)
Path:=CodeToolBoss.GetSrcPathForDirectory(Dir);

// der vollständige Suchpfad enthält auch alle Package-Quell-Pfade für Units:
Path:=CodeToolBoss.GetCompleteSrcPathForDirectory(Dir);

Quelltext-Editor

Aktiver Quelltext-Editor

uses SrcEditorIntf;
...
Editor:=SourceEditorManagerIntf.ActiveEditor;
if Editor=nil then exit;
Filename:=Editor.FileName;
ScreenPos:=Editor.CursorScreenXY;
TextPos:=Editor.CursorTextXY;

SynEdit

Die Einstellungen für einen TSynEdit holen

Wenn Sie einen TSynEdit in einem Dialog haben und Sie wollen die selbe Schriftart und die selben Einstellungen wie im Quelltext-Editor verwenden::

uses SrcEditorIntf;
...
SourceEditorManagerIntf.GetEditorControlSettings(ASynEdit);

Die Einstellungen für einen SynEdit-Highlighter holen

Wenn Sie einen Dialog haben, der einen TSynEdit mit einem Highlighter enthält, können Sie die selben Farben wie der Highlighter des Quelltext-Editors für diese Sprache verwenden:

uses SrcEditorIntf;
...
SourceEditorManagerIntf.GetHighlighterSettings(ASynHighlighter);

Siehe für ein Beispiel auch: TSQLStringsPropertyEditorDlg.Create in der Unit SQLStringsPropertyEditorDlg.

Hilfe

Hilfe für die Quellen hinzufügen

Erzeugen sie zuerst eine THelpDatabase:

HelpDB := TFPDocHTMLHelpDatabase(
  HelpDatabases.CreateHelpDatabase('EinNameIhrerWahlFürDieDatenbank',
                                    TFPDocHTMLHelpDatabase,true));
  HelpDB.DefaultBaseURL := 'http://ihre.hilfe.org/';

  FPDocNode := THelpNode.CreateURL(HelpDB,
                                   'Package1 - A new package',
                                   'file://index.html');
  HelpDB.TOCNode := THelpNode.Create(HelpDB,FPDocNode);// einmal als Inhaltsverzeichnis
  DirectoryItem := THelpDBISourceDirectory.Create(FPDocNode,'$(PkgDir)/lcl',
                                   '*.pp;*.pas',false);// und einmal als normale Seite
  HelpDB.RegisterItem(DirectoryItem);

Zeilen zum Nachrichtenfenster hinzufügen

unit IDEMsgIntf;
...
var Dir: String;
begin
  Dir:=GetCurrentDir;
  IDEMessagesWindow.BeginBlock;
  IDEMessagesWindow.AddMsg('unit1.pas(30,4) Error: Identifier not found "a"',Dir,0);
  IDEMessagesWindow.EndBlock;
end;

Überblick über die verschiedenen Elemente der Hilfe

Hilfe für die IDE erzeugen