Grafische Komponenente
-
Hallo
ich sehe immer noch nicht, was du nun von uns wissen willst. Was stört dich an den beschriebenen Fakten? Wie soll es werden?
bis bald
akari
-
mal ein paar anmerkungen...
das Paint sollte wie bereits von mir geschrieben virtual sein, denn sonst kannst du mal später nicht von deiner komponente ableiten und das Paint in der abgeleiteten Version verwenden. (bin grad nicht sicher... oder hiess einmal virtual immer virtual?)
wieso bekommt das TImage den selben Owner wie deine komponente und nicht die komponente selbst?
Image = new TImage(this); Image->Parent = this;ausserdem ist ein name wie TGraphicControl1 ziemlich blöd gewählt, führt schnell dazu sich zu verlesen, da auch die 1 (eins) kaum von l (L) zu unterscheiden ist...
-
Sunday schrieb:
(bin grad nicht sicher... oder hiess einmal virtual immer virtual?)
Genau so ist es.
-
Noch mal zur Sicherheit der Standard: Kapitel 10.3 2
If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base, a member function vf with the same name and same parameter list as Base::vf is declared, then Derived::vf is also virtual (whether or not it is so declared) and it overrides Base::vf.
-
Image = new TImage(this);
Image->Parent = this;Ok, Owner von Image sollte natürlich meine Komponenete sein, ebenfalls
das Parent von Image.Image->Parent = this; //Parent ist meine Komponente
gibt eine Fehlermeldung "... TTemp *const nach TWinControl* nicht möglich.
Caste ich den Pointer this auf TWinControl
Image->Parent = ((TWinControl*)Owner)this;
kommt der Fehler zwar nicht mehr, dafür gibt es beim benutzen der Komponenete
eine Zugrifsverletzung.
-
Hallo
das liegt ja auch daran, das TGraphicControl nicht von TWinControl abgeleitet ist, und damit auch nicht dein TGraphicControl1. Damit kannst du zwar diesen harten C-Style Cast machen, aber das Ergbnis ist in jedenfall fehlerhaft. Mit einem static_cast stattdessen hätte dich der Compiler davor gewarnt.
Du must als Parent in deinem Fall den Parent von dem TGraphicControl1 übergeben
Image->Parent = Parent;bis bald
akari
-
Hallo,
das liegt ja auch daran, das TGraphicControl nicht von TWinControl abgeleitet ist, und damit auch nicht dein TGraphicControl1. Damit kannst du zwar diesen harten C-Style Cast machen, aber das Ergbnis ist in jedenfall fehlerhaft. Mit einem static_cast stattdessen hätte dich der Compiler davor gewarnt.
Ok, da TGraphicControl nicht von TWinControl abgeleitet ist darf ich den Pointer natürlich nicht auf TWinControl casten.
Mein Code sieht nun folgendermassen aus.
class PACKAGE TTemp : public TGraphicControl { private: TImage *Image; TColor IMColor; void __fastcall Paint(void); void __fastcall SetIMColor(TColor NewColor); void DrawGrafValue(void); __published: __property TColor Color = {read=IMColor,write=SetIMColor}; protected: public: __fastcall TTemp(TComponent* Owner); }; //--------------------------------------------------------------------------- __fastcall TTemp::TTemp(TComponent* Owner) : TGraphicControl(Owner) { Image = new TImage(this); Image->Parent = Parent; //Parent des erstellten Objects Image->Height = 100; Image->Width = 100; Image->Visible = true; SetIMColor(clRed); } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMColor(TColor NewColor) { if(Image) IMColor = NewColor; Repaint(); } //--------------------------------------------------------------------------- void __fastcall TTemp::Paint(void) { DrawGrafValue(); } //--------------------------------------------------------------------------- // Zeichnet eine Balckengrafig //--------------------------------------------------------------------------- void TTemp::DrawGrafValue(void) { Image->Canvas->Brush->Color = IMColor; Image->Canvas->FillRect(Rect(0,0,Image->Width,Image->Height)); }Nun wird die Komponenete trotz Repaint nicht mehr gezeichnet.
-
probiere mal statt Repaint ein Invalidate();...
Repaint bzw. Invalidate brauchst du auch nur aufrufen, wenn sich eine eigenschaft auch wirklich geändert hat.
-
Invalidate() funktioniert auch nicht.
Selbst nach dem Progstart und Änderung der Eigenschaft Color durch Button1Click
taucht die Grafig nicht auf, obwohl der Setter SetIMColor ausgeführt wird (mit Break getestet).//--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { Temp1->Color = clBlue; }
-
Wenn der Parent des Image der Parent der Komponente ist, wird das Image doch eigentlich auch da gezeichnet. Im Objektinspektor also garnicht.
Warum eigentlich das Image? Eine von TGraphicControl abgeleitete Komponente hat doch ein eigens Canvas auf dem man zeichnen kann. Das könnte man doch einfach nehmen. Genau dafür ist TGraphicControl doch da.
-
Warum eigentlich das Image? Eine von TGraphicControl abgeleitete Komponente hat doch ein eigens Canvas auf dem man zeichnen kann. Das könnte man doch einfach nehmen. Genau dafür ist TGraphicControl doch da.
Stimmt, das mit dem Image kann ich mir sparen.
//--------------------------------------------------------------------------- __fastcall TTemp::TTemp(TComponent* Owner) : TGraphicControl(Owner) { Height = 100; Width = 100; SetIMColor(clRed); } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMColor(TColor NewColor) { IMColor = NewColor; Repaint(); } //--------------------------------------------------------------------------- void __fastcall TTemp::Paint(void) { DrawGrafValue(); } //--------------------------------------------------------------------------- // Zeichnet eine Balckengrafig //--------------------------------------------------------------------------- void TTemp::DrawGrafValue(void) { Canvas->Brush->Color = IMColor; Canvas->FillRect(Rect(0,0,Width,Height)); }So gehts.
-
Hi,
ich würd das so machen:void __fastcall TTemp::SetIMColor(TColor NewColor) { if (IMColor != NewColor) { IMColor = NewColor; Repaint(); } }Dann wirds nur beim tatsächlichen Ändern neugezeichnet.
MfG
Alexander Sulfrian
-
void __fastcall TTemp::SetIMColor(TColor NewColor) { if (IMColor != NewColor) { IMColor = NewColor; Repaint(); } }Gute Idee.
Ich habe nun noch die Eigenschaften PosValue, ErrorValue, NoErrorColor, ErrorColor.
Ist ErrorValue > PosValue wird die Farbe ErrorColor benutzt, sonst NoErrorColor.
Sollte man da so vorgehen oder anders.class PACKAGE TTemp : public TGraphicControl { private: TColor Color; TColor IMNoErrorColor; TColor IMErrorColor; int IMErrorValue; int IMPosValue; void __fastcall Paint(void); void __fastcall SetIMNoErrorColor(TColor NewColor); void __fastcall SetIMErrorColor(TColor NewColor); void __fastcall SetIMErrorValue(int NewErrorValue); void __fastcall SetIMPosValue(int NewPosValue); void DrawGrafValue(void); __published: __property TColor NoErrorColor = {read=IMNoErrorColor,write=SetIMNoErrorColor}; __property TColor ErrorColor = {read=IMErrorColor,write=SetIMErrorColor}; __property int ErrorValue = {read=IMErrorValue,write=SetIMErrorValue}; protected: public: __fastcall TTemp(TComponent* Owner); __property int PosValue = {read=IMPosValue,write=SetIMPosValue}; }; //--------------------------------------------------------------------------- __fastcall TTemp::TTemp(TComponent* Owner) : TGraphicControl(Owner) { Height = 100; Width = 100; } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMNoErrorColor(TColor NewColor) { IMNoErrorColor = NewColor; } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMErrorColor(TColor NewColor) { IMErrorColor = NewColor; } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMErrorValue(int NewErrorValue) { IMErrorValue = NewErrorValue; } //--------------------------------------------------------------------------- void __fastcall TTemp::SetIMPosValue(int NewPosValue) { IMPosValue = NewPosValue; if(IMPosValue > IMErrorValue) { Color = IMErrorColor; } else { Color = IMNoErrorColor; } Repaint(); } //--------------------------------------------------------------------------- void __fastcall TTemp::Paint(void) { DrawGrafValue(); } //--------------------------------------------------------------------------- // Zeichnet eine Balckengrafig //--------------------------------------------------------------------------- void TTemp::DrawGrafValue() { Canvas->Brush->Color = Color; Canvas->FillRect(Rect(0,0,Width,Height)); }Und kann man ohne Probleme eine Timer Instanz erzeugen, die dann das ganze
noch blinken lässt, oder besser nicht.
-
Hallo,
die Eigenschaften Width sowie Height werden ja von TGraphicControl als Publisched
geerbt.Wie kann ich diese Eigenschaften nun als private überschreiben.
-
Hallo
indem du
__property int Width; __property int Height;in den private-Teil deiner Klasse schreibst.
Allerdings kann das zu unschönen Fehlern führen.bis bald
akari
-
Dann kommt die Fehlermeldung _property-Variable muss initialisiert sein.
-
Hallo
sorry, int muß da weg
__property Width; __property Height;bis bald
akari
-
Scheint irgendwie nicht richtig zu sein, die Eigenschaften tauchen nachwievor
im OI auf.Ist vieleicht
__property int Width;
__property int Height;doch nicht richtig.
TGraphicControl erbt die Eigenschaft von TControl.
TControl::Height
__property int Height = {read=FHeight, write=SetHeight, nodefault};muss ich da nicht auch noch die Membervariablen int FHeight, int SetHight mit
überschreiben und dann unter private
__property int Height = {read=FHeight, write=SetHeight};
die Property überschreiben.
Habe das schon probiert, funkt aber auch nicht.