Autor Beitrag
cuejo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Fr 22.09.06 19:06 
Hi
Ich bin's mal wieder:wink:. Und ich bin mal wieder auf ein Problem gestoßen. :?
Also, ich will mir eine Komponente basteln und im großen ganzen funktioniert das auch wunderbar. Nun habe ich viele Farben als property und dachte mir daher, dass ich alle Farben in eine Klasse packe um sie im OI als Node darstellen zu lassen. Das geht ja auch noch. Aber ich schaffe es einfach nicht, dass bei einem wechsel der Farben die Komponente neu gezeichnet wird. Hier mal ein Auszug aus dem was ich bisher geschafft habe:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
//...
type
  TConditionColors = class(TPersistent)
  private
    FFace, FFrame: TColor;
    procedure SetFace(Value: TColor);
    procedure SetFrame(Value: TColor);
  public
    procedure Assign(Source: TPersistent); override;
  published
    property Face: TColor read FFace write SetFace default clGray;
    property Frame: TColor read FFrame write SetFrame default clWhite;
  end;

  TColors = class(TPersistent)
    private
      FBackgroundColor, FBorderColor: TColor;
      FFalseColors, FTrueColors: TConditionColors;
      procedure SetBackgroundColor(Value: TColor);
      procedure SetBorderColor(Value: TColor);
    public
      constructor Create;
      procedure Assign(Source: TPersistent); override;
    published
      property BackgroundColor: TColor read FBackgroundColor
        write SetBackgroundColor default $00F0F0F0;
      property BorderColor: TColor read FBorderColor write SetBorderColor
        default clBlack;
      property FalseColors: TConditionColors read FFalseColors
        write FFalseColors;
      property TrueColors: TConditionColors read FTrueColors write FTrueColors;
    end;

  TPattern = class(TGraphicControl)
  private
    //...
    FColors: TColors;
  protected
    //...  
    procedure Paint; override;
    procedure SetColors(Value: TColors);
  public
    constructor Create(AOwner: TComponent); override;
    //...
  published
    //...
    property Colors: TColors read FColors write SetColors;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Library', [TPattern]);
end;

{***ConditionColors************************************************************}

procedure TConditionColors.Assign(Source: TPersistent);
begin
if Source is TConditionColors then begin
  Self.Face:=TConditionColors(Source).Face;
  Self.Frame:=TConditionColors(Source).Frame;
end else
  if Source is TPersistent then inherited Assign(Source);
end;

procedure TConditionColors.SetFace(Value: TColor);
begin
FFace:=Value;
end;

procedure TConditionColors.SetFrame(Value: TColor);
begin
FFrame:=Value;
end;

{***Colors*********************************************************************}

constructor TColors.Create;
begin
inherited Create;
FFalseColors:=TConditionColors.Create;
FTrueColors:=TConditionColors.Create;
end;

procedure TColors.Assign(Source: TPersistent);
begin
if Source is TColors then begin
  Self.BackgroundColor:=TColors(Source).BackgroundColor;
  Self.BorderColor:=TColors(Source).BorderColor;
  Self.FalseColors.Assign(TColors(Source).FalseColors);
  Self.TrueColors.Assign(TColors(Source).TrueColors);
end else
  if Source is TPersistent then inherited Assign(Source);
end;

procedure TColors.SetBackgroundColor(Value: TColor);
begin
FBackgroundColor:=Value;
end;

procedure TColors.SetBorderColor(Value: TColor);
begin
FBorderColor:=Value;
end;

{***Pattern********************************************************************}

constructor TPattern.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//defaults
//...
FColors:=TColors.Create;
FColors.FBackgroundColor:=$00F0F0F0;      
FColors.FBorderColor:=clBlack;
FColors.FFalseColors.FFace:=clWhite;
//usw
end;

procedure TPattern.SetColors(Value: TColors);
begin
FColors.Assign(Value);
Paint;  {* <--- hier müsste doch eigentlich neu gezeichnet werden, wenn ich 
         irgendwas von Colors ändere!?!*}

