AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

VCL-Komponenten aufeinander aufbauen

Ein Thema von Ookami · begonnen am 30. Mär 2014 · letzter Beitrag vom 31. Mär 2014
Antwort Antwort
Benutzerbild von Ookami
Ookami

Registriert seit: 20. Nov 2009
Ort: Baden Württemberg
77 Beiträge
 
Delphi 2009 Architect
 
#1

VCL-Komponenten aufeinander aufbauen

  Alt 30. Mär 2014, 20:29
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:
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;
Ich habe von hier eine Klasse abgeleitet, die wiederum auch funktioniert.

Delphi-Quellcode:

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;
in der Paint-Methode

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:
 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;
Das nächste dann, wenn ich versuche diese in der Paint-Methode zu zeichnen,

Delphi-Quellcode:
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;
Wenn ich das dann starten möchte dann wird das soweit auch gezeichnet.
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
Miniaturansicht angehängter Grafiken
unbenannt.png  
Wolfgang
Grüße und Danke
Wolfgang
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: VCL-Komponenten aufeinander aufbauen

  Alt 30. Mär 2014, 20:48
Du musst wahrscheinlich noch SetSubComponent verwenden: http://www.delphipraxis.net/79726-un...der-gruen.html
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Ookami
Ookami

Registriert seit: 20. Nov 2009
Ort: Baden Württemberg
77 Beiträge
 
Delphi 2009 Architect
 
#3

AW: VCL-Komponenten aufeinander aufbauen

  Alt 30. Mär 2014, 21:04
Hallo Stahli,

ich hab das mal so gemacht. Hat aber nichts bewirkt.

Trotzdem Danke
Wolfgang
Grüße und Danke
Wolfgang
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 10:24
Dumme Frage, aber müsste man für die Properties die auch in die DFM nicht noch eine stored -Direktive anhängen oder ist das irgendwie schon automatisch?
  Mit Zitat antworten Zitat
Benutzerbild von Ookami
Ookami

Registriert seit: 20. Nov 2009
Ort: Baden Württemberg
77 Beiträge
 
Delphi 2009 Architect
 
#5

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 11:12
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
Wolfgang
Grüße und Danke
Wolfgang
  Mit Zitat antworten Zitat
Der schöne Günther
Online

Registriert seit: 6. Mär 2013
6.158 Beiträge
 
Delphi 10 Seattle Enterprise
 
#6

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 11:29
Delphi-Quellcode:
type TMyComponent = class(...)
   protected
      procedure setMyProperty(const Value: String);
      function getMyProperty(): String;
   
   published
      property name: String
         read getMyProperty
         write setMyProperty
         stored True;

end;
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
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 12:17
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:
Speicherbezeichner

Die optionalen Direktiven stored, default und nodefault sind Speicherbezeichner. Sie haben keinerlei Auswirkungen auf die Funktionsweise des Programms, sondern bestimmen, ob die Werte der published-Eigenschaften in Formulardateien gespeichert werden.

Nach der Angabe stored muss der Wert True oder False, der Name eines booleschen Feldes oder der Name einer parameterlosen Methode folgen, die einen booleschen Wert zurückgibt. Beispiel:
property Name : TComponentName read FName write SetName stored False;

Wird eine Eigenschaft ohne die Angabe von stored deklariert, entspricht dies der Definition stored True.
@Ookami
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.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Ookami
Ookami

Registriert seit: 20. Nov 2009
Ort: Baden Württemberg
77 Beiträge
 
Delphi 2009 Architect
 
#8

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 12:43
Hallo Stahli,

Danke noch für die Antwort.

Zitat:
@Ookami
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
.
Den Test werd ich so mal machen, wie du es vorschlägst. Bleibt mir wohl auch nichts anderes übrig.

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:
type TMyComponent = class(...)
   protected
      procedure setMyProperty(const Value: String);
      function getMyProperty(): String;
   
   published
      property name: String
         read getMyProperty
         write setMyProperty
         stored True;

end;
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.
Und –
Zitat:
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?
Die Frage ist mit JA zu beantworten. Das ist alles weg.
Wolfgang
Grüße und Danke
Wolfgang
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.343 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 12:58
Hier mal ein Auszug aus einem alten Projekt:

Delphi-Quellcode:
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.
TodDataSet war von TComponent abgeleitet:

Delphi-Quellcode:
  TodDataSet = class(TComponent)
  private
...
  protected
...
  public
...
  published
    property PropName: String read get_PropName write set_PropName;
  end;
Das hat so wunderbar funktioniert.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Benutzerbild von Ookami
Ookami

Registriert seit: 20. Nov 2009
Ort: Baden Württemberg
77 Beiträge
 
Delphi 2009 Architect
 
#10

AW: VCL-Komponenten aufeinander aufbauen

  Alt 31. Mär 2014, 13:04
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.
Wolfgang
Grüße und Danke
Wolfgang
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:17 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz