Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Plugin-System fragen (https://www.delphipraxis.net/151495-plugin-system-fragen.html)

himitsu 21. Mai 2010 08:36

Re: Plugin-System fragen
 
Zitat:

Zitat von b1428727
es wäre doch toll, wenn die plugin-entwickler ihre eigenen objekte/komponenten nutzen könnten.
dann habe ich weniger aufwand und die plugin-ersteller müssen nicht meine interface-deklarationen lernen.

Du kannst auch ein ErstellePanel bereitstellen und dessen Handle übergeben.

Ein Panel ist wie eine Form und darin kann man nun alles machen, was man will.
(z.B. bei einer Form MSDN-Library durchsuchenSetParent und da das Handle angeben, schon wird diese Form in das Panel eingefügt)
Aber bei den Standardkomponenten behält deine Anwendung dennoch die Kontrolle.

b1428727 21. Mai 2010 09:45

Re: Plugin-System fragen
 
Zitat:

Zitat von himitsu
Zitat:

Zitat von b1428727
es wäre doch toll, wenn die plugin-entwickler ihre eigenen objekte/komponenten nutzen könnten.
dann habe ich weniger aufwand und die plugin-ersteller müssen nicht meine interface-deklarationen lernen.

Du kannst auch ein ErstellePanel bereitstellen und dessen Handle übergeben.

Ein Panel ist wie eine Form und darin kann man nun alles machen, was man will.
(z.B. bei einer Form MSDN-Library durchsuchenSetParent und da das Handle angeben, schon wird diese Form in das Panel eingefügt)
Aber bei den Standardkomponenten behält deine Anwendung dennoch die Kontrolle.

habe ein test-programm geschrieben um dies auszutesten.

programm hat ein haupt-formular, ein komponenten-formular und ein docking-formular
-das komponenten-formular enthält ein edit, label, memo, etc.
-das docking-formular enthält ein panel, docking-formular kann an das haupt-formular gedockt werden.
-das hauptformular kann docking-formulare erstellen

wenn ich nun mit Windows.SetParent(komponentenformular.handle,docki ngformular.panel.handle)
das ganze formular in das panel packe, dann das dockingformular docke verschwindet auch alles.

himitsu 21. Mai 2010 09:54

Re: Plugin-System fragen
 
Hmmm, kannst du mal etwas testen?

Welchen Wert hat Handle denn vor und nach dem Docking ... verändert sich eventuell das Handle?

b1428727 21. Mai 2010 12:38

Re: Plugin-System fragen
 
ja, es gibt neue handles... für das docking-formular selbst UND auch für das panel im docking-formular.
jeweils nach docking bzw. undocking.

himitsu 21. Mai 2010 12:55

Re: Plugin-System fragen
 
OK, dann erklärt das schonmal das Verschwinden der Nicht-VCL-Komponenten.

Delphi erstellt die internen Windows-Controls gerne mal neu, wenn sich der Fenster-Style verändert.
Dabei gehen natürlich alle WinAPI-Sachen verloren.
Danach wird die Anzeige dann aus den VCL-Objekten neu aufgebaut, aber dort fehlen natürlich die "externen" Controls und alle (der VCL unbekannten und somit nicht beachteten) Änderungen via WinAPI.



Einzige Idee, welche ich aktuell hätte, wäre:

> vor dem (Un)Docking:
- alle externen Controls suchen
(im Fall der GibMirPanel wäre es einfach, denn da müßte man nur diese paar Panels prüfen)
- also via WinAPI alle ChildControls in den entsprechenden Komponenten (Fenster, Panels usw.) suchen, diese mit den Handles der VCL abgleichen >> übrig blieben dann nur die Fremdkomponenten
(sobkomponenten von Fremdkomponenten könnte man wohl erstmal ignorieren)
- dann eine temporäre (unsichtbare) Form erzeugen, darauf die Fremdkomponenten via MSDN-Library durchsuchenSetParent zwischenparken
- dabei die Verbindung von Handle der Fremdkomponente und der VCL-Komponente merken

> nun (un)docken

> nach dem (Un)Docking:
- jetzt die Fremdkomponenten wieder via MSDN-Library durchsuchenSetParent auf die neuen Windows-Controls (neues Handle zu den gemerkten VCL-Objekten) übergeben.
- eventuell Tempform löschen

(klingt schlimmer, als es ist :lol: )


Im Falle einer in ein Panel eingebundenen Form, könnte man sie auch mal kurzzeitig auf SetParent(..., nil) setzen und braucht womöglich keine Tempform.


Tja, wenn du alles/vieles über über die Pluginschnittstelle, als Weiterleitung zur Programminternen VCL, erzeugen ließest, dann würde die VCL alles kennen und nach dem Neuaufbau wäre nichts verschwunden. :stupid:

b1428727 27. Mai 2010 12:54

Re: Plugin-System fragen
 
Zitat:

Zitat von implementation
Ich habe sowas bisher immer so geregelt, dass ich ein paar Interface zu jedem Zweck gebastelt habe (z.B. eins für Dock-Fenster, eins für Label, usw.) + ein Factory-Interface deklariere und beim Start des Plug-Ins die Factory übergebe.
Delphi-Quellcode:
type
  IFactory = interface
    function CreateDockWindow: IDockWindow;
    ...
  end;
  IDockWindow = interface
    function GetCaption: string;
    procedure SetCaption(val: string);
    property Caption: string read GetCaption write SetCaption;
    ...
  end;

type
  TFactory = class(TInterfacedObject, IFactory)
    ...
  end;
  TDockWindow = class(TInterfacedObject, IDockWindow)
    ...
  end;
Die Interfaces kann dann jeder Plug-In-Entwickler in seiner Sprache deklarieren.
Außerdem können die Plug-Ins schön klein bleiben, da ein Delphi-PlugIn dann z.B. keine VCL braucht, ein VC++-PlugIn keine MFC/WTL usw.


zu dieser methode hätte ich noch zwei fragen:

1. gibt es da keine probleme mit der freigabe?
ich kann doch kein DockWindow erzeugen, ein interface darauf an die dll geben und das DockWindow
schliessen ohne dass es in der DLL dann zu problemen kommt? was ich meine: die dll hat das interface
IDockWindow noch, obwohl das Formular bereits geschlossen/zerstört wurde...
wie geht man damit um?

2. wie funktioniert das mit events bei dieser methode? z.b. OnClick, OnChange, etc...

Gibt es dafür ein Interface welches z.B. so aussieht:
Delphi-Quellcode:
IEinInterface = interface
  procedure SetOnChange(OnChangeIntf: IOnChangeEvent);
  property OnChange: IOnNotifyEvent write SetOnChange;
end;

IOnChangeEvent = interface
  procedure OnChangeEvent(Sender: IObject);
end;
das plugin erstellt dann eine klasse TOnChangeEvent und setzt dies über IEinInterface.SetOnChange(MyOnChangeEvent)?

gibt es da eine elegantere lösung?

himitsu 27. Mai 2010 13:16

Re: Plugin-System fragen
 
Das Objekt hinter dem Interface IDockWindow muß Owner des Fensters sein.

- entweder erst wenn das Objekt gelöscht wird, wird auch die Form gelöscht
(wird das Formular geschlossen, wird dieses nur unsichtbar gemacht)

- oder das Formular wird freigegeben, aber IDockWindow reagiert dann entsprechend, wenn man doch noch versucht drauf zuzugreifen
(anfragen ignoreren, diese nur intern verwalten oder einen "Fehler" auslösen)



2. entweder man registriert bei IDockWindow die entsprechenden Methoden/Callbackfunktionen
(wie in deinem Beispliel)
oder man läßt sich vom Plugin passend zu den "Komponenten" ein Event-Interface übergeben.

Delphi-Quellcode:
IEvent = interface
  procedure OnEnterEvent(Sender: IObject);
  procedure OnExitEvent(Sender: IObject);
  procedure OnClickEvent(Sender: IObject);
  procedure OnDblClickEvent(Sender: IObject);
end;

IEdit = interface(IObject)
  procedure SetOnChange(OnChangeIntf: IOnChangeEvent);
  property OnChange: IOnNotifyEvent write SetOnChange;
end;

IFactory = interface
  function CreateEdit(pos: TRect; events: IEvent): IObject{IEdit};
end;

Es gibt da tausende Möglichkeiten.

hanspeter 27. Mai 2010 13:32

Re: Plugin-System fragen
 
Bei dll und Interface gibt es aber noch eine kleine Falle.
Eine Reihe Komponenten von Delphi registrieren sich bei Windows mit "Registerclass".
So eine Komponente kann auch bei Interfaces nicht in 2 Modulen gleichzeitig verwendet werden.
Das jeweils später nachgeladene Modul bringt dann einen Registerclass - Fehler.

Konkretes Beispiel Fastreport.
Fastreport im Hauptprogramm verwendet -> kein Plugin auf dll Basis kann Fastreport verwenden.

Fastreport in A.dll und B.dll.
Jede dll kann verwendet werden. Wird a und b geladen kommt es zum Programmabsturz.

Plugin als Comserver/ActiveX haben das Problem nicht.

Gruß
Peter

b1428727 27. Mai 2010 13:44

Re: Plugin-System fragen
 
Vielen Dank für die Info's!

Werde ein Test-Projekt damit starten um zu sehen wie es so läuft.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:33 Uhr.
Seite 2 von 2     12   

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