AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Delphi Erstellen eines Delphi-PlugIns
Tutorial durchsuchen
Ansicht
Themen-Optionen

Erstellen eines Delphi-PlugIns

Ein Tutorial von sakura · begonnen am 11. Mai 2003 · letzter Beitrag vom 24. Mai 2006
Antwort Antwort
Benutzerbild von sakura
sakura
Registriert seit: 10. Jun 2002
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:
[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]
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:
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:
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;
......
Angehängte Dateien
Dateityp: zip delphi-plug_sample__i_.zip (52,3 KB, 251x aufgerufen)
Ich bin nicht zurück, ich tue nur so
 
Benutzerbild von sakura
sakura

 
Delphi 11 Alexandria
 
#2
  Alt 11. Mai 2003, 16:43
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:
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:
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:
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:
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:
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.

......
Angehängte Dateien
Dateityp: zip delphi-plug_sample__ii_.zip (53,7 KB, 239x aufgerufen)
Daniel W.
  Mit Zitat antworten Zitat
Lord_Stifterl

 
Turbo Delphi für Win32
 
#3
  Alt 30. Jan 2004, 10:06
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
Alex
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

 
Delphi 11 Alexandria
 
#4
  Alt 30. Jan 2004, 10:15
Zitat von Lord_Stifterl:
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

Zitat von Lord_Stifterl:
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

......
Daniel W.
  Mit Zitat antworten Zitat
Benutzerbild von Corpsman
Corpsman

 
Delphi XE2 Professional
 
#5
  Alt 6. Feb 2006, 19:20
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:
Procedure Test;
  Var x:Integer;
Begin
  X:=10;
End;
wird

Delphi-Quellcode:
Procedure Test;
  Var x:Integer;
// Begin
// X:=10;
End;
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:
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]
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von MaBuSE
MaBuSE

 
Delphi 10 Seattle Enterprise
 
#6
  Alt 27. Feb 2006, 08:46
Zitat von Corpsman:
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
  Mit Zitat antworten Zitat
Benutzerbild von Corpsman
Corpsman

 
Delphi XE2 Professional
 
#7
  Alt 8. Mär 2006, 18:30
@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
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von Corpsman
Corpsman

 
Delphi XE2 Professional
 
#8
  Alt 12. Mär 2006, 12:35
@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.
Uwe
  Mit Zitat antworten Zitat
Benutzerbild von Amnon82
Amnon82

 
FreePascal / Lazarus
 
#9
  Alt 24. Mai 2006, 21:45
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.
  Mit Zitat antworten Zitat
Benutzerbild von sakura
sakura

 
Delphi 11 Alexandria
 
#10
  Alt 24. Mai 2006, 22:11
Zitat von Amnon82:
Ungültige Version des Experten 'C:\Programme\Borland\Plugins\DelphiPlug.dll'
Die DLLs sind mit/für Delphi 7 kompiliert.
Zitat von Amnon82:
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

......
Daniel W.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:42 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz