Plugins Support - nur wie? (TFont kann nicht zu TFont zugewiesen werden)



  • Hallo,

    ich möchte mal testen eine Anwendung zu schreiben, die ich mit PlugIns
    erweitern kann.

    Ich hab leider keine Idee wie ich anfangen könnte. Programmiert hab ich
    schon viel mit dem Borland Builder 6, aber hier steh ich echt auf dem
    Schlauch.

    Das Plugin sollte mir z.B. in einer MDI-Form ein neues Fenster mit einem
    Knopf erstellen. Hat jemand ein solches Beispiel / Tutorial dafür oder
    kann mir einen Rat geben womit ich anfangen kann?

    Vielen Dank schonmal!



  • also der akutelle Status sieht so aus:

    So wie ich das sehe ist das ganze nur per dll's machbar, also hab ich das hier
    versucht:

    In dem Projekt:

    typedef void TDoNothing(TPanel *);
    void DoNothing(TPanel * MyPanel);
    
    void DoNothing(TPanel * MyPanel)
    {
        TDoNothing* DoNothing; 
        HINSTANCE h = LoadLibrary("Project2.dll"); 
    
        if (h != 0) {
            DoNothing = (TDoNothing*)GetProcAddress(h, "_DoNothing");
            if (SubVals != NULL) {
            	DoNothing(MyPanel);
            }
            FreeLibrary(h); //DLL freigeben.
        }
    }
    

    und in der dll:

    extern "C" __declspec(dllexport) void DoNothing(TPanel *MyPanel)
    {
        MyPanel->Caption = "hallo"; // <- das hier klappt noch
    
        TButton * NewButton = new TButton(MyPanel);
        NewButton->Parent = MyPanel;
        NewButton->Caption = "hurrai";
    }
    

    leider kommt dann eine sehr merkwürdige Fehlermeldung:
    "TFont kann nicht zu TFont zugewiesen werden".

    Wie kann ich auf dem Panel wirklich einen neuen Knopf und andere Steuerelemente
    anlegen?



  • hat sowas wirklich noch keiner gemacht? Ich finde echt nichts über PlugIn
    Programmierung mit dem BCB 6 😞



  • Schau dir mal das hier an:

    http://bcb-tutorial.c-plusplus.net/DLL_Tutorial/index.html

    Hab' damit auch meine ersten DLL's programmiert...



  • inzwischen funktioniert es 🙂 🙂 🙂

    wenn Interesse besteht kann ich auch mal ein kleines Beispiel machen
    wie man PlugIn's für seine eigenen Programme schreibt und verwendet.
    Ist eigentlich recht einfach.

    Danke für den Link Dasd



  • PluginHeader.h

    Hier ist die Deklaration der Plugin Schnittstelle. Diese sollten alle
    Plugin Entwickler kennen. Und diese muss auch in jedes Plugin included
    werden.

    #include <vcl.h>
    
    class myPlugIn: public TObject
    {
    public:
        virtual void Execute(int a, int b) = 0;
        virtual bool ReadBytes(int iBytes, char * cData) = 0;
    };
    

    CPlugins.h

    CPlugins.h und CPlugins.cpp sind ein kleiner Bonus. Diese Klasse
    handelt mehrere Plugins und erstellt entsprechende Menüs im Hauptprogramm.

    #include <vcl.h>
    #include "PluginHeader.h"
    typedef struct TFiledata
    {
      String Name;
      String Path;
      TSearchRec Data;
    }tFiledata;
    
    typedef tFiledata* pFiledata;
    
    class CPlugins {
        private:
            void __fastcall CPlugins::GetPluginList(TList*Liste, String StartDirectory, String Extention);
        public:
            __fastcall CPlugins::CPlugins();
            void __fastcall ShowPlugins(TMenuItem * MenuItem);
            void __fastcall CPlugins::StartPlugin(AnsiString PluginName);
    };
    

    Cplugins.cpp

    #include "CPlugins.h"
    #include "PluginHeader.h"
    
    void __fastcall CPlugins::ShowPlugins(TMenuItem * MenuItem) 
    { 
        TList*FileList = new TList; 
        GetPluginList(FileList, "Plugins\\", "*.dll"); 
    
        pFiledata Item; 
        for(int i = 0; i < FileList->Count; i++) { 
            Application->ProcessMessages(); 
            Item = (pFiledata)FileList->Items[i]; 
    
            TMenuItem *newMenuItem = new TMenuItem(MenuItem); 
            newMenuItem->Caption = Item->Name.SubString(1, Item->Name.Length() - 4); 
            MenuItem->Add(newMenuItem); 
            delete Item; 
        } 
    
        delete FileList; 
    } 
    
    void __fastcall CPlugins::GetPluginList(TList*Liste, String StartDirectory, String Extention) 
    { 
        TSearchRec sr; 
        String Directory; 
        int result = FindFirst((StartDirectory + Extention).c_str(), faReadOnly|faHidden|faDirectory, sr ); 
    
        while(result == 0) { 
            Application->ProcessMessages(); 
    
            if((sr.Attr & faDirectory)) { // ist ein Verzeichnis 
            } else {  // ist normale Datei 
                pFiledata Item = new tFiledata; 
                Item->Name = sr.Name; 
                Item->Path = StartDirectory; 
                Item->Data = sr; 
                Liste->Add(Item); 
            } 
            result=FindNext(sr); 
        } 
        FindClose(sr); 
    } 
    
    void __fastcall CPlugins::StartPlugin(AnsiString PluginName) 
    { 
        typedef myPlugIn* TCreatePluginObject(void);
        TCreatePluginObject* CreatePlugInObject;
    
        PluginName = "Plugins\\" + PluginName; 
    
        HINSTANCE h = LoadLibrary(PluginName.c_str()); //DLL laden. 
        myPlugIn* MyPlugin;
        if (h != 0) { 
            CreatePlugInObject = (TCreatePluginObject*)GetProcAddress(h, "@CreatePlugInObject$qv"); 
        } else { 
            ShowMessage("DLL Not found"); 
            return; 
        } 
        if (CreatePlugInObject != NULL) { 
            MyPlugin = CreatePlugInObject(); 
        } else { 
            ShowMessage("Objekt not created"); 
            return; 
        } 
    
        // DLL ist nun geladen und kann verwendet werden. 
    
        MyPlugin->Execute(1, 2); 
    
        // irgendwann auch wieder löschen. 
        delete MyPlugin; 
    }
    

    Beispiel Plugin, myPlugin.cpp
    Wird erstellt über Datei / neu / weiter -> DLL Experte

    #include <vcl.h>
    #include <windows.h>
    #pragma hdrstop
    #include "PluginHeader.h"
    
    #pragma argsused
    
    class CTestPlugin: public myPlugIn
    {
    __published:
    private:
    public:
        void Execute(int a, int b);
        bool ReadBytes(int iBytes, char * cData);
    };
    
    void CTestPlugin::Execute(int a, int b)
    {
        ShowMessage(a);
        ShowMessage(b);
    }
    
    bool CTestPlugin::ReadBytes(int iBytes, char * cData)
    {
         return false;
    }
    
    __declspec(dllexport) myPlugIn* CreatePlugInObject()
    {
        return new CTestPlugin;
    }
    
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
        return 1;
    }
    

    das war auch schon alles 😉 viel Spaß beim programmieren.



  • Habe etwas aufgeräumt und die "Push"-Beiträge gelöscht.

    Es wäre nett, wenn mal jemand das Beispiel nachvollzieht bzw. eine Rückmeldung gibt, so dass eventuelle Fragen oder Verbesserungsvorschläge diskutiert werden können, bevor der Thread in die FAQ kommt.



  • Ich möchte das mit den PlugIns jetzt auch mal ausprobieren und damit herumtesten.
    Aber er sagt mir in der Cplugins.cpp immer Undefiniertes Symbol 'pFiledata'. Was habe ich vergessen?



  • @pug habs hinzugefügt. Hatte die Deklaration vergessen.



  • Irgendwie habe ich auch noch ein Problem mit dieser Zeile.

    typedef SPCGFXPlugIn* TCreatePluginObject(void);
    


  • *schieb*

    Gibt immer noch den Fehler Undefiniertes Symbol 'TCreatePluginObject'



  • versuch es jetzt nochmal. Müsste nun gehen. Ich hatte einen Klassennamen anders
    benannt wie bei mir.



  • Vielen Dank. So funktioniert alles.


Anmelden zum Antworten