 |
| |
|
|
 |
Autor |
Nachricht |
 |
| |
| sakura |
#1| Verfasst am: 11.05.2003, 16:15 Titel: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Super-Moderator Alter: 33 Status: offline Beiträge: 11.294 angemeldet: 10.06.2002 Wohnort: München RAD-Studio 2007 Architect

|
Sprache: Delphi (Win32) 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: | markieren | HINWEIS:
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. |
|
Installation eines Delphi-IDE-PlugIns
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: | markieren | function InitExpert(ToolServices: TIToolServices; RegisterProc:
TExpertRegisterProc; var Terminate: TExpertTerminateProc): Boolean; export;
stdcall; |
|
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.
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: - Die Methode GetState muss [esEnabled] zurückliefern
- Die Methode GetStyle muss esStandard zurückliefern
- Die Methode GetMenuText liefert den Text des Menüeintrages zurück
- Die Methode Execute definiert das eigentliche Ereignis
Hier noch der Code der relevanten Methoden. Der komplette Code ist im Anhang zu finden.
Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · · 20 · · · · 25 · · · · 30 31
| 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; |
|
... ... |
| [ An diesen Beitrag wurden eine oder mehrere Dateien angehängt. Zum Herunterladen bitte anmelden. ] |
 Jeder Mensch lebt praktisch in seiner eigenen, privaten Welt. Kommunikation bedeutet zwischen diesen Welten Brücken zu bauen.
CodeGear Associate Evangelist |
 |
|
|
|
| |
| sakura |
#2| Verfasst am: 11.05.2003, 16:43 Titel: |
 |
 |
 |
|
Super-Moderator Alter: 33 Status: offline Beiträge: 11.294 angemeldet: 10.06.2002 Wohnort: München RAD-Studio 2007 Architect

|
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: | markieren | function TDelphiPlug.GetStyle: TExpertStyle;
begin
// liefert die Art des Experten zurück
// mögliche Werte: esStandard, esForm, esProject, esAddIn
Result := esAddIn;
end; |
| 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.
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: | markieren | function InsertItem(Index: Integer; Caption, Name, Hint: string;
ShortCut, Context, GroupIndex: Integer; Flags: TIMenuFlags;
EventHandler: TIMenuClickEvent): TIMenuItemIntf; stdcall; |
|
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 Delphi-Quellcode: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15 · · · · 20 · · · · 25 · · · · 30 · · 33
| 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; |
|
Der Eventhandler
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: | zusammenfalten | markieren | 1 · · · 5 · · · · 10 · · · · 15
| 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; |
|
Wo liegt die DLL eigentlich rum?
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: | markieren | 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; |
|
Der liebe Rest...
kann dem beigefügten Download entnommen werden. Und nicht vergessen, das PlugIn muß in der Registry eingetragen werden, damit Delphi es auch lädt.
... ... |
| [ An diesen Beitrag wurden eine oder mehrere Dateien angehängt. Zum Herunterladen bitte anmelden. ] |
 Jeder Mensch lebt praktisch in seiner eigenen, privaten Welt. Kommunikation bedeutet zwischen diesen Welten Brücken zu bauen.
CodeGear Associate Evangelist |
 |
|
|
|
| |
| Lord_Stifterl |
#3| Verfasst am: 30.01.2004, 11:06 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Mitglied Alter: 26 Status: offline Beiträge: 170 angemeldet: 13.12.2002 Wohnort: Wien Turbo Delphi für Win32

|
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 |
|
 |
|
|
|
| |
| sakura |
#4| Verfasst am: 30.01.2004, 11:15 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Super-Moderator Alter: 33 Status: offline Beiträge: 11.294 angemeldet: 10.06.2002 Wohnort: München RAD-Studio 2007 Architect

|
| Lord_Stifterl hat folgendes geschrieben: | | du hast in diesem Tutorial erwähnt das diese Technik seit Delphi7 als veraltet gilt. Mit welcher Begründung? |
Der Compiler gibt ein Warning "deprecated" raus
| Lord_Stifterl hat folgendes geschrieben: | | Gibt es hier neue Techniken dieses Problem zu lösen? |
Ja, die neue Variante geht über Interfaces, aber mit denen habe ich mich nicht weiter beschäftigt, da seit Delphi 8 alles über Assemblies gelöst
... ... |
 Jeder Mensch lebt praktisch in seiner eigenen, privaten Welt. Kommunikation bedeutet zwischen diesen Welten Brücken zu bauen.
CodeGear Associate Evangelist |
 |
