Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Komponentenprogrammierung, ReadOnly -> Farbe wechseln


Jakane - Di 07.05.13 09:52
Titel: Komponentenprogrammierung, ReadOnly -> Farbe wechseln
Hallo liebe Delphi-Helfer :)

nachdem ich gelernt habe Eigenschaften und Ereignisse "verschwinden" zu lassen ;) möchte ich nun auf Ereignisse reagieren, wärend der Programmierzeit.

Mein Beispiel dazu:
Wenn ich ReadOnly auf True setze, möchte ich das Color auf clGray springt.
Wenn ich ReadOnly auf False setze, möchte ich das Color auf clWhite springt.

Weiss leider nicht wonach ich unter Google und Co da suchen muss :D

Danke


Nersgatt - Di 07.05.13 10:01

Du könntest z.B. auf die Message EM_SETREADONLY reagieren.
Du musst dafür eine Procedure nach dem Muster einfügen:


Delphi-Quelltext
1:
procedure OnReadOnlyChanged(var Msg: TMessage); message EM_SETREADONLY;                    


WasWeißDennIch - Di 07.05.13 10:07

Oder man schreibt Setter-Methode für die Eigenschaft. Das ist insbesondere dann nötig, wenn es keine Message für einen Wechsel gibt.


Jakane - Di 07.05.13 10:22

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Du könntest z.B. auf die Message EM_SETREADONLY reagieren.
Du musst dafür eine Procedure nach dem Muster einfügen:


Delphi-Quelltext
1:
procedure OnReadOnlyChanged(var Msg: TMessage); message EM_SETREADONLY;                    



Quelltext
1:
2:
3:
4:
5:
procedure TJEdit.OnReadOnlyChanged(var Msg: TMessage);
begin
  if ReadOnly then Color:= clGray;
  if not ReadOnly then Color:= clWhite;
end;


Beim wechseln von ReadOnly wärend der Programmierzeit reagiert er nicht.

user profile iconWasWeißDennIch hat folgendes geschrieben Zum zitierten Posting springen:
Oder man schreibt Setter-Methode für die Eigenschaft. Das ist insbesondere dann nötig, wenn es keine Message für einen Wechsel gibt.


Wie macht man das?


WasWeißDennIch - Di 07.05.13 10:46

Prinzipiell so:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
type
  TSomeClass = class
  private
    FPropertyname: SomeType;
    procedure SetPropertyname(const Value: SomeType);
  public
    property Propertyname: SomeType read FPropertyName write SetPropertyname;
  end;

procedure TSomeClass.SetPropertyname(const Value: SomeType);
begin
  FPropertyname := Value;
end;

Innerhalb der Setter-Methode kann man dann z.B. Gültigkeitsprüfungen vornehmen oder weitere Methoden aufrufen.


Jakane - Di 07.05.13 11:17

Ganz vielen Dank für den Beispielcode, man muss es ausprobieren um zu verstehen wie und das es geht :D
Aber genau das was ich wollte, Danke


Jakane - Di 07.05.13 11:21

Kann ich die Farbe auch beim "Komponente auf's Formular setzen" vordefinieren?


WasWeißDennIch - Di 07.05.13 11:25

Ich hab mal schnell eine Beispielkomponente geschrieben. Diese verdeckt die Protected ReadOnly-Eigenschaft und führt eine eigene ein, greift dann aber intern auf die geerbte zu:

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:
unit TestEdit;

interface

uses Classes, Controls, StdCtrls, Graphics;

type
  TTestEdit = class(TCustomEdit)
  private
    function GetReadOnly: Boolean;
    procedure SetReadOnly(const Value: Boolean);
  public
    constructor Create(AOwner: TComponent); override;
  published
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly;
    property Align;
    property Alignment;
    property Anchors;
    property AutoSelect;
    property AutoSize;
    property BevelEdges;
    property BevelInner;
    property BevelKind default bkNone;
    property BevelOuter;
    property BevelWidth;
    property BiDiMode;
    property BorderStyle;
    property CharCase;
    property Color;
    property Constraints;
    property Ctl3D;
    property DoubleBuffered;
    property DragCursor;
    property DragKind;
    property DragMode;
    property Enabled;
    property Font;
    property HideSelection;
    property ImeMode;
    property ImeName;
    property MaxLength;
    property NumbersOnly;
    property OEMConvert;
    property ParentBiDiMode;
    property ParentColor;
    property ParentCtl3D;
    property ParentDoubleBuffered;
    property ParentFont;
    property ParentShowHint;
    property PasswordChar;
    property PopupMenu;
    property ShowHint;
    property TabOrder;
    property TabStop;
    property Text;
    property TextHint;
    property Touch;
    property Visible;
    property OnChange;
    property OnClick;
    property OnContextPopup;
    property OnDblClick;
    property OnDragDrop;
    property OnDragOver;
    property OnEndDock;
    property OnEndDrag;
    property OnEnter;
    property OnExit;
    property OnGesture;
    property OnKeyDown;
    property OnKeyPress;
    property OnKeyUp;
    property OnMouseActivate;
    property OnMouseDown;
    property OnMouseEnter;
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDock;
    property OnStartDrag;
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TTestEdit]);
end;

{ TTestEdit }

constructor TTestEdit.Create(AOwner: TComponent);
begin
  inherited;
  ReadOnly := inherited ReadOnly;
end;

function TTestEdit.GetReadOnly: Boolean;
begin
  Result := inherited ReadOnly;
end;

procedure TTestEdit.SetReadOnly(const Value: Boolean);
begin
  inherited ReadOnly := Value;
  if Value then
    Font.Color := clRed
  else
    Font.Color := clGreen;
end;

end.


Jakane - Di 07.05.13 11:41


Quelltext
1:
2:
  published
    property ReadOnly: Boolean read GetReadOnly write SetReadOnly;


Fehler: Inkompatible Typen
beim write...


WasWeißDennIch - Di 07.05.13 13:08

Du hast den gesamten Code so übernommen? Dann dürfte das eigentlich nicht passieren.


Jakane - Di 07.05.13 14:12

Habe den Code so ziemlich übernommen.
Gelöst habe ich es mit F-Variablen

Danke.


WasWeißDennIch - Di 07.05.13 14:15

Dann wird aber das "Original-ReadOnly" ggf. außer Kraft gesetzt. Versuch doch mal, ReadOnly zu setzen und dann in Dein Edit zu schreiben.


Jakane - Di 07.05.13 14:31

So wie es gerade eingestellt ist, funktioniert mein FReadOnly wie es soll.
Ohne das FReadOnly lässt er mich die Komponente ja nicht compilieren :(


WasWeißDennIch - Di 07.05.13 14:37

Das wundert mich zwar, aber ohne Deinen Code zu kennen kann ich natürlich nichts Genaueres dazu sagen.


Jakane - Di 07.05.13 14:50

Was auch immer es war.... beim jetzigen Versuch passierte es nicht...
Hab FReadOnly wieder rausgenommen