Komponente mit eigenen Eigenschaften, zusammengefasst wie z.B. bei den Fonts
-
Hallo ihr,
ich möchte eine Komponente mit dem C++ Builder 2006 schreiben, abgeleitet von TCustomPanel.Es sollen zwei Eigenschaften hinzugefügt werden, welche zusammengefasst werden sollen, wie z.B. bei Fonts. Bei Fonts kann auf das kleine + geklickt werden und es öffnet sich der Bereich, der verschiede Eigenschaften darstellt, wie Farbe,Größe usw.
Die Unteren Eigenschaften Vollbild und Rand sollen zu einer Gruppe namens Setup zusammengefasst werden. Könnt ihr mir sagen, wie das geht?
//--------------die header-Datei----------------
class PACKAGE TMyPanel : public TCustomPanel
{
private:bool FVollbild;
int FRand;protected:
void __fastcall SetVollbild(bool boolVar);
void __fastcall SetRand(int intVar);public:
__fastcall TMyPanel(TComponent* Owner);
__published:
__property bool Vollbild={read=FVollbild,write=SetVollbild};
__property bool Rand={read=FRand,write=SetRand};
}
//---------------------------------------------------------
-
Hallo
Das geht nur wenn du die beiden betreffenden Eigenschaften in eine externe Klasse auslagerst, und jede Instanz von deinem Panel eine Instanz davon bekommt.
TFont ist schließlich auch eine extra Klasse, deshalb werden die Eigenschaften von TFont auch nicht direkt in der Liste von z.B. TLabel angezeigt sondern als Untereigenschaft der Eigenschaft TLabel::Font.Und bitte beim nächsten Posten von Code hier im Forum beachten : sfds
bis bald
akari
-
Ok, also:
//----------------------die header-Datei------------------- class TExtraMenue: public TPersistent { private: bool FVollbild; int FRand; protected: void __fastcall SetVollbild(bool boolVar); void __fastcall SetRand(int intVar); public: __published: __property bool Vollbild={read=FVollbild,write=SetVollbild}; __property bool Rand={read=FRand,write=SetRand}; } //--------------------------------------------------------- class PACKAGE TMyPanel: public TCustomPanel { private: TExtraMenue* FExtraMenue; AnsiString FCaption; protected: void __fastcall SetCaption(AnsiString Text); public: __fastcall TMyPanel(TComponent* Owner); __published: __property TExtraMenue* ExtraMenue = {read=FExtraMenue, write=FExtraMenue}; __property AnsiString Caption = { read = FCaption, write = SetCaption}; } //---------------------------------------------------------Wenn ich nun die Eigenschaft von Vollbild ändere, wird SetVollbild() ausgeführt (Ist ja auch OK). Von dort soll SetCaption() ausgeführt werden. Die obere Klasse kennt aber SetCaption nicht... ???? Und diese Aufklappliste im Objektinspektor ist auch nicht da.
Und Nu???
-
Dann mußt du der Klasse TExtraMenue noch einen Zeiger auf TMyPanel mitgeben. Am besten, du schreibst dir dafür einen eigenen Konstruktor:
class TMyPanel; // forward-reference class TExtraMenue { public: TExtraMenue(TMyPanel *Owner) : pOwner(Owner) {} private: TMyPanel *pOwner; }Nun solltest du noch in der Klasse TMyPanel TExtraMenue zum Freund erklären:
class TMyPanel { friend TExtraMenue; };Dann kannst du auch die Methoden aus TMyPanel aufrufen:
void TExtraMenue::SetFullScreen() // i prefer english names !! { pOwner->SetCaption("FullScreen"); }Und als letztes mußt du noch eine gültige Instanz von TExtraMenue erzeugen, am besten im Konstruktor von TMyPanel - und entsprechend im Destruktor wieder löschen:
TMyPanel::TMyPanel() { FExtraMenue = new TExtraMenue(this); } TMyPanel::~TMyPanel() { delete FExtraMenue; }P.S. Dein Syntax-Coloring hat nicht funktioniert
Und die Namensgebung mit 'F...' wird zwar in Delphi so benutzt (weiß bis heute leider nicht, wofür das F steht (Field?)), aber in C++ finde ich sie nicht so gut...
-
**Das ist ja super!!
Vielen, vielen Dank. Ich habe schon ewig daran gebastelt.**
Nun habe ich aber noch eine Funktion in TMyPanel:
//-----------.h-Datei------------ protected: void __fastcall DrawText(void); //-----------.cpp-Datei---------- void __fastcall TMyPanel::DrawText(void) { . Farben ändern, Text ändern..... . }Diese Funktion soll nun bei SetVollbild()oder SetFullScreen() aufgerufen werden
void TExtraMenue::SetFullScreen() // i prefer english names !! { pOwner->SetCaption("FullScreen"); pOwner->DrawText(void); //??????????????? }Kannst Du mir hier noch einmal helfen ??
-
Du scheinst dich mit den Grundlagen von C++ noch nicht so auszukennen, oder?
Eine parameterlose Funktion ruft man nur mit () auf:
pOwner->DrawText();Und bei der Deklaration von parameterlosen Funktionen läßt man in C++ (im Gegensatz zu C) auch das 'void' weg:
void DrawText();Das '__fastcall' brauchst du auch nur bei den Ereignismethoden zu verwenden, bei eigenen Methoden lass es lieber weg.
-
Soweit klappt alles, aber...
in der TExtraMenue Klasse soll nun TFont(FxFont) eingefügt werden:
private: TFont* FxFont; __published: __property TFont* xFont={read=FxFont,write=FxFont};Wenn ich das bei TMyPanel einfüge und mit FxFont=new TFont; anmelde klappt es.
Leider nicht innerhalb des TExtraMenue's
Kann mir jemand helfen z.B. "~Components"
-
Was heißt, es klappt bei TExtraMenue nicht?
Th69 (= ~Components)
-
Im Objektinspektor erscheint im ExtraMenue zwar ,,xFont" mit dem kleinen Plus-Zeichen, aber wenn ich dort auf + klicke öffnet sich das Font-Menue nicht.
-
Zeig mal ein bißchen Code, wie sieht z.B. dein Konstruktor v. TExtraMenue aus?
P.S: Was ist eigentlich der Grund, daß du ein eigenes Control entwickeln willst?
-
Also, das zu mir:
Obwohl ich Anfänger bin, interessiert mich die Komponentenentwicklung.
Das Programmieren ist mein Hobby und ich habe mir alles selbst zusammengesucht/beigebracht. Das ist auch der Grund, warum ich mit Begriffen, wie Instanz, Konstruktor u.s.w. Probleme habe. Ich weiß, das sollte ich unbedingt lernen... komme ich wohl auch nicht drum herum. Den eigenen Panel wollte ich entwickeln, um Hintergrundwissen zu erlangen. z.B. wann wird OnPaint ausgelöst, wie funktionieren Botschaften....Hier nun mein Code der *.h Datei:
#ifndef MyPanelH #define MyPanelH //--------------------------------------------------------------------------- #include <SysUtils.hpp> #include <Classes.hpp> #include <Controls.hpp> #include <ExtCtrls.hpp> class TMyPanel; //--------------------------------------------------------------------------- class TExtraMenue: public TPersistent { private: TMyPanel *MyPanel; bool FVollbild; int FRand; TFont* FxFont; protected: void __fastcall SetRand(int); void __fastcall SetVollbild(bool); void __fastcall SetFxFont(TFont *AFont); public: TExtraMenue(TMyPanel *Owner) : MyPanel(Owner) {} __published: __property bool Vollbild={read=FVollbild,write=SetVollbild}; __property int Rand={read=FRand,write=SetRand}; __property TFont* xFont={read=FxFont,write=SetFxFont}; }; //****************************************************************************** class PACKAGE TMyPanel : public TCustomPanel { private: TExtraMenue* FExtraMenue; friend TExtraMenue; AnsiString FCaption; protected: void __fastcall SetCaption(AnsiString Text); public: __fastcall TMyPanel(TComponent* Owner); __fastcall ~TMyPanel(void); __published: __property AnsiString Caption = { read = FCaption, write = SetCaption}; __property TExtraMenue* ExtraMenue={ read = FExtraMenue, write = FExtraMenue}; }; //--------------------------------------------------------------------------- #endifUnd hier der wichtige Teil der *.cpp Datei:
__fastcall TMyPanel::TMyPanel(TComponent* Owner) : TCustomPanel(Owner) { FExtraMenue = new TExtraMenue(this); }xFont ist im ExtraMenue enthalten. Bei Klick auf + wird das Font-Menue NICHT geöffnet.
..
-
ist auch kein Wunder, da dein Konstruktor von TExtraMenue leer ist, dort mußt du eine Instanz von FxFont erzeugen (new) und im Destruktor (der noch fehlt) wieder löschen
-
Habe ich versucht, bin ich aber zu doof zu.
Was muß ich denn eintippen?
-
naja, eigentlich das gleiche wie beim Konstruktor von TMyPanel für FExtraMenue (natürlich dann für TFont) und auch dort solltest du das Löschen in Destruktor nicht vergessen
falls du nicht weißt wie man Instanzen mit new erstellt und mit delete löscht solltest du vielleicht dazu erstmal etwas mehr lernen/probieren
-
Linnea, besser hätte ich es auch nicht ausdrücken können -)
Vera, noch viel Spaß beim Lernen...
-
Für andere Anfänger, die es interessiert(ohne Sprüche...)
im TExtraMenue:public: . . TExtraMenue(TMyPanel *Owner) : MyPanel(Owner) {FxFont=new TFont;} . .Schade, das Ihr plötzlich so komisch reagiert.
Trotzdem vielen Dank
-
Wir reagieren nicht komisch, aber vorkauen wollen wir dir auch nicht alles, da du doch anscheinend etwas lernen willst und das geht nunmal nur wenn man mal selber was versucht bzw. bei den Grundlagen anfängt. Das Thema Komponentenentwicklung ist auch in der BCB-Hilfe relativ ausführlich beschrieben, z.B. solltest du dir hier das Thema "Stift und Pinsel als published deklarieren" mal genauer ansehen, da das für den Font ganz ähnlich funktioniert.
-
Sorry Vera,
Vera in Action schrieb:
Habe ich versucht, bin ich aber zu doof zu.
Was muß ich denn eintippen?Aber das hat mir nicht gezeigt, daß du wirklich etwas lernen willst, sondern daß du nur einen "Dummen" suchst, der dir etwas hinschreibt.
Ich habe mir doch wirklich Mühe gegeben, dir soviel wie möglich an Code und Hilfe zu geben...
Ich weiß, daß es nicht einfach ist, so etwas Komplexes wie Komponentenentwicklung zu betreiben, aber auch ich selber habe es nur durch Beispiele, viel Lesen (besonders die Hilfe beim BCB ist super) und selber ausprobieren hingekriegt (vor 10 Jahren hatte ich noch kein Internet, geschweige denn Zugriff auf ein so gutes Forum wie dieses hier -)
P.S: Ich werde aber gerne weitere Fragen von dir beantworten.
-
Ok, Schwamm drüber und nochmals vielen, vielen Dank für die Hilfe.
Ihr habt mir sehr geholfen und ich freue mich darüber, immer ein wenig weiter zu kommen.
Mein größter Dank geht natürlich an Th69!Ich wünsche euch ein schönes Wochenende