|
|
|
| |
| Corpsman |
#5| Verfasst am: 06.02.2006, 20:20 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Mitglied Alter: 28 Status: offline Beiträge: 916 angemeldet: 08.11.2005 Wohnort: Stuttgart Lazarus

|
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
wird
Wenn ich beim Drücken der Tasten kombi die Zeilen Begin und X:=10 Markiert habe.
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: | markieren | Procedure CommentChange( Var Code:Tstrings; Key:Word; Selstart:Integer; Selend:Integer);
begin
end; |
|
Ich benutzt D5 Pro .
Wäre cool wenn das jemand wüste
[edit=MrSpock]Delphi Code Tags gesetzt. Mfg, MrSpock[/edit] |
Zuletzt bearbeitet von MrSpock am 06.02.2006, 21:33, insgesamt 1-mal bearbeitet. |
 |
|
|
|
| |
| MaBuSE |
#6| Verfasst am: 27.02.2006, 09:46 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
"Rüsselmops" ;-) Alter: 35 Status: offline Beiträge: 1.483 angemeldet: 23.09.2002 Wohnort: Frankfurt am Main Delphi 2007 Enterprise

|
| Corpsman hat folgendes geschrieben: | Ich habe vor ein Plugin zu schreiben welches mir auf Tasten Druck im Quelltexteditor die Selektierten Zeilen in Kommentare fast oder diese wieder entfernt.
...
Wäre cool wenn das jemand wüste |
Diese Funktionalität gibt es schon
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
http://www.gexperts.org/
ps: Herzlich willkommen in der DP |
 (°¿°) MaBuSE - proud to be a DP member
(°¿°) MaBuSE - proud to be a "Rüsselmops" ;-)
Zuletzt bearbeitet von MaBuSE am 27.02.2006, 09:47, insgesamt 1-mal bearbeitet. |
 |
|
|
|
| |
| Corpsman |
#7| Verfasst am: 08.03.2006, 19:30 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Mitglied Alter: 28 Status: offline Beiträge: 916 angemeldet: 08.11.2005 Wohnort: Stuttgart Lazarus

|
@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 www.Corpsman.de.vu |
|
 |
|
|
|
| |
| Corpsman |
#8| Verfasst am: 12.03.2006, 13:35 Titel: Re: Erstellen eines Delphi-PlugIns |
 |
 |
 |
|
Mitglied Alter: 28 Status: offline Beiträge: 916 angemeldet: 08.11.2005 Wohnort: Stuttgart Lazarus

|
@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. |
 My Site www.Corpsman.de.vu
My marble madness clone Balanced ( ca. 3,9 mb ) aktuell ver 0.64 |
 |
|
|
|
| |
| Amnon82 |
#9| Verfasst am: 24.05.2006, 21:45 Titel: Probleme mit Delphi 2005 PE |
 |
 |
 |
|
Mitglied Status: offline Beiträge: 185 angemeldet: 05.01.2005 Turbo Delphi für Win32

|
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. |
|
 |
|
|
|
| |
| sakura |
#10| Verfasst am: 24.05.2006, 22:11 Titel: Re: Probleme mit Delphi 2005 PE |
 |
 |
 |
|
Super-Moderator Alter: 33 Status: offline Beiträge: 11.294 angemeldet: 10.06.2002 Wohnort: München RAD-Studio 2007 Architect

|
| Amnon82 hat folgendes geschrieben: | | Ungültige Version des Experten 'C:\Programme\Borland\Plugins\DelphiPlug.dll' | Die DLLs sind mit/für Delphi 7 kompiliert.
| Amnon82 hat folgendes geschrieben: | Schön und gut. Dann wollte ich die Source der Examples compilen.
Fehlanzeige! Kann die ExptIntf bei meinem Delphi 2005 Personal nicht finden. | Es kann gut sein, dass das mit D2005 nicht geht
... ... |
 Jeder Mensch lebt praktisch in seiner eigenen, privaten Welt. Kommunikation bedeutet zwischen diesen Welten Brücken zu bauen.
CodeGear Associate Evangelist |
 |
|
|
|
 |
|
 |
| |
|
|
| |
 
|
|
| |
|
Du darfst keine Beiträge in dieses Forum schreiben. Du darfst auf Beiträge in diesem Forum nicht antworten. Du darfst Deine Beiträge in diesem Forum nicht bearbeiten. Du darfst Deine Beiträge in diesem Forum nicht löschen. Du darfst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum nicht posten. Du kannst Dateien in diesem Forum nicht herunterladen.
|
|
 |