zur laufzeit generierten button ansprechen



  • ich schaff es einfach nicht einem zur laufzeit generiertem button einen event zuzuweisen. hab mich streng an die faq gehalten, aber es funktioniert einfach nicht.

    Indem du z.B. bei einem button OnClick die Einsprungadresse zuweist:

    Button1->OnClick = OnButton1Click;

    wobei irgendwo da steht:

    void __fastcall TForm1::OnButton1Click(TObject *Sender)
    {
    ...
    }

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-39206.html

    weiss jemand wieso es nicht geht?



  • Was junix schrieb ist vollkommen richtig. Zeig am Besten mal Deinen Quellcode.



  • void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      TButton*Button2 = new TButton(Application);
      Button2->Parent = Form1;
      Button2->Height = 50;
      Button2->Width = 100;
      Button2->OnClick = OnButton2Click;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::OnButton2Click(TObject *Sender)
    {
    
    }
    

    kann es sein, dass ich das zeugs einfach am falschen ort habe?



  • Du hast alles richtig gemacht, vermutlich aber nur vergessen, OnButton2Click zu deklarieren:

    In der Headerdatei sollte stehen:

    ...
    class TForm1 : public TForm
    {
    __published:	// IDE-managed Components
            TButton *Button1;
            void __fastcall Button1Click(TObject *Sender);
            void __fastcall OnButton2Click(TObject* Sender); /* hier wird Deine Ereignisbehandlungsroutine
     des dynamischen Buttons deklariert */
    private:	// User declarations
    public:		// User declarations
            __fastcall TForm1(TComponent* Owner);
    
    };
    ...
    


  • kann ich die deklaration auch während der laufzeit machen?



  • Überleg mal selber; macht das Sinn?



  • wie deklarier ich denn events für arrays von komponenten?



  • Auf dem gleichen Wege durch einfache Zuweisung über den Array-Operator []
    also z.B.:

    ...
    for(int x = 0; x <= 25; x++)
           {
             myObject[x]              = new TObject(Formx);
             myObject[x]->Parent      = Formx;
             myObject[x]->OnMouseMove = myObjectMouseMove;
             myObject[x]->OnClick     = myObjectOnClick;
             myObject[x]->Caption     = IntToStr(x)
             myObject[x]->Name        = "myObject" + IntToStr(x);
           }
    ...
    
    void __fastcall Formx::myObjectOnClick(TObject* Sender)
    {
      DoSomething();
    }
    

    Über Sender kann man später auswerten, welche Komponente das Ereignis ausgelöst hat.



  • Über Sender kann man später auswerten, welche Komponente das Ereignis ausgelöst hat.

    wie geht das?
    (sorry, bin ein ziemlicher noob was das programmieren anbelangt...)



  • Für einen Button könnte das so aussehen:

    void __fastcall Formx::ChangeButtonCaption(TObject* Sender)
    {
      ((TButton*)Sender)->Caption = "neue Caption";
    }
    
    // Aufruf der Funktion
    
    ...
    Button1->Caption = "alte Caption";
    ChangeButtonCaption(Button1);
    ...
    

    Jetzt könntest Du einem Array aus z.B. Button-Steuerelementen eine einzige Ereignisbehandlungroutine für OnClick zuweisen, aber wüsstest immer genau, welcher Button diese Routine aufgerufen hat.



  • hab mal etwas anderes probiert. ich weise allen buttons den gleichen onclick event zu:

    void __fastcall TForm1::ButtonClick(TObject *Sender)
    {
      ((TButton*)Sender)->Caption = "Text";
    }
    

    bei buttons, die schon von anfang an drin sind funktioniert das tiptop, jedoch zur laufzeit generierte buttons sprechen auf den befehl (TButton*)Sender)->Caption nicht an. wieso?



  • Doch, das sollte eigentlich problemlos funktionieren, egal ob die Steuerelemente zur Design,- oder Laufzeit erstellt werden. Poste mal Deinen relevanten Code.



  • hat sich jetzt gelöst das problem (hatte ein flüchtigkeitsfehler im progr.-text).
    das einzige problem, das ich jetzt noch habe, ist mit den arrays. ich habe folgenden programmtext:

    void __fastcall TForm1::ButtonClick(TObject *Sender)
    const int x = 10;                                  //beispiel aus faq
    TImage *img[x];
    
    for (int i = 0; i < x; i++)
    {
      img[i] = new TImage(this);
      img[i]->Parent = this;
      img[i]->Width = 32;
      img[i]->Height = 32;
      img[i]->Top = i * 35;
      img[i]->Show();
      img[i]->Canvas->Brush->Color = clWhite; // nur zum Test
      img[i]->OnClick = imgClick;
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::imgClick(TObject *Sender)
    {
      ((TImage*)Sender)->Width = 120;
    }
    

    eigentlich sollte jetzt sich jetzt beim klicken auf eines der images die grösse ändern, aber es passiert nichts...



  • probier mal bei Deinem Array TImage::AutoSize auf false zu setzen.



  • hat nichts genutzt.

    edit: gibt es eigentlich eine funktion die einfach alle veränderungen die während des benützens des programms angefallen sind abspeichert?



  • Dann prüfe mal mit dem Debugger Deinen Programmablauf und ob Deine eigene Routine überhaupt angesprungen wird.



  • sie wird angesprungen.
    ausserdem funktionieren ja andere befehle. (zb top oder so)



  • Das Bild ist anschliessend 120 Pixel breit, wie du leicht prüfen kannst, wenn du statt TImage z.B. mal TPanel verwendest.



  • super, hast recht gehabt.


Anmelden zum Antworten