Hallo,
habe mich an diesem
Thread orientiert, jedoch habe ich noch ein kleineres Problem. Es geht darum mittels Plugin u.a. Menu Einträge dem MainMenu im Hauptprogramm hinzuzufügen. Das funktioniert gut, lade ich das Plugin werden diese angezeigt, entlade ich es wieder, werden diese entfernt. Nun möchte ich aber auch darauf reagieren, wenn der Nutzer auf ein solchen Menu Eintrag klickt. Leider scheitert es an dieser Stelle, irgendwo muss da noch ein kleiner Fehler sein.
Ich benutze zwar nicht die Delphi eigenen TMainMenu Komponenten, sondern die von DevExpress, an sich spielt es aber keine große Rolle.
Auszug aus der uApiMainMenu.pas
Delphi-Quellcode:
procedure TIMenuItem.MenuItemOnClick(Sender: TObject); // OnClick Event wenn auf das
var // visuelle TMenuItem sprich DevExpress TMenuItem geklickt wird
MenuItem: TIMenuItem;
begin
MenuItem := TIMenuItem.Create(Sender as TdxBarItem);
try
if (@FNotifyEvent <> nil) then
FNotifyEvent.OnNotify(MenuItem); // hier kommt die Zugriffsverletzung
finally
MenuItem.Free;
end;
end;
Interface:
Delphi-Quellcode:
type
INotifyEvent = interface(IUnknown)
['{EE9407DD-2337-4DFC-BC35-A40C4FA0A1A7}']
procedure OnNotify(const Sender: IUnknown); stdcall;
end;
PlugIn:
Delphi-Quellcode:
type
TNotifyMethod = procedure(const Sender: IUnknown) of object;
TINotifyEvent = class(TInterfacedObject, INotifyEvent)
private
FOnNotify: TNotifyMethod;
public
property OnNotifyHandler: TNotifyMethod read FOnNotify write FOnNotify;
procedure OnNotify(const Sender: IUnknown); stdcall;
end;
TMirrorSort = class(TAppPlugIn)
private
// FNotifyEvent:TINotifyEvent;
procedure OnClick(const Sender: IUnknown);
public
function GetName: WideString; override; safecall;
function Start(const AAppController: IAppController): Boolean; override; stdcall;
procedure Stop; override; stdcall;
end;
var
FAppController: IAppController;
FNewMenuItem: IMenuItem;
FNotifyEvent: TINotifyEvent;
implementation
{$R *.dfm}
procedure TINotifyEvent.OnNotify;
begin
// würde es klappen müsste er beim onklick zuerst hier rein springen
if (@FOnNotify <> nil) then
FOnNotify(Sender);
end;
procedure TMirrorSort.OnClick;
begin
// dannach diesen Code ausführen
ShowMessage('OnClickFunktioniert ;)');
end;
function TMirrorSort.Start; // plugin wurde geladen und aktiviert
begin
FAppController := AAppController; // bekommt hiermit ein Zugriff auf die Hauptanwendung
FNotifyEvent := TINotifyEvent.Create;
FNotifyEvent.OnNotifyHandler := OnClick;
with FAppController.MainMenu.GetMenuItems.GetItem(3) do
FNewMenuItem := InsertMenuItem(GetMenuItems.GetCount, 'MirrorSort', 'This sorts', 'name', 0, 0, FNotifyEvent);
Result := True;
end;
procedure TMirrorSort.Stop; // hiernach wird das plugin entladen
begin
FAppController.MainMenu.GetMenuItems.GetItem(3).GetMenuItems.RemoveItem(FNewMenuItem);
FNotifyEvent := nil;
end;
Im Anhang habe ich nochmal den kompletten Code, der die Interfaces implementiert.
EDIT:
Problem lag/liegt nicht an diesem Code-Stück... Der Wrapper ist falsch konzipiert