![]() |
VCL-Komponenten aufeinander aufbauen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Gemeinde,
ich wollte mal was Testen und das raubt mir gerade den Verstand. Was jetzt folgt ist viel Stoff zum Lesen, aber ich wollte mal sicher gehen, dass ich mich nicht umständlich und falsch ausdrücke. Mein Problem, ich wollte eine VCL-Komponente aufbauen. Der Bereich TBMBasic. Der Funktioniert auch soweit. Der Code ist a. noch nicht fertig und b. der Übersicht halber beschnitten.
Delphi-Quellcode:
Type TMBBasic = Class (TGraphicControl)
private fMouseOver : Boolean; fPushDown : Boolean; fHasFrame : Boolean; fFrameStyle : TPenStyle; fFrameThickness : Integer; fFrameColor : TColor; fBackFilling : tBrushStyle; fBackGroundColor : TColor; Procedure SetHasFrame (Value : Boolean); Procedure SetFrameStyle (Value : TPenStyle); Procedure SetFrameThickness (Value : Integer); Procedure SetBackFilling (Value : TBrushStyle); Procedure SetFrameColor (Value : TColor); Procedure SetBackGroundColor (Value : TColor); protected procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Override; procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); Override; procedure CMMouseLeave (var Message: TMessage); message CM_MouseLeave; procedure CMMouseEnter (var Message: TMessage); message CM_MouseEnter; procedure CMFontChanged (var Message: TMessage); message CM_FONTCHANGED; procedure CMTextChanged (var Message: TMessage); message CM_TEXTCHANGED; public procedure Paint; override; constructor Create(AOwner:Tcomponent);override; destructor Destroy; override; published property HasFrame : Boolean read fHasFrame write SetHasFrame; property FrameStyle : TPenStyle read fFrameStyle write SetFrameStyle; property FrameThickness : Integer read fFrameThickness write SetFrameThickness; property FrameColor : TColor read fFrameColor write SetFrameColor; property BackFilling : tBrushStyle read fBackFilling write SetBackFilling; property BackGroundColor: TColor read fBackGroundColor write SetBackGroundColor; Hier die Paint-Methode. Wie gesagt funktioniert.
Delphi-Quellcode:
Ich habe von hier eine Klasse abgeleitet, die wiederum auch funktioniert.
procedure TMBBasic.Paint;
var rgn : Hrgn; Area : TRect; Procedure DrawFrame; Begin canvas.pen.style:= fFrameStyle; canvas.Pen.Width := fFrameThickness; canvas.pen.color := fFrameColor; canvas.brush.Style := bsClear; canvas.Rectangle(0, 0, Width-fFrameThickness+1, Height-fFrameThickness+1); End; Begin Area := Rect(0, 0, Width, Height); canvas.pen.style:= fFrameStyle; canvas.brush.color := fBackGroundColor; canvas.brush.Style := fBackFilling; canvas.FillRect(Area); if fHasFrame then drawframe; End;
Delphi-Quellcode:
in der Paint-Methode Type TMBTitleLine = Class (TMBBasic) private fTitle : String; fDirection : sdDirection; procedure SetTitle (Value : String); procedure SetDirection (Value : sdDirection); protected public procedure Paint; override; constructor Create(AOwner:Tcomponent);override; destructor Destroy; override; published property Title : String read fTitle write SetTitle; property Direction : sdDirection read fDirection write SetDirection; End;
Delphi-Quellcode:
procedure TMBTitleLine.Paint;
var rgn : Hrgn; Area : TRect; procedure drawcaption; begin canvas.brush.style := bsclear; canvas.font.color := Font.color; DrawText (canvas.handle, @Title[1], -1, Area, DT_SINGLELINE or DT_VCENTER or DT_CENTER or DT_END_ELLIPSIS); end; Procedure DrawFrame; Begin canvas.pen.style:= fFrameStyle; canvas.Pen.Width := fFrameThickness; canvas.pen.color := fFrameColor; canvas.brush.Style := bsClear; canvas.Rectangle(0, 0, Width-fFrameThickness+1, Height-fFrameThickness+1); End; Begin canvas.font.Assign(Font); canvas.brush.style:=bssolid; Height := font.Size * 5; <== Das scheint nicht zu gehen Area := Rect(0, 0, Width, Height); canvas.pen.style:= fFrameStyle; canvas.brush.color := fBackGroundColor; canvas.brush.Style := fBackFilling; canvas.FillRect(Area); if fHasFrame then drawframe; if Title<>'' then DrawCaption; End; Soweit sogut: Nun wollte ich eine weitere Komponente, die dann später die Hauptkomponente sein wird aufbauen. Nennen wir die mal TMBPaintBoard und schon gingen die Probleme los.
Delphi-Quellcode:
Das nächste dann, wenn ich versuche diese in der Paint-Methode zu zeichnen,
Type TMBPaintBoard = Class (TGraphicControl)
private fMouseOver : Boolean; fPushDown : Boolean; fMBTitleLine : TMBTitleLine; Procedure SetTitleLine (Value : TMBTitleLine); protected public procedure Paint; override; constructor Create(AOwner:Tcomponent);override; destructor Destroy; override; published property Titleline : TMBTitleLine read fMBTitleLine write SetTitleLine; End;
Delphi-Quellcode:
Wenn ich das dann starten möchte dann wird das soweit auch gezeichnet.
procedure TMBPaintBoard.Paint;
var rgn : Hrgn; Area : TRect; Procedure DrawFrame; Begin canvas.pen.style:= fFrameStyle; canvas.Pen.Width := fFrameThickness; canvas.pen.color := fFrameColor; canvas.brush.Style := bsClear; canvas.Rectangle(0, 0, Width-fFrameThickness+1, Height-fFrameThickness+1); End; Begin Area := Rect(0, 0, Width, Height); canvas.pen.style:= fFrameStyle; canvas.brush.color := fBackGroundColor; canvas.brush.Style := fBackFilling; canvas.FillRect(Area); if fHasFrame then drawframe; fMBTitleLine.Left := Left + 5; fMBTitleLine.Top := Top + 5; fMBTitleLine.Width := Width - 10; fMBTitleLine.fBackGroundColor := clSkyBlue; fMBTitleLine.Parent := self.Parent; fMBTitleLine.Paint; Ich habe die Komponente registriert und eingebunden. Funktioniert auch. Taucht auf der TForm als MBPaintBoard1 auf, wird gezeichnet und eigentlich könnte ich zufrieden sein. Nur die Properties, die ich dann im Objektinspektor bekomme schauen schon mal seltsam aus und Zuweisungen funktionieren garnicht, d.h. nicht so ganz. Im Designmode zeigt es mir die Geschichte korrekt an, im Laufzeitmode nicht. Ich habe mal ein Bild Ausschnitt vom Objektinspekor mit angehängt. Wäre toll, wenn einer von euch ne Antwort weiß. Ich komm grad nicht wirklich weiter. Thx |
AW: VCL-Komponenten aufeinander aufbauen
Du musst wahrscheinlich noch SetSubComponent verwenden:
![]() |
AW: VCL-Komponenten aufeinander aufbauen
Hallo Stahli,
ich hab das mal so gemacht. Hat aber nichts bewirkt. Trotzdem Danke |
AW: VCL-Komponenten aufeinander aufbauen
Dumme Frage, aber müsste man für die Properties die auch in die DFM nicht noch eine
Delphi-Quellcode:
-Direktive anhängen oder ist das irgendwie schon automatisch?
stored
|
AW: VCL-Komponenten aufeinander aufbauen
Hallo Günther,
ich steh noch auf dem Schlauch. Umstellung Sommerzeit und so weiter... aber Scherz beiseite, ich versteh dich gerade wirklich nicht. Könntest du da bitte ein bisschen genauer werden? Danke mal |
AW: VCL-Komponenten aufeinander aufbauen
Delphi-Quellcode:
Ich dachte "Stored" gibt bei einer Property noch an, ob die Werte in der DFM gespeichert werden oder nicht. Allerdings merke ich grade, dass ja garkeine eigene DFM für die Komponente im Spiel ist. Deshalb Quatsch :oops:
type TMyComponent = class(...)
protected procedure setMyProperty(const Value: String); function getMyProperty(): String; published property name: String read getMyProperty write setMyProperty stored True; end; |
AW: VCL-Komponenten aufeinander aufbauen
Ich habe das schon so verstanden, dass es um die Speicherung im Formular geht.
Stored ist schon wichtig, aber standardmäßig True. Aus dem Wiki: Zitat:
Dein Quelltext ist vielleicht etwas komplex um das trocken nachzuvollziehen. Mach doch mal einen kleinen Test mit einer Unterkomponente, in der Du nur einen Text oder so speicherst. Es geht doch darum, dass Du zur Designtime die Untereigenschaften deklarierst und nach dem Projektstart oder nach dem Delphi-Neustart sind Deine Einstellungen weg - oder? Dann musst Du dafür sorgen, dass die Unterkomponenteneigenschaften mit in der DFM gespeichert werden. Dazu muss eigentlich Deine Komponente Owner der Unterkomponente sein und SetSubComponent(True) sein. Mein Tipp: Versuche mal einen kleinen, übersichtlich Test mit sehr einfachen Komponenten. |
AW: VCL-Komponenten aufeinander aufbauen
Hallo Stahli,
Danke noch für die Antwort. Zitat:
Um ehrlich zu sein, hab ich das mit den DFM so noch nie händisch gemacht. Ist das so zu verstehen, wie das Günther vorgeschlagen hat? siehe
Delphi-Quellcode:
Falls ja, dann versuch ich das so. Falls nein, wäre ich auf ein kleines Snippet angewiesen, gesucht hab ich schon, bin aber nicht besonders fündig geworden. Hab zumindest nichts gefunden, was mich weiterbringt.
type TMyComponent = class(...)
protected procedure setMyProperty(const Value: String); function getMyProperty(): String; published property name: String read getMyProperty write setMyProperty stored True; end; Und – Zitat:
|
AW: VCL-Komponenten aufeinander aufbauen
Hier mal ein Auszug aus einem alten Projekt:
Delphi-Quellcode:
TodDataSet war von TComponent abgeleitet:
unit odEdit;
interface uses StdCtrls, {$INCLUDE 'inc\uses.inc'}; type TodEdit = class(TEdit) private {$INCLUDE 'inc\privat_var.inc'} {$INCLUDE 'inc\privat_meth.inc'} protected public constructor Create(AOwner: TComponent); override; destructor Destroy; override; {$INCLUDE 'inc\public_prop.inc'} procedure WndProc(var Message: TMessage); override; published {$INCLUDE 'inc\published_prop.inc'} // Die inc sieht so aus: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // property DataSet: TodDataSet read FDataSet; // property OnAfterGetData: TNotifyEvent read FOnAfterGetData write FOnAfterGetData; // property OnBeforeGetData: TNotifyEvent read FOnBeforeGetData write FOnBeforeGetData; end; procedure Register; implementation uses Graphics, Controls, Themes, Windows, SysUtils; procedure Register; begin RegisterComponents('odControls', [TodEdit]); end; { TodEdit } function TodEdit{$INCLUDE 'inc\get_od.inc'} procedure TodEdit{$INCLUDE 'inc\set_od.inc'} function TodEdit{$INCLUDE 'inc\get_PropName.inc'} procedure TodEdit{$INCLUDE 'inc\set_PropName.inc'} function TodEdit{$INCLUDE 'inc\get_PropText.inc'} procedure TodEdit{$INCLUDE 'inc\set_PropText.inc'} constructor TodEdit.Create(AOwner: TComponent); begin inherited; {$INCLUDE 'inc\create.inc'} // Die inc sieht so aus: !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // FDataSet := TodDataSet.Create(Self); // DataSet.SetSubComponent(True); end; destructor TodEdit.Destroy; begin inherited; end; procedure TodEdit.WndProc(var Message: TMessage); begin ... inherited; end; end.
Delphi-Quellcode:
Das hat so wunderbar funktioniert.
TodDataSet = class(TComponent)
private ... protected ... public ... published property PropName: String read get_PropName write set_PropName; end; |
AW: VCL-Komponenten aufeinander aufbauen
Ok Stahli,
Danke erst mal. Das Muss ich mir heute Abend mal in Ruhe durch die Birne ziehen. So ganz bin ich da in der Schnelle noch nicht durchgestiegen, aber ich denke ich hab den entscheidenden Hinweis erhalten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:42 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz