Ereignisse von eigenen Komponenten (Klappe die tausendste)
-
Hallo.
Sorry, ich weiß, dass diese Frage hier schon tausendmal gestellt worden ist. Ich habe die entsprechenden Beiträge auch über die Suche gefunden. Leider checke ich sie nicht

Daher an dieser Stelle noch mal die Frage, mit Bitte auf Antwort im "für newbys, die noch die eigene Komponenten im Builder 6 benutzt haben" Style
Also, ich habe meine Komponente TMyStringGrid
Header://--------------------------------------------------------------------------- #ifndef MyStringGridH #define MyStringGridH //--------------------------------------------------------------------------- #include <SysUtils.hpp> #include <Classes.hpp> #include <Controls.hpp> #include <Grids.hpp> //--------------------------------------------------------------------------- class PACKAGE TMyStringGrid : public TStringGrid { private: protected: public: __fastcall TMyStringGrid(TComponent* Owner); int colSorted; __published: }; //--------------------------------------------------------------------------- #endifcpp:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "MyStringGrid.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // Mit ValidCtrCheck wird sichergestellt, daß die erzeugten Komponenten // keine rein virtuellen Funktionen besitzen. // static inline void ValidCtrCheck(TMyStringGrid *) { new TMyStringGrid(NULL); } //--------------------------------------------------------------------------- __fastcall TMyStringGrid::TMyStringGrid(TComponent* Owner) : TStringGrid(Owner) { } //--------------------------------------------------------------------------- namespace Mystringgrid { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TMyStringGrid)}; RegisterComponents("Beispiele", classes, 0); } } //---------------------------------------------------------------------------Dieser Code wurde automatisch vom Borland Builder erstellt.
Ich möchte jetzt, dass alle Objekte, die ich aus dieser KLasse ableiten, ein bestimmtes OnDraw Ereignis benutzen. Diese möchte ich in die Klasse integrieren.
Was muss ich tun?Danke!
-
Hi,
was du mit OnDraw machen willst, weiss ich nicht. Vielleicht etwas genauer erklären was du vorhast.
Hast du dir das Tutorial (in der Signatur) angeschaut ?
-
Hallo,
ich möchte ein StringGrid haben, welches alle Anforderungen die ich normalerweise an ein Grid habe, erfüllt. D.h. es muss einfach farbige Cellen, reihen usw. darstellen können, muss nach int, String und DateTime sortierbar sein, und sollte einige extra Eigenschaften zur weiteren Nutzung haben.
Bis jetzt habe ich das immer mühsam im Programm realsiert. D.h. jedes grid hatte sein eigenes OnDrawCell Event, mit teils sehr redundanten Code (jede zweite Zeile farbeig etc.). Das gleiche gilt für die Sortieraufrufe. Das ist nur sehr schwer zu pflegen, sondern ist auch noch umständlich.
Daher möchte ich ein Grid schreiben, dass all diese Anforderungen bereits mitbringt. Über Eigenschaften soll dann steuerbar sein, nach welchen Regeln Zellen oder Reihen eingefärbt werden sollen (wenn überhaupt). Zudem sollen die Sortiermethoden mit implementiert werden.Bis jetzt habe ich den folgenden Code, der zwar nichts bewirkt (geht nicht), aber zumindest auch keine Fehler mehr verursacht.
Header:
//--------------------------------------------------------------------------- #ifndef MyStringGridH #define MyStringGridH //--------------------------------------------------------------------------- #include <SysUtils.hpp> #include <Classes.hpp> #include <Controls.hpp> #include <Grids.hpp> //--------------------------------------------------------------------------- class PACKAGE TMyStringGrid : public TStringGrid { private: TDrawCellEvent FOnDrawCell; protected: virtual void __fastcall DrawCell(int ACol, int ARow, const Types::TRect &ARect, TGridDrawState AState); __property TDrawCellEvent OnDrawCell = {read=FOnDrawCell, write=FOnDrawCell}; public: __fastcall TMyStringGrid(TComponent* Owner); __published: }; //--------------------------------------------------------------------------- #endifcpp:
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "MyStringGrid.h" #pragma package(smart_init) //--------------------------------------------------------------------------- // Mit ValidCtrCheck wird sichergestellt, daß die erzeugten Komponenten // keine rein virtuellen Funktionen besitzen. // static inline void ValidCtrCheck(TMyStringGrid *) { new TMyStringGrid(NULL); } //--------------------------------------------------------------------------- __fastcall TMyStringGrid::TMyStringGrid(TComponent* Owner) : TStringGrid(Owner) { } //--------------------------------------------------------------------------- namespace Mystringgrid { void __fastcall PACKAGE Register() { TComponentClass classes[1] = {__classid(TMyStringGrid)}; RegisterComponents("Beispiele", classes, 0); } } //--------------------------------------------------------------------------- virtual void __fastcall TMyStringGrid::DrawCell(int ACol, int ARow, const Types::TRect &ARect, TGridDrawState AState) { TStringGrid::DrawCell(ACol, ARow, Types::TRect &ARect, AState); if (ARow != 0) { Canvas->Brush->Color = 0x00DDDDFF; Canvas->FillRect(Rect); DrawText(Canvas->Handle, Cells[ACol][ARow].c_str(), -1, &Rect, DT_SINGLELINE | DT_VCENTER | 0); } } //---------------------------------------------------------------------------Dein Tut werde ich mir gleich mal anschauen!
-
Ein Weg wäre, die Methode Loaded() zu überschreiben und darin zu überprüfen, ob das OnDrawCell-Ereignis gesetzt wurde.
Wenn also jemand Deine Komponente verwendet, hat er ja auch die Möglichkeit für das Ereignis eine entsprechende
Methode zuzuweisen. Wenn Loaded aufgerufen wird, sind sämtliche Eigenschaften, die ein Benutzer (in diesem Fall
ein Programmierer, der Deine Komponente verwendet) im Objektinspektor gesetzt hat, eingelesen.
Dann hast Du die Möglichkeit, Deine eigene Routine hier einzuklinken: Immer wenn das OnDrawCell-Ereignis eintritt,
arbeitest Du zuerst Deine Routine ab und anschließend die von außen gesetzte.Das Problem ist allerdings, dass Du nicht mitbekommst, wenn OnDrawCell per Code gesetzt wird.
OnDrawCell hat leider keine set-Methode, die Du überschreiben kannst. Du kannst höchstens die Eigenschaft neu
implementieren, ob das aber funktioniert, habe ich noch nicht ausprobiert.Vielleicht könntest Du auch die entsprechende Windows-Message abfangen; entweder über Message-Maps oder über
einen Hook. Hooks funktionieren mit Komponenten, da .bpl-Dateien auch DLLs sind. Allerdings habe ich die
Erfahrung gemacht, dass die Komponente dann in der Liste der Laufzeit-Packages enthalten sein muss.Gruß,
Alexander