end;

procedure TPattern.Paint;
begin
inherited;
with Canvas do begin  //... zeichnen halt ;)
end;

//...

end.

Also die gute Nachricht ist das es so funktioniert wie ich es haben will, nur SetColors() führt meine Komponente anscheinend nicht aus, obwohl es in der property als write definiert ist. Was mache ich falsch?

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.
Marco D.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2750

Windows Vista
Delphi 7, Delphi 2005 PE, PHP 4 + 5 (Notepad++), Java (Eclipse), XML, XML Schema, ABAP, ABAP OO
BeitragVerfasst: Sa 23.09.06 11:03 
In einer von mir geschrieben Komponente heißt es in der überschriebenen Paint-Methode:
ausblenden Delphi-Quelltext
1:
2:
 //Paint-Methode der Mutterklasse aurufen
  inherited Paint;

Bei dir steht nur inherited. :nixweiss:

_________________
Pascal keeps your hand tied. C gives you enough rope to hang yourself. C++ gives you enough rope to shoot yourself in the foot
jakobwenzel
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1889
Erhaltene Danke: 1

XP home, ubuntu
BDS 2006 Prof
BeitragVerfasst: Sa 23.09.06 11:12 
Man muss den Methodennamen beim inherited nur hinschreiben, wenns andere Parameter sind.

