Messages
-
Hallo erstmal
Ich baue grad an einer Komponente, welche von TPanel abgeleitet ist. Auf dieses Panel werden mehrere Labels nebeneinander gelegt so das es völlig bedeckt ist. Wird jetzt mit dem Event OnMousDown auf ein Label geklickt bekommt das Panel dies logischerweise nicht mit.
Wie kann das Panel diese Nachricht auch bekommen, ohne das es vom Kind (dem Label) darüber informiert wird (also wie: Parent->IchWurdeGeklickt(Label)) ??
Ich dachte bis jetzt immer Windows schickt die Nachrichten auf folgendem Weg
Win -> Form -> Panel -> Label
ist aber woll nicht so ???Vielen Dank schon mal
-
Was willst du damit erreichen?
-
Also wie schon gesagt mehrere Labels auf einem Panel.
Wird ein Label_1 gedrückt, verändert sich jetzt einfach gesagt die Farbe der anderen Label (_2 und _3).So der normale Weg wäre jetzt in Label_1 irgendetwas wie
Label_1->Parent->Label_2->ÄndereFarbe();
Aber das ist doch wie von Pontius zu Pilatus zu gehen.
Außerdem muss ich da in der Label_1.cpp die MyPanel.h includieren und eine Instanz von MyPanel dann als global in der Label_1.cpp deklarieren, damit die Funktion ÄndereFarbe() bekannt gemacht wäre.Und das finde ich ist dann schon fast Spagetti-Code
Ich weis nicht ob ich mich da irre, vielleicht gibt es ja noch einen anderen Weg??
-
Für alle labels OnClick auf die Routine setzen
void __fastcall TForm1::Label1Click(TObject *Sender) { TWinControl* c = ((TControl*)Sender)->Parent; for (int i = 0; i < c->ControlCount; i++) { if (c->Controls[i] != Sender) ((TLabel*)c->Controls[i])->Color = clRed; } ((TLabel*)Sender)->Color = clGreen; } //---------------------------------------------------------------------------
-
Danke für deine Lösung die funktioniert einwandfrei...
Aber jetzt kommt das aber, wenn ich die Komponente dynamisch erzeuge komme ich immer in eine blöde Situation. In der ich entweder mein Event durchgereicht bekomme wenn ich in Spagetti-Code übergehe oder es bekommen nur die Labels die Nachricht.Hier erstmal ne Menge Code der mein Problem noch etwas erläutern soll
Das Form sieht wie folgt aus
//** Unit1.cpp //-- Konstruktor __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { TMyKompo *MeineKompo; MeineKompo = new TMyKompo(this); } //** Unit1.h #include "MyKompo.h"
Und die Komponente
/** MyKompo.cpp //--------------------------------------------------------------------------- // KONSTRUKTOR //--------------------------------------------------------------------------- __fastcall TMyKompo::TMyKompo(TComponent* Owner): TPanel(Owner) { Parent = (TWinControl*)Owner; TForm *Formular = (TForm*)Owner; if (Parent) { //** Fürs Auge Height = 250; Width = 400; // SubKompo1 erzeugen SubKompo1 = new TSubKompo(this); SubKompo1->Parent = this; SubKompo1->Align = alBottom; SubKompo1->Color = clRed; // SubKompo2 erzeugen SubKompo2 = new TSubKompo(this); SubKompo2->Parent = this; SubKompo2->Align = alClient; SubKompo2->Color = clBlue; // Tasten zuerst auf Form und Komponente hat den Focus Formular->KeyPreview = true; Formular->ActiveControl = this; } } //--------------------------------------------------------------------------- // DESTRUKTOR //--------------------------------------------------------------------------- __fastcall TMyKompo::~TMyKompo() { delete SubKompo1; SubKompo1 = 0; delete SubKompo2; SubKompo2 = 0; } //** MyKompo.h #include <vcl.h> #include "SubKompo.h" class TMyKompo : public TPanel { public: __fastcall TMyKompo(TComponent* Owner); // Konstruktor __fastcall ~TMyKompo(); // Destruktor TSubKompo *SubKompo1; TSubKompo *SubKompo2; };
Nun noch die SubKomponente
//** SubKompo.cpp //--------------------------------------------------------------------------- // KONSTRUKTOR //--------------------------------------------------------------------------- __fastcall TSubKompo::TSubKompo(TComponent* Owner): TLabel(Owner) { Parent = dynamic_cast<TPanel*>(Owner); //-- Gibt es einen Parent? if (!VarIsNull(Parent)) { OnMouseDown = Parent->OnMouseDown; } }
Und jetzt beachte mal die Zeile:
OnMouseDown = Parent->OnMouseDown;Das führt zu dem Fehler:
Zugriff auf TControl::OnMousDown nicht MöglichSo der nächste Schritt wäre jetzt die MyKompo.h in die SubKompo.cpp mit einzubinden und eine Instanz davon (also: TMyKompo *MyParentKompo;) global vorzuhalten. Und damit Willkommen im Spagetti-Code.
Gibt es noch eine andere Lösung ???
Das MyKompo das Event direkt vom Form bekommt, denn die Eventsteuerung soll eigentlich von MyKompo ausgehen anstatt von SubKompo.
-
__fastcall TSubKompo::TSubKompo(TComponent* Owner): TLabel(Owner) { Parent = dynamic_cast<TPanel*>(Owner); //-- Gibt es einen Parent? if (Parent) { OnMouseDown = ((TPanel*)Parent)->OnMouseDown; } }
-
Wozu der zweite Cast? Entweder Parent ist bereits vom Typ TPanel (dynamic_cast) oder es ist NULL/false!?
-
Danke und leider auch wieder aber...
Der Code ist jetzt so abgeändert wie du es geposted hast. Schön erstmal kein Fehler mehr, aber leider auch keine Reaktion.Folgende Code Änderungen:
in MyKompo.cpp
// im Konstruktor if (Parent) { OnMouseDown = MyOnMouseDown; } // außerhalb und weiter unten void __fastcall TMyKompo::MyOnMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { ShowMessage("Hier"); }
in der SubKompo.cpp
// ebenfalls im Konstruktor if (Parent) { OnMouseDown = Parent->OnMouseDown; }
Problem ist das die Parent-Methode MyOnMouseDown nie erreicht wird.
Kann mir einer nochmal erklären wie die Ereignisse von Windows durchgereicht werden??
Oder bekommt immer nur das oberste Objekt die Ereignisse und nicht der Vater??
Und warum pssiert mit dem Code da nix??
-
@Jansen Duhast Recht
@Möre Hast du denn Parent->OnMouseDown irgend eine Routine zugewiesen? Ist Parent->OnMouseDown vielleich == NULL?
-
Danke, vielen Dank Xqgene für deine letzte Bemerkung. Deine Lösung funktioniert natürlich, der Fehler lag auf meiner Seite. Ich hab die Ereignisroutine, erst nachdem ich die Kinder erzeugt hatte dem Vater zugewiesen und das kann ja dann nicht gehen.
Sorry.Ich stell hier nochmal die Komplettlösung rein:
Problem: Ereignis vom Kind an den Vater übergeben.
Lösung:die Vater-Komponente
//** MyKompo.cpp //--------------------------------------------------------------------------- // KONSTRUKTOR //--------------------------------------------------------------------------- __fastcall TMyKompo::TMyKompo(TComponent* Owner): TPanel(Owner) { Parent = (TWinControl*)Owner; TForm *Formular = (TForm*)Owner; if (Parent) { //** Fürs Auge Height = 250; Width = 400; //-- HIER OnMouseDown = MyOnMOuseDown; // SubKompo1 erzeugen SubKompo1 = new TSubKompo(this); SubKompo1->Parent = this; SubKompo1->Align = alBottom; SubKompo1->Color = clRed; // SubKompo2 erzeugen SubKompo2 = new TSubKompo(this); SubKompo2->Parent = this; SubKompo2->Align = alClient; SubKompo2->Color = clBlue; // Tasten zuerst ans Form und Komponente hat den Focus Formular->KeyPreview = true; Formular->ActiveControl = this; } } //--------------------------------------------------------------------------- // DESTRUKTOR //--------------------------------------------------------------------------- __fastcall TMyKompo::~TMyKompo() { delete SubKompo1; SubKompo1 = 0; delete SubKompo2; SubKompo2 = 0; } void __fastcall TMyKompo::MyOnMouseDown(TObject* Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { ShowMessage("Hier"); } //** MyKompo.h #include <vcl.h> #include "SubKompo.h" class TMyKompo : public TPanel { public: __fastcall TMyKompo(TComponent* Owner); // Konstruktor __fastcall ~TMyKompo(); // Destruktor void __fastcall MyOnMOuseDown(System::TObject* Sender, TMouseButton Button, Classes::TShiftState Shift, int X, int Y); TSubKompo *SubKompo1; TSubKompo *SubKompo2; };
So und noch die Kind-Kompo
//**SubKompo.cpp //--------------------------------------------------------------------------- // KONSTRUKTOR //--------------------------------------------------------------------------- __fastcall TSubKompo::TSubKompo(TComponent* Owner): TLabel(Owner) { Parent = dynamic_cast<TPanel*>(Owner); //-- Gibt es einen Parent? if (Parent) { //-- HIER OnMouseDown = Parent->OnMouseDown; } }
Nochmals Vielen Dank
Xqgene