Wiki-KopieMirror

Dies ist ein Mirror des Wikis von pascal.chat. Bearbeiten, Verlauf und Anmeldung finden dort statt.

Extending the IDE/de

Deutsch · English · Español · Français · Slovenčina · Русский · 中文(中国) · 日本語

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:

pascal
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:

pascal
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:

pascal
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:

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

Packages erzeugen ihre eigenen xml-Dateien mit:

pascal
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:

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:

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

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

text
 initialization
   {$I mybutton.lrs}

Installieren Sie das Package.

Eine Komponente aus der Palette verstecken

Package IDEIntf, unit componentreg:

pascal
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/.

Einen neuen einzigartigen Komponentennamen erzeugen

pascal
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

pascal
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:

text
 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:

pascal
 // 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:

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;

Projektereignisse

Diese Ereignisse sind definiert in der Unit LazIDEIntf.

Andere IDE Ereignisse

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:

pascal
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

pascal
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:

pascal
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 ...':

Hinzufügen eines neuen Dateityps

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

pascal
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:

pascal
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):

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

Suche ein Package mit einem bestimmten Namen

pascal
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.

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;

Fenster

Grundsätzlich gibt es vier Typen von IDE Fenstern:

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.

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;

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:

pascal
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:

pascal
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:

pascal
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:

pascal
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

pascal
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::

pascal
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:

pascal
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:

pascal
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

pascal
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


From the Free Pascal wiki, page "Extending the IDE/de", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.

Version 2, zuletzt geändert von WikiArchive .