In einem Ereignis Komponenten ansprechen



  • Hallo,

    ich habe mir meine eigene Klasse angelegt, die ich von TGroupBox abgeleitet habe. Dort habe ich nun ein Label,ein Button, ein Edit und eine ListBox.

    class TMyGroup : public TGroupBox
    {
        private:
            TLabel *Label1;
            TButton *Button1;
            TEdit *edit1;
            TListBox *ListBox1;
    
           void __fastcall MyButtonClick(TObject *Sender);
    
        public:
    
            __fastcall TMyGroupBox(TComponent *Owner);
    };
    

    Das anlegen der Objekte funktioniert wunderbar, nun möchte ich jedoch meine erste Funktion anlegen, nämlich MyButtonClick:

    void __fastcall TMyPanel::MyButtonClicked(TObject *Sender)
    {
    
    }
    

    Ich möchte gerne, dass nach dem Button Klick, der Text, der im Edit1->Text steht in die ListBox hinzufügen.

    Wie kann ich dieses machen? Ich kann ja nicht einfach die Komponenten mit ihren Namen ansprechen. Hat da jemand vielleicht ein kleines beispiel?

    Markus

    **
    [Edit] Bitte Code- Tags benutzen ! [/Edit]**

    [ Dieser Beitrag wurde am 17.05.2003 um 20:56 Uhr von AndreasW editiert. ]



  • Hi Markus

    Schreib' Dir 'ne Methode (public!!!), die das macht! Die Methode kann auf die private Members zugreifen.

    void TMyGroup::Edit2List(void) //im Header bei public
    {
      ListBox1->Add(edit1->Text);
    }
    

    **
    [Edit] Bitte Code- Tags benutzen ! [/Edit]**

    [ Dieser Beitrag wurde am 17.05.2003 um 20:55 Uhr von AndreasW editiert. ]



  • Hallo,

    das war nicht ganz meine Frage. Bevor ich anfing meine Klasse zu schreiben, habe ich mit folgendem Code zum üben angefangen:

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    anz++;
    TButton *MyButton = new TButton(this);
    MyButton->Parent = this;
    MyButton->Left = 100 * anz;
    MyButton->Top = 100;
    MyButton->Tag = 100;
    MyButton->OnClick = ButtonClick;   
    MyButton->Caption = Edit1->Text;
    MyButton->Visible = true;
    MyButton->UpdateControlState();
    }
    
    void __fastcall TForm1::ButtonClick(TObject *Sender)
    {
       ShowMessage(static_cast<TButton*>(Sender)->Caption);
    }
    

    In der zweiten kann ich ja nicht

    ShowMessage(MyButton->Caption);
    

    schreiben. Hier muss ich casten.

    Bei meiner Klasse habe ich festgestellt, muss ch nicht casten, da kann ich direkt auf die Komponenten zugreifen.

    Kan man nun pauschal sagen, dass man bei den Klassen nicht casten braucht, sondenr nur wenn man einzelne Objekte zur Laufzeit erzeugt?

    markus

    **
    [Edit] Bitte Code- Tags benutzen ! [/Edit]**

    [ Dieser Beitrag wurde am 17.05.2003 um 20:56 Uhr von AndreasW editiert. ]



  • Leute: Ich möchte euch innigst bitte doch die Code- Tags zu benutzen.
    Quellcode ist ansonsten echt schwer zu lesen. Ich lese mir zum Beispiel Code, der nicht in Code- Tags geschreiben wurde gar nicht erst durch, womit ich nicht der einzigste bin....



  • Hi nochmal,

    @ <Markus Schneider> :

    du hast noch grundsätzliche Probleme mit C++, die du mit Hilfe eines C++- Tutiorials in den Griff bekommen könntest.

    Wenn du Komponenten entwickeln möchtest, so schau mal in meiner Signatur. C++ solltest du aber schon können...



  • Original erstellt von <Markus Schneider>:
    **
    Kan man nun pauschal sagen, dass man bei den Klassen nicht casten braucht, sondenr nur wenn man einzelne Objekte zur Laufzeit erzeugt?
    **

    Nein!

    In der Klasse kannste auf alle Members direkt zugreifen (Variable), die sind ja in Klasse bekannt!

    In Deinem OnClick greifst Du ueber den Parameter Sender zu - das ist ein void* Zeiger - Du musst casten, damit der Compiler weis, welchen Typ du meinst!



  • Hi,

    mit C++ komme ich sonst eigentlich sehr gut zurecht, jedoch arbeite ich das erste mal an einem komplizierteren Ding, wo ich ne eigene Klasse benötige und damit beliebige Objekte erstelle, die der Benutzer alle individuell bearbeiten kann. Einzelne Probleme tauchen halt immer auf.

    An einem guten Tutorial hätte ich schon interesse, aber an keinem, welches von vorne angängt, sondern ein einem, welches ein ganzes Stück später anfängt.

    Markus



  • Original erstellt von DerAltenburger:
    **
    In Deinem OnClick greifst Du über den Parameter Sender zu - das ist ein void* Zeiger - Du musst casten, damit der Compiler weis, welchen Typ du meinst!**

    TObject ist mit Sicherheit kein void* - Zeiger sondern eine Klasse !
    Alle VCL- Klassen sind indirekt von TObject abgeleitet. Deshalb lässt sich jede VCL- Klasse nach TObject casten. Um eine gewisse Typsicherheit zu gewährleisten nimmt man dafür in der Regel dynamic_cast weil dynamic_cast überprüft, ob die Typ- Paarung in der Hierarchie des Cast- Zieles castbar ist und somit eine Typprüfung vornimmt.
    somit halte ich :

    void __fastcall TForm1::ButtonClick(TObject *Sender)
    {
       ShowMessage(static_cast<TButton*>(Sender)->Caption);
    }
    

    für überarbeitbar.

    In den Ereignissen soll das aktuelle Objekt zurückgegeben werden. Es wäre nun unnötig aufwendig ein Ereignistyp für jede Klasse anzulegen. Deshalb einigt man sich auf den kleinsten gemeinsamen Nenner. Und das ist TObject. Da alle Klassen nach TObject castbar sind, ist das die einfachste und sicherste Methode den Sender zu übergeben.

    Deshalb muss man in den Ereignissen casten.

    [ Dieser Beitrag wurde am 17.05.2003 um 21:37 Uhr von AndreasW editiert. ]



  • So, nun zur Klasse. Ich versuch mal Starthilfe zu geben:

    class PACKAGE TMyGroup : public TGroupBox  // Wenns ne Kompo werden sol muss PACKAGE davor, damit die Kompo aus dem Package geladen werden kann
    {
        private:
            TLabel *Label1; // Hab mal nur das Label dringelassen
            //TButton *Button1;
            //TEdit *edit1;
            //TListBox *ListBox1;
    
           void __fastcall MyButtonClick(TObject *Sender);
           void __fastcall SetLabel(TLabel* ALabel){Label1=ALabel;}
           TLabel* __fastcall GetLabel(){return Label1;}
        public:
    
            __fastcall TMyGroupBox(TComponent *Owner)
                 {
                   Label1=new TLabel(this);
                   Label1->Name="Label"; // wichtig für die Regristrierung als SubComponent, da es da ein Bug gibt, der von Borland nohc nicht gefixt wurde.. 
                   Label1->Parent=this;
                   Label1->SetBounds(10,10,100,20);
                   Label1->Caption="Hallo";
                   Label1->SetSubComponent(true); // sorgt dafür, dass die Kompo als Sub- Komponente regristriert wird.
    
                 };
    __fastcall ~TMyGroupBox(){delete Label1;}
    __published: // Der Bereich, welcher später in Objektinspector erscheint. Wenn keine Kompo kannste auch public nehmen.
    
    __property TLabel* Label={read=GetLabel,write=SetLabel};
    
    };
    

    ungetestet....

    Ansonsten siehe Signatur...


Anmelden zum Antworten