_________________
I thought what I'd do was, I'd pretend I was one of those deaf-mutes.
cuejo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Sa 23.09.06 14:28 
Nun wie gesagt, das zeichen funktioniert ja so weit. Nur reagiert es nicht auf eine Veränderung des Farben-Nodes mit einer Neuzeichnung der Komponente. :(

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 23.09.06 14:32 
Hallo!

Der Setter für die Property wird wahrscheinlich gar nicht aufgerufen. Denn Du setzt ja keinen neuen Wert bei "Colors", sondern veränderst nur etwas an der existierenden Instanz! Geh mal im Einzelschritt durch und schau mal, ob die entsprechdenden Zeilen überhaupt "angesteuert" werden.

Grüße
Christian

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
cuejo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Sa 23.09.06 18:59 
user profile iconChristian S. hat folgendes geschrieben:

Der Setter für die Property wird wahrscheinlich gar nicht aufgerufen.

Ja das stimmt. Hab's überprüft. Wenn ich beispielsweise Colors.BackgroundColor von TPattern verändere, dann wird nur der Setter von TColors aufgerufen, nicht aber der Setter von TPattern. Wie kriege ich das jetzt hin? :autsch:

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.
cuejo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Mi 27.09.06 16:34 
Hat jemand eine Idee?

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mi 27.09.06 16:40 
Du müsstest eigentlich nur einen Owner in TColors einbauen. Dieser wird der Create-Methode vom Pattern übergeben. Damit kennt die TColors-Instanz wer sie besitzt und kann dann ein Refresh auslösen, wenn es gebraucht wird.
cuejo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Mi 27.09.06 16:53 
Jetzt stehe ich leider ziehmlich auf dem Schlauch. Kannst du mir erklären wie das geht? :nixweiss:

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.
UGrohne
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Veteran
Beiträge: 5502
Erhaltene Danke: 220

Windows 8 , Server 2012
D7 Pro, VS.NET 2012 (C#)
BeitragVerfasst: Mi 27.09.06 17:59 
Ich hab mal die entsprechenden Änderungen an Deinem Code vorgenommen und diese hervorgehoben:
ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
//...
type
  TConditionColors = class(TPersistent)
  private
    FFace, FFrame: TColor;
    procedure SetFace(Value: TColor);
    procedure SetFrame(Value: TColor);
  public
    procedure Assign(Source: TPersistent); override;
  published
    property Face: TColor read FFace write SetFace default clGray;
    property Frame: TColor read FFrame write SetFrame default clWhite;
  end;

  TColors = class(TPersistent)
    private
      FOwner: TPattern;
      FBackgroundColor, FBorderColor: TColor;
      FFalseColors, FTrueColors: TConditionColors;
      procedure SetBackgroundColor(Value: TColor);
      procedure SetBorderColor(Value: TColor);
    public
      constructor Create(AOwner: TPattern);
      procedure Assign(Source: TPersistent); override;
    published
      property BackgroundColor: TColor read FBackgroundColor
        write SetBackgroundColor default $00F0F0F0;
      property BorderColor: TColor read FBorderColor write SetBorderColor
        default clBlack;
      property FalseColors: TConditionColors read FFalseColors
        write FFalseColors;
      property TrueColors: TConditionColors read FTrueColors write FTrueColors;
    end;

  TPattern = class(TGraphicControl)
  private
    //...
    FColors: TColors;
  protected
    //...  
    procedure Paint; override;
    procedure SetColors(Value: TColors);
  public
    constructor Create(AOwner: TComponent); override;
    //...
  published
    //...
    property Colors: TColors read FColors write SetColors;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Library', [TPattern]);
end;

{***ConditionColors************************************************************}

procedure TConditionColors.Assign(Source: TPersistent);
begin
if Source is TConditionColors then begin
  Self.Face:=TConditionColors(Source).Face;
  Self.Frame:=TConditionColors(Source).Frame;
end else
  if Source is TPersistent then inherited Assign(Source);
end;

procedure TConditionColors.SetFace(Value: TColor);
begin
FFace:=Value;
end;

procedure TConditionColors.SetFrame(Value: TColor);
begin
FFrame:=Value;
end;

{***Colors*********************************************************************}

constructor TColors.Create;
begin
inherited Create;
FFalseColors:=TConditionColors.Create;
FTrueColors:=TConditionColors.Create;
FOwner := AOwner;
end;

procedure TColors.Assign(Source: TPersistent);
begin
if Source is TColors then begin
  Self.BackgroundColor:=TColors(Source).BackgroundColor;
  Self.BorderColor:=TColors(Source).BorderColor;
  Self.FalseColors.Assign(TColors(Source).FalseColors);
  Self.TrueColors.Assign(TColors(Source).TrueColors);
end else
  if Source is TPersistent then inherited Assign(Source);
end;

procedure TColors.SetBackgroundColor(Value: TColor);
begin
FBackgroundColor:=Value;
FOwner.Invalidate //oder Paint public deklarieren und das aufrufen
end;

procedure TColors.SetBorderColor(Value: TColor);
begin
FBorderColor:=Value;
end;

{***Pattern********************************************************************}

constructor TPattern.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
//defaults
//...
FColors:=TColors.Create;
FColors.FBackgroundColor:=$00F0F0F0;      
FColors.FBorderColor:=clBlack;
FColors.FFalseColors.FFace:=clWhite;
//usw
end;

procedure TPattern.SetColors(Value: TColors);
begin
FColors.Assign(Value);
Paint;  {* <--- hier müsste doch eigentlich neu gezeichnet werden, wenn ich 
         irgendwas von Colors ändere!?!*}

end;

procedure TPattern.Paint;
begin
inherited;
with Canvas do begin  //... zeichnen halt ;)
end;

//...
end.

Ich weiß nicht, ob das mit Invalidate funktionieren wird. Wenn nicht, musst Du die Paint-Methode public deklarieren und diese dann aufrufen.
cuejo Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 142

Win XP
Delphi 7 Personal und 2005 PE
BeitragVerfasst: Mi 27.09.06 18:14 
user profile iconUGrohne du bist göttlich! :flehan:
Danke! :zustimm: Du glaubst gar nicht wie ich mich mit diesem Problem gequält habe. (Ich konnte Repaint übrigens direkt aufrufen.)

_________________
Computer sind dumm, aber fleißig. Deshalb arbeite ich so gerne damit.