Grafische Komponenente
-
Du mußt dafür sorgen, dass Paint nach Ändern der Frabe auch aufgerufen wird. Wenn die Änderung von IMColor über eine set-Methode erfolgt (evtl. in einer Property) dann ruftst du einfach dort Repaint() auf. Wenn IMColor einfach nur eine Membervariable ist, mach eine Property draus.
Jo alles klar.
Wie kann ich nun noch dafür sorgen das die Komponenete schon zur Entwurfszeit
auf dem Formular sichtbar wird und bei Änderung einer Property im
Objektinspektor neu gezeichznet wird?
-
Hallo
das passiert automatisch, wenn du wie beschrieben ableitest und Paint() benutzt.
Und wenn du bei den Settern der Eigenscvhaften, die du im OI anzeigen läßt, auch entsprechend die Repaint-Methode aufrufst.bis bald
akari
-
Mit einem Setter lässt sich nun die Eigenschaft Color auch zur Entwurfszeit
ändern.Habe nun ein anderes Problem, beim plazieren der Komponente existieren nun
zwei Komponenten. Einmal die von mir erstellte mit der entsprechenden
Eigenschaft Color, sowie eine weitere ohne Namen die alle Eigenschaften von
einem Image hat. Bei dieser Komponente ändert sich dann auch die Farbe.
Meine eigentliche Komponente bleibt dabei unsichtbar.//--------------------------------------------------------------------------- class PACKAGE TGraphicControl1 : 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 TGraphicControl1(TComponent* Owner); //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- __fastcall TGraphicControl1::TGraphicControl1(TComponent* Owner) : TGraphicControl(Owner) { Image = new TImage(Owner); Image->Parent = ((TWinControl*)Owner); Image->Height = 100; Image->Width = 100; Image->Visible = true; IMColor = clRed; } //--------------------------------------------------------------------------- void __fastcall TGraphicControl1::SetIMColor(TColor NewColor) { if(Image) IMColor = NewColor; Repaint(); } //--------------------------------------------------------------------------- void __fastcall TGraphicControl1::Paint(void) { DrawGrafValue(); } //--------------------------------------------------------------------------- // Zeichnet eine Balckengrafig //--------------------------------------------------------------------------- void TGraphicControl1::DrawGrafValue(void) { Image->Canvas->Brush->Color = IMColor; Image->Canvas->FillRect(Rect(0,0,Image->Width,Image->Height)); }
-
Hallo
und wo ist jetzt das Problem? Ich sehe keine Frage.
bis bald
akari
-
Meine Frage über dem Source Code.
Habe nun ein anderes Problem, beim plazieren der Komponente existieren nun
zwei Komponenten. Einmal die von mir erstellte mit der entsprechenden
Eigenschaft Color, sowie eine weitere ohne Namen die alle Eigenschaften von
einem Image hat. Bei dieser Komponente ändert sich dann auch die Farbe.
Meine eigentliche Komponente bleibt dabei unsichtbar.
-
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