![]() |
Erstellen eines Delphi-PlugIns
Liste der Anhänge anzeigen (Anzahl: 1)
Dieses Tutorial zeigt Ihnen auf, wie sie mit Hilfe eines PlugIns die Funktionalität der Delphi-IDE erweitern können. Es ist in zwei Abschnitte aufgeteilt.
Der erste Abschnitt zeigt die denkbar einfachste Form für ein Delphi-IDE-PlugIn, der zweite ist ungleich komplexer. Beide Abschnitte sind jedoch bloß die Spitze des Eisbergs dessen, was möglich ist.
Code:
Installation eines Delphi-IDE-PlugIns
[color=#000080][i]HINWEIS:[/i]
Die hier gezeigte Technik ist gültig ab Delphi 4 und gilt seit Delphi 7 als veraltet, kann jedoch noch genutzt werden und wird vollständig unterstützt.[/color] Vorab möchte ich kurz erläutern, wie ein PlugIn für Delphi installiert wird. Damit können Sie die Beispiele testen, bevor Sie alles durchgelesen haben. Jedes Delphi-IDE-PlugIn wird in der Registry eingetragen. Sollten mehrere Delphi-Versionen auf einem Rechner installiert sein, so muß das PlugIn für jede Delphi-Version separat installiert werden. Gleiches gilt, wenn eine Delphi-Version auf dem gleichen Rechner durch mehrere Anwender genutzt wird. In der Registry muß das PlugIn unter folgendem Schlüssel installiert werden. HKCU\Software\Borland\Delphi\X.0\Experts , wobei das X durch die entsprechende Delphi-Version zu ersetzen ist. Es ist möglich, daß der Schlüssel Experts nicht existiert. Dieser muß dann bei Bedarf angelegt werden.Unter diesem Schlüssel muß ein Eintrag (REG_SZ) mit einem eindeutigen Namen angelegt werden. Der Wert dieses Eintrages verweisst dann auf die DLL des PlugIns (inkl. Pfad und Dateinamen). Beim nächsten Start von Delphi wird das PlugIn dann automatisch geladen. Die Schnittstelle zwischen der Delphi-IDE und dem PlugIn Damit Delphi mit dem PlugIn kommunizieren kann, muß eine Methode exportiert werden. Diese Methode muß unter dem Namen ExpertEntryPoint exportiert werden und hat folgende Parameterliste
Delphi-Quellcode:
Der erste Paramter ToolServices bietet sämtliche "dokumentierten" Schnittstellen zur Delphi-IDE. Der zweite Paramter RegisterProc wird benötigt, um eines oder mehrere PlugIns in die Delphi-IDE zu integrieren. Der dritte Paramter Terminate kann genutzt werden, um die PlugIn-DLL zu informieren, wenn das PlugIn entladen wird.
function InitExpert(ToolServices: TIToolServices; RegisterProc:
TExpertRegisterProc; var Terminate: TExpertTerminateProc): Boolean; export; stdcall; Die Methode gibt True zurück, wenn das PlugIn erfolgreich geladen wurde. Es kann entweder False zurückgegeben werden, wenn ein Fehler aufgetreten ist, oder es wird eine Exception ausgelöst, damit die Delphi-IDE das PlugIn sofort wieder entlädt (siehe Code-Beispiel im Download). Die PlugIn Klasse TIExpert Das PlugIn muß von der Klasse TIExpert abgeleitet werden, welche in der Unit ExptIntf deklariert ist. Diese Klasse definiert mehrere abstrakte Methoden, welche durch jedes PlugIn implementiert werden müssen: GetName, GetAuthor, GetComment, GetPage, GetGlyph (Unterschiedlich für Windows und Linux), GetStyle, GetState, GetIDString, GetMenuText und Execute. Die Bedeutung der einzelnen Methoden ist im Quelltext (im Anhang) genauer erläutert. Das einfachste PlugIn Unser erstes PlugIn wird einen neuen Eintrag in das Hilfe-Menü (Standard) einbinden. Wenn der User auf diesen Eintrag klickt, wird durch die Delphi-IDE die Methode Execute des PlugIns aufgerufen. Folgende Punkte sind entscheidend:
Hier noch der Code der relevanten Methoden. Der komplette Code ist im Anhang zu finden.
Delphi-Quellcode:
...:cat:...
procedure TDelphiPlug.Execute;
begin // Execute wird aufgerufen, wenn der User auf den Eintrag im Hilfe-Menü klickt MessageBox(ToolServices.GetParentHandle, 'Wie kann ich Ihnen helfen?', 'Öhm', MB_ICONQUESTION + MB_OK); end; function TDelphiPlug.GetMenuText: string; begin // Text der im Hilfe Menü angezeigt wird. Diese Funktion wird jedesmal // aufgerufen, wenn das Hilfemenü angezeigt wird. // // HINWEIS: // die Methode GetState muß esStandard zurückliefern, damit dieser Eintrag // im Hilfemenü automatisch generiert wird Result := 'Hallo, ich erscheine im Hilfe-Menü'; end; function TDelphiPlug.GetState: TExpertState; begin // liefert ein Set ´von Stati zurück // mögliche Werte: esEnabled, esChecked Result := [esEnabled]; end; function TDelphiPlug.GetStyle: TExpertStyle; begin // liefert die Art des Experten zurück // mögliche Werte: esStandard, esForm, esProject, esAddIn Result := esStandard; end; |
Liste der Anhänge anzeigen (Anzahl: 1)
Dieser zweite Teil beschäftigt sich mit der Erweiterung des Menüs der Delphi-IDE.
Erster, wichtiger Unterschied zu einem einfachen Plugin Im Vergleich zum ersten Teil möchten wir dieses Mal alles selbst erledigen. Damit kommt auch schon die erste Änderung einher. Die Methode GetStyle muß einen anderen Wert zurück liefern.
Delphi-Quellcode:
Wir könnten auch hier wieder esStandard nutzen, allerdings würde die Delphi-IDE dann einen Eintrag im Hilfe-Menü erstellen, welchen wir dieses Mal nicht benötigen.
function TDelphiPlug.GetStyle: TExpertStyle;
begin // liefert die Art des Experten zurück // mögliche Werte: esStandard, esForm, esProject, esAddIn Result := esAddIn; end; Das PlugIn kommt in das Menü der Delphi-IDE Dieses PlugIn wird im Tools-Menü ein Submenü einrichten, welches wiederum drei Menüeinträge hat. Dazu dient die Methode CreateMenuEntries unserer PlugIn-Klasse. Um das Menü der IDE anzusteuern muß die Schnittstelle zur IDE (TIToolServices) bekannt sein. Diese Schnittstelle liefert uns die Schnittstelle zum Hauptmenü (TIMainMenuIntf) zurück. Über diese können wir das gewünschte Menü (TIMenuItemIntf) ansteuern. Diese Schnittstelle bietet uns die Methode InsertItem, welche es uns ermöglicht einen neuen Menüpunkt zu erstellen. Diese Methode ist wie folgt definiert
Delphi-Quellcode:
Der dritte Parameter Name muß eindeutig für die gesamte Delphi-IDE sein, also seid kreativ! Der fünfte Parameter ist für Short-Cuts, aufgrund eines Bugs bis einschließlich Delphi 7 jedoch unbrauchbar. :-( Um das zu umgehen ist ein sogenannter AddInNotifier notwendig, das sprengt jedoch den aktuellen Rahmen des Tutorials. Der sechste Parameter Context ist wichtig, um zu ermitteln, welcher Menüpunkt vom User angesteuert wurde und sollte innerhalb des PlugIns eindeutig sein. Der letzte Parameter EventHandler ist ein Pointer auf eine Methode der PlugIn-Klasse, welcher aufgerufen wird, wenn der Menüpunkt in der Delphi-IDE geklickt wurde. Für Menüeinträge mit Untereinträgen sollte dieser nil sein, da es sonst zu Problemen kommen kann. Auszug aus dem relevanten Code
function InsertItem(Index: Integer; Caption, Name, Hint: string;
ShortCut, Context, GroupIndex: Integer; Flags: TIMenuFlags; EventHandler: TIMenuClickEvent): TIMenuItemIntf; stdcall;
Delphi-Quellcode:
Der Eventhandler
procedure TDelphiPlug.CreateMenuEntries;
var MainMenu: TIMainMenuIntf; ToolsMenu: TIMenuItemIntf; begin // get main menu MainMenu := FToolServices.GetMainMenu; if MainMenu <> nil then try // get tools menu ToolsMenu := MainMenu.FindMenuItem('ToolsMenu'); try // create sub-menu FMI_Sub := ToolsMenu.InsertItem(1, 'Mein PlugIn', 'mplugMain', 'Ein Hinttext', 0, MIdx_Main, 0, [mfVisible, mfEnabled], nil); // create three sub-menu entries FMI_Main := FMI_Sub.InsertItem(0, 'Über mein PlugIn', 'mplugInfo', 'Ein Hinttext', 0, MIdx_Main, 0, [mfVisible, mfEnabled], MenuItemClick); FMI_ShowItems := FMI_Sub.InsertItem(1, 'Hauptmenü Namen', 'mplugShow', 'Ein Hinttext', 0, MIdx_ShowItems, 0, [mfVisible, mfEnabled], MenuItemClick); FMI_RunCommand := FMI_Sub.InsertItem(2, 'Visit DP!', 'mplugDP', 'Ein Hinttext', 0, MIdx_RunCommand, 0, [mfVisible, mfEnabled], MenuItemClick); finally ToolsMenu.Free; end; finally MainMenu.Free; end; end; Im Eventhandler muß überprüft werden, welcher Menüpunkt durch den User ausgewählt wurde. Am einfachsten ist das mit einem case...of Statement zu erreichen. Auszug aus dem Code
Delphi-Quellcode:
Wo liegt die DLL eigentlich rum?
procedure TDelphiPlug.MenuItemClick(Sender: TIMenuItemIntf);
begin case Sender.getContext of MIdx_Main: MessageBox(ToolServices.GetParentHandle, PChar( 'Der Hauptmenüpunkt wurde aktiviert.'#13#10 + 'Der Name der Expert-DLL ist: ' + GetDllName), 'Öhm', MB_ICONERROR or MB_OK); MIdx_ShowItems: ShowMainMenuItems; MIdx_RunCommand: RunCommand; else // unerwarteter, bzw. nicht implementierter Aufruf MessageBox(ToolServices.GetParentHandle, 'Wer hat gerufen?', 'Öhm', MB_ICONERROR or MB_OK); end; end; In normalen Anwendungen (EXE-Apps) kann man immer über ParamStr(0) bzw. Application.ExeName den Namen inkl. Pfad der Anwendung erhalten. Dieses ist bei DLLs allerdings nicht möglich, deshalb ist im Code noch die Funktion GetDllName zu finden, welche den Pfad und Namen der PlugIn DLL zurückliefert, falls Sie dort irgendwelche INI Dateien oder ähnliches hinterlegen wollen. Diese Funktion kann in jeder beliebigen Anwendung (EXE, DLL, ...) genutzt werden.
Delphi-Quellcode:
Der liebe Rest...
function GetDllName: String; stdcall;
var TheFileName : array[0..MAX_PATH] of char; begin FillChar(TheFileName, sizeof(TheFileName), #0); GetModuleFileName(hInstance, TheFileName, sizeof(TheFileName)); Result := TheFileName; end; kann dem beigefügten Download entnommen werden. Und nicht vergessen, das PlugIn muß in der Registry eingetragen werden, damit Delphi es auch lädt. ...:cat:... |
Re: Erstellen eines Delphi-PlugIns
Hi Sakura,
du hast in diesem Tutorial erwähnt das diese Technik seit Delphi7 als veraltet gilt. Mit welcher Begründung? Gibt es hier neue Techniken dieses Problem zu lösen? LG LS |
Re: Erstellen eines Delphi-PlugIns
Zitat:
Zitat:
...:cat:... |
Re: Erstellen eines Delphi-PlugIns
Ho Sakura,
Ich habe vor ein Plugin zu schreiben welches mir auf Tasten Druck im Quelltexteditor die Selektierten Zeilen in Kommentare fast oder diese wieder entfernt. Als aus
Delphi-Quellcode:
wird
Procedure Test;
Var x:Integer; Begin X:=10; End;
Delphi-Quellcode:
Wenn ich beim Drücken der Tasten kombi die Zeilen Begin und X:=10 Markiert habe.
Procedure Test;
Var x:Integer; // Begin // X:=10; End; dazu mus ich aber wissen wie ich auf das Drücken einer Bestimmten Tastenkombi Reagieren kann und welcher textteil Selektiert ist. Weist du wie ich das Machen mus. Das ich Praktisch eine Procedure vom Delphi Aufgerufen bekomme der art
Delphi-Quellcode:
Ich benutzt D5 Pro .
Procedure CommentChange( Var Code:Tstrings; Key:Word; Selstart:Integer; Selend:Integer);
begin end; Wäre cool wenn das jemand wüste [edit=MrSpock]Delphi Code Tags gesetzt. Mfg, MrSpock[/edit] |
Re: Erstellen eines Delphi-PlugIns
Zitat:
Schau Dir mal GExperts an, das ist ein Delphi Plugin mit vielen Funktionen. Unter anderem auch ein Comment / Uncomment Diese Funktion wird mit [Strg+Alt+.] und [Strg+Alt+,] aufgerufen. Da GExpert im Quelltext vorliegt, kannstDu ja schauen, wie die das programmiert haben :mrgreen: ![]() ps: Herzlich willkommen in der DP |
Re: Erstellen eines Delphi-PlugIns
@mabuse
ich weis das es in Gexperts das hat. Von da bin ich ja mehr oder weniger auch inspiriert worden. Das Prob ist nur das ich den Source absolut nicht verstehe, da die dort ettliche Plugins ineinander bauen. Installieren wollte ich mir das Gexperts eigentlich auch nicht da ich es total überladen finde. Und ich nicht gerade die schnellsten Rechner habe, es dauert so schon immer lang genug bis mein D5 startet. -- Visit my Page at ![]() |
Re: Erstellen eines Delphi-PlugIns
@sakura
Du sprichst von einem AddInNotifier um die Shortcuts zu Aktivieren, gibts da irgendwo infos wie ich sowas einbauen kann ? Denn ohne shortcut macht zumindest mein Plugin keinen großen sinn. |
Probleme mit Delphi 2005 PE
Ich hab nun ein paar Probleme.
Erstens: Ich hab die Examples runtergeladen und wollte diese einbinden. Es kommt immer folgende Fehlermeldung: Ungültige Version des Experten 'C:\Programme\Borland\Plugins\DelphiPlug.dll' Zweitens: Schön und gut. Dann wollte ich die Source der Examples compilen. Fehlanzeige! Kann die ExptIntf bei meinem Delphi 2005 Personal nicht finden. |
Re: Probleme mit Delphi 2005 PE
Zitat:
Zitat:
...:cat:... |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz