Ich hab sowas mal angefangen, aber nachdem das Hauptprojekt derzeit auf Eis liegt, wurde das Pluginsystem auch nicht weiter entwickelt.
Hier, ist sogar kommentiert, dein Glück
Plugin Host
Code: Alles auswählen
EnableExplicit
Define PS_PluginPath .s = "plugins/" ;Pfad und ID des Plugin Ordners.
Define PS_PluginDirectoryID .i
Define.i WindowEvent, EventGadget, Main_WindowID
Prototype proto_init(hWnd.i) ;Prototypen der Plugin-Funktionen
Prototype proto_eventgadget(eventgadget.i)
Structure plugins_structure ;Struktur, welche die LibraryID enthält
libID .i ;und alle Prototype-Funktionen
plugin_init .proto_init
plugin_eventgadget .proto_eventgadget
EndStructure
NewList plugins.plugins_structure() ;Liste aller Plugins
Define PS_PluginDirectoryID = ExamineDirectory(#PB_Any, PS_PluginPath, "*.dll") ;Pluginordner durchkämmen und jede DLL laden
While NextDirectoryEntry(PS_PluginDirectoryID)
AddElement(plugins())
With plugins()
\libID = OpenLibrary(#PB_Any, PS_PluginPath + DirectoryEntryName(PS_PluginDirectoryID)) ;DLLs laden und Funktionen mit
\plugin_eventgadget = GetFunction(\libID, "plugin_eventgadget") ;Prototype in die Struktur speichern
\plugin_init = GetFunction(\libID, "plugin_init")
EndWith
Wend
Main_WindowID = OpenWindow(#PB_Any , 0, 0, 400, 300, "plugin test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ForEach plugins()
plugins()\plugin_init(WindowID(Main_WindowID)) ;Init-Funktion aller Plugins aufrufen.
Next
Repeat
WindowEvent = WaitWindowEvent(20)
Select WindowEvent
Case #PB_Event_Gadget
EventGadget = EventGadget()
Select EventGadget
Case -900 ;Irgendeinen Unsinn, damit "Default" funktioniert
Debug "..."
Default
ForEach plugins() ;EventGadget an alle Plugins weiterleiten, die selbst überprüfen,
plugins()\plugin_eventgadget(EventGadget) ;ob das EventGadget zum Plugin gehört
Next
EndSelect
EndSelect
Until WindowEvent = #PB_Event_CloseWindow
End
Testplugin, als DLL kompiliert und in den angegebenen Unterordner geschoben.
Code: Alles auswählen
;test.dll
Define button.i
ProcedureDLL plugin_init(hWnd.i)
Shared button
UseGadgetList(hWnd) ;Vom Hauptprogramm mitgeteilte GadgetList verwenden (Fenster oder auch ContainerGadget etc...)
button = ButtonGadget(#PB_Any, 0, 0, 100, 20, "Plugin")
EndProcedure
ProcedureDLL plugin_eventgadget(eventgadget.i)
Shared button
If eventgadget = button ;Das Plugin überprüft selbst, ob das EventGadget ein eigenes ist und führt entsprechend Code aus.
MessageRequester("Plugin","Button pushed")
EndIf
EndProcedure
Der Host erlaubt den Plugins Gadgets zu erstellen. Das sollte viel restriktiver sein, damit sich keine Gadgets von verschiedenen Gadgets überlagern. Aber oftmals öffnet sich für ein Plugin eh ein neues Fenster. Dann gibt es keine Probleme.
Wenn ein Gadget betätigt wird, wird die plugin_eventgadget() Funktion aufgerufen. Somit kann das Gadget reagieren. Das ist nicht sehr elegant, dafür einfach.
Man kann natürlich auch jedes vom Plugin erstelle Gadget an den Host senden, so dass dieser erstmal prüft zu welchem Plugin der Button gehört, bevor die entsprechende Pluginfunktion aufgerufen wird.
Man kann immer alles besser machen und sich natürlich fragen ob man ein System entwickeln will, dass sich auf Riesenanwendungen á la Photoshop hochskalieren lässt, oder ob man eher erstmal kleinere Brötchen backt.