Auf OnClick-Event in einer DLL reagieren



  • Hallo,

    ich brauche unbedingt mal EURE Hilfe. Irgendwie stehe ich auf dem Schlauch.

    Ich erzeuge zur Laufzeit in einer "dynamisch" eingebundenen DLL ein Formular und auf dem Formular einen Button.
    Bis dahin alles kein Problem.

    Nun möchte ich gerne auf ein "OnClick-Event" des Buttons reagieren.
    Und das möchte in der DLL einfach nicht klappen.

    extern "C" __declspec(dllexport) int Test(void);
    void MyButtonClick(TObject *Sender);
    
    int Test(void)
    {
    TForm *MyForm = new TForm(Application);
    TButton *MyButton = new TButton(Application);
    
    	MyForm->Width = 300;
    	MyForm->Height = 300;
    	MyForm->Position = poDesktopCenter;
    	MyForm->Visible = true;
    
    	MyButton->Name = "TMyButton1";
    	MyButton->Top = 10;
    	MyButton->Left = 10;
    	MyButton->Height = 25;
    	MyButton->Width = 75;
    	MyButton->Show();
    	MyButton->Parent = MyForm;
    	MyButton->OnClick = MyButtonClick;  [b]<== Hier ist das Problem![/b]
    }
    
    //---------------------------------------------------------------------------
    void MyButtonClick(TObject *Sender)
    {
    	ShowMessage("KLICK");
    }
    

    Als Fehlermeldung bekomme ich dann das:
    *[C++ Fehler] FormChange_.cpp(71): E2034 Konvertierung von 'void (*)(TObject )' nach 'TNotifyEvent' nicht möglich. 😞

    Mache ich das auf die gleiche Weise in meiner EXE-Datei, funktioniert das
    einwandfrei.
    Aber warum?! Und wie kann ich das lösen?

    Ich hoffe ihr könnt mir helfen.

    Vielen Dank.

    Gruß
    Andreas



  • void __fastcall !!!

    EDIT: TNotifyEvent <- void __fastcall XYZ(TObject* Sender);



  • Hi,

    danke für deine schnelle Antwort.

    Ich habe zwei Sachen ausprobiert, leider ohne Erfolg:

    extern "C" __declspec(dllexport) int Test(void);
    [b]void __fastcall[/b] MyButtonClick(TObject *Sender);
    
    int Test(void)
    {
    TForm *MyForm = new TForm(Application);
    TButton *MyButton = new TButton(Application);
    
        MyForm->Width = 300;
        MyForm->Height = 300;
        MyForm->Position = poDesktopCenter;
        MyForm->Visible = true;
    
        MyButton->Name = "TMyButton1";
        MyButton->Top = 10;
        MyButton->Left = 10;
        MyButton->Height = 25;
        MyButton->Width = 75;
        MyButton->Show();
        MyButton->Parent = MyForm;
        MyButton->OnClick = MyButtonClick;  [b]<== Hier ist das Problem![/b]
    }
    
    //---------------------------------------------------------------------------
    [b]void __fastcall[/b] MyButtonClick(TObject *Sender)
    {
        ShowMessage("KLICK");
    }
    

    hierbei bekomme ich diesen Fehler:
    **[C++ Fehler] FormChange_.cpp(65): E2034 Konvertierung von 'void (_fastcall )(TObject )' nach 'TNotifyEvent' nicht möglich

    und ich habe es so probiert:

    extern "C" __declspec(dllexport) int Test(void);
    [b]TNotifyEvent __fastcall[/b] MyButtonClick(TObject *Sender);
    
    int Test(void)
    {
    TForm *MyForm = new TForm(Application);
    TButton *MyButton = new TButton(Application);
    
        MyForm->Width = 300;
        MyForm->Height = 300;
        MyForm->Position = poDesktopCenter;
        MyForm->Visible = true;
    
        MyButton->Name = "TMyButton1";
        MyButton->Top = 10;
        MyButton->Left = 10;
        MyButton->Height = 25;
        MyButton->Width = 75;
        MyButton->Show();
        MyButton->Parent = MyForm;
        MyButton->OnClick = MyButtonClick;  <== Hier ist das Problem!
    }
    
    //---------------------------------------------------------------------------
    [b]TNotifyEvent __fastcall[/b] MyButtonClick(TObject *Sender)
    {
        ShowMessage("KLICK");
    }
    

    und dann bekomme ich diesen Fehler:
    [C++ Fehler] FormChange_.cpp(65): E2034 Konvertierung von 'TNotifyEvent' nach 'TNotifyEvent' nicht möglich

    Beides funktioniert leider nicht 😕

    Hast du da vielleicht noch eine Idee zu?!

    Danke

    Gruß
    Andreas



  • extern "C" __declspec(dllexport) int Test(void);
    void __fastcall MyButtonClick(TObject *Sender);
    
    int Test(void)
    {
        TForm *MyForm = new TForm(Application);
        TButton *MyButton = new TButton(Application);
    
        MyForm->Width = 300;
        MyForm->Height = 300;
        MyForm->Position = poDesktopCenter;
        MyForm->Visible = true;
    
        MyButton->Name = "TMyButton1";
        MyButton->Top = 10;
        MyButton->Left = 10;
        MyButton->Height = 25;
        MyButton->Width = 75;
        MyButton->Show();
        MyButton->Parent = MyForm;
        MyButton->OnClick = &MyButtonClick; // <- hier
    }
    
    //---------------------------------------------------------------------------
    void __fastcall MyButtonClick(TObject *Sender)
    {
        ShowMessage("KLICK");
    }
    

    & nicht vergessen 😉 Ich hoffe das wars



  • Hi,

    nein, das mit dem & funktioniert auch nicht. 😞

    Fehlt mir vielleicht irgendein include oder so?

    #include <windows.h>
    #include <vcl.h>
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    

    Finde das total komisch. Kein einziges Event funktioniert.

    Das einzige was funktioniert, wenn ich eine Variable vom Typ
    TNotifyEvent deklariere.

    Dann gibt es keine Fehlermeldung beim Compilieren.

    TNotifyEvent OnClick;
    MyButton->OnClick = OnClick; [b]<== Das funktioniert zwar, aber...[/b]
    

    ...ich muss ja auch irgendwie eine Methode haben, die beim Event aufgerufen wird. Wie soll das gehen?
    Sehr undurchsichtig..... 😕

    Gruß
    Andreas



  • Hallo Andreas,

    die OnClick-Funktion muß sich in einer Klasse befinden (d.h. nicht als freie Funktion).
    Alle Events sind sog. Closures, d.h. sie arbeiten intern mit einem Klassenobjekt.



  • Hallo Th69,

    die OnClick-Funktion muß sich in einer Klasse befinden (d.h. nicht als freie Funktion).

    .....das war genau das was ich gesucht habe. 👍 😃

    Das Herumprobieren hat mich etwa 2 Jahre meines Lebens gekostet. 😃
    Und wie immer ist es eigentlich ganz einfach wenn man weiß wie es funktioniert.

    Und für alle die es interessiert ist hier ist nun mein kompletter - und vor allem voll funktionstüchtiger Code - meiner DLL.

    Das soll übrigens das Grundgerüst für eine Plugin-Schnittstelle werden.

    //**********************************************************
    // Auf Events in einer DLL reagieren
    //**********************************************************
    
    #include <windows.h>
    #include <vcl.h>
    #include <Classes.hpp>
    #include <Controls.hpp>
    #include <StdCtrls.hpp>
    #include <Forms.hpp>
    
    //**********************************************************
    // Externe Funktionen für DLL-Export deklarieren
    //**********************************************************
    //Initialisierungs-Funktion ( beim ersten Aufruf der DLL )
    extern "C" __declspec(dllexport) TStringList * init(TForm *Form, TMainMenu *Menu);
    //Arbeits-Funktion
    extern "C" __declspec(dllexport) int ShowForm(void);
    
    //---------------------------------------------------------------------------
    
    //DLL Einsprungspunkt
    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
    {
    	return 1;
    }
    
    //**********************************************************
    // Meine eigene Event-Klasse
    //**********************************************************
    class TMyEventClass
    {
    protected:
    private:
    public:
       //Constructor
       TMyEventClass(void);
       //Destructor
       ~TMyEventClass(void);
    
       //Methoden
       void __fastcall OnClick(TObject *Sender);
       void __fastcall OnClose(TObject *Sender, TCloseAction &Action);
    
       //Variablen usw.
       TForm *MyForm;
       TButton *MyButton;
    };
    
    //**********************************************************
    //Globalen Zeiger auf meine Event-Klasse erzeugen
    //**********************************************************
    TMyEventClass *MyEvent = new TMyEventClass;
    
    //**********************************************************
    //Constructor
    //**********************************************************
    TMyEventClass::TMyEventClass (void)
    {
    	MyForm = new TForm(Application);
    	MyButton = new TButton(Application);
    }
    
    //**********************************************************
    //Destructor
    //**********************************************************
    TMyEventClass::~TMyEventClass (void)
    {
    	delete MyForm;
    	delete MyButton;
    }
    
    //**********************************************************
    //Exportierte Initialisierungs-Funktion ( beim ersten Aufruf der DLL )
    //**********************************************************
    TStringList * init(TForm *Form, TMainMenu *Menu)
    {
    TStringList *List = new TStringList();
    
    	//Mit der Stringlist kann alles mögliche
    	//zurückgegeben werden.
    	//In meinem Fall der Name meiner Arbeitsfunktion
    	List->Add("Formular anzeigen");
    	List->Add("_ShowForm");
    
    	return(List);
    }
    
    //**********************************************************
    //Exportierte Arbeits-Funktion
    //**********************************************************
    int ShowForm(void)
    {
    	MyEvent->MyForm->Width = 300;
    	MyEvent->MyForm->Height = 300;
    	MyEvent->MyForm->Position = poDesktopCenter;
    	MyEvent->MyForm->Visible = true;
    	MyEvent->MyForm->OnClose = MyEvent->OnClose;
    
    	MyEvent->MyButton->Name = "TMyButton1";
    	MyEvent->MyButton->Top = 10;
    	MyEvent->MyButton->Left = 10;
    	MyEvent->MyButton->Height = 25;
    	MyEvent->MyButton->Width = 75;
    	MyEvent->MyButton->Show();
    	MyEvent->MyButton->Parent = MyEvent->MyForm;
    	MyEvent->MyButton->OnClick = MyEvent->OnClick;
    
    	return (0);
    }
    
    //**********************************************************
    // Methoden meiner Event-Klasse
    //**********************************************************
    void __fastcall TMyEventClass::OnClick(TObject *Sender)
    {
    	ShowMessage("KLICK");
    }
    
    //---------------------------------------------------------------------------
    
    void __fastcall TMyEventClass::OnClose(TObject *Sender, TCloseAction &Action)
    {
    	ShowMessage("Form schließen");
    }
    
    //---------------------------------------------------------------------------
    

    Vielen Dank für deine Unterstützung.

    Gruß
    Andreas



  • Gismo2007 schrieb:

    Das Herumprobieren hat mich etwa 2 Jahre meines Lebens gekostet. 😃

    In der Zeit hättest du die Dokumentation etwa fünfmal durchlesen können. Dann hättest du es auch gewußt 😉


Anmelden zum Antworten