Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - TPanel neu zeichnen?


jjturbo - Di 30.03.10 08:25
Titel: TPanel neu zeichnen?
Moin Forum,

ich habe hier eine Komponente die von TPanel abgeleitet ist. Auf dieser werden weitere Panels gezeichnet.
Wenn ich meine Anwendung starte, dann sieht die Kompo aus wie im Bild ...028 (Siehe Anhang), wenn ich dann mit ALT+TAB zu einer anderen Anwendung und anschließend wieder zurück wechsle, dann sieht sie aus wie im Bild ...029. So wäre es dann auch richtig.
Wie kann ich meine Komponente dazu bewegen sich neu zu zeichnen wenn es erforderlich ist?
Wenn ich in einem Timer ein Repaint aufrufe wird es richtig dargestellt, ist aber nicht sonderlich elegant, geht bestimmt besser, oder?


Tastaro - Di 30.03.10 08:50

Wenn es sich schon um eine eigene Komponente handelt, dann kannst du einfach die paint-Methode überschreiben. Dann kann nix gemalt werden was du nicht willst.

Beste Grüße


jjturbo - Di 30.03.10 09:13

Könntest Du das etwas weiter ausführen?
Was muß ich denn in der neuen Paint-Methode machen? Jedes einzelne Rechteck neu zeichnen?
Wäre nett, wenn mir jemand mit einem kleinen Beispiel auf die Sprünge helfen könnte.

---Moderiert von user profile iconNarses: Beiträge zusammengefasst---

Habe es so hinbekommen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
type
  TMyKompo= class(TPanel)
  private
    FOnPaint        :TNotifyEvent;
//...
  protected
    procedure Paint; override;
//...

procedure TMyKompo.Paint;
begin

  inherited;
  if assigned(fOnPaint)
   then fOnPaint(Self);

end;


Tastaro - Di 30.03.10 10:41

Die paint Methode wird immer dann aufgerufen wenn das Panel neu gezeichnet wird. Wenn du sie überschreibst, dann wird nur das gemalt, was du programmiert hast.

Ich habe eine, die etwas so aussieht:

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:
type
   TMyPanel = class(TCustomPanel)
   private
      { Private-Deklarationen }
      iFrameColor: tcolor;
   protected
      { Protected-Deklarationen }
      procedure Paint;
                override;
   public
      { Public-Deklarationen }
      property DockManager;

      constructor Create(AOwner: TComponent);
                  reintroduceoverride;
   published
      property Align;
      property Alignment;
      property Anchors;
      property AutoSize;
      property BevelInner;
      property BevelOuter;
      property BevelWidth;
      property BiDiMode;
      property BorderWidth;
      property BorderStyle;
      property Caption;
      property Color;
      property Constraints;
      property Ctl3D;
      property UseDockManager default True;
      property DockSite;
      property DragCursor;
      property DragKind;
      property DragMode;
      property Enabled;
      property FullRepaint;
      property Font;
      property Locked;
      property ParentBiDiMode;
      property ParentBackground;
      property ParentColor;
      property ParentCtl3D;
      property ParentFont;
      property ParentShowHint;
      property PopupMenu;
      property ShowHint;
      property TabOrder;
      property TabStop;
      property Visible;
      property OnCanResize;
      property OnClick;
      property OnConstrainedResize;
      property OnContextPopup;
      property OnDockDrop;
      property OnDockOver;
      property OnDblClick;
      property OnDragDrop;
      property OnDragOver;
      property OnEndDock;
      property OnEndDrag;
      property OnEnter;
      property OnExit;
      property OnGetSiteInfo;
      property OnMouseDown;
      property OnMouseMove;
      property OnMouseUp;
      property OnResize;
      property OnStartDock;
      property OnStartDrag;
      property OnUnDock;
      { Published-Deklarationen }
      property FrameColor: tcolor
               read iFrameColor
               write iFrameColor;

   end;

implementation

constructor TMyPanel.create(AOwner: TComponent);
begin
   inherited create(AOwner);
   Height := 44;
   Width := 120;
   iFrameColor := clBtnShadow;
end;

procedure TMyPanel.paint;
const
   aiAlignments: array[talignment] of integer = (DT_LEFT, DT_RIGHT, DT_CENTER);
var
   recRect: trect;
   iTopColor: tcolor;
   iBottomColor: tcolor;
   iFontHeight: integer;
   iFlags: integer;

   procedure adjust_colors(Bevel: TPanelBevel);
   begin
      iTopColor := clWhite;
      if Bevel = bvLowered then
         iTopColor := iFrameColor;
      iBottomColor := iFrameColor;
      if Bevel = bvLowered then
         iBottomColor := clWhite;
   end;

begin
   recRect := GetClientRect;
   if BevelOuter <> bvNone then
   begin
      adjust_colors(BevelOuter);
      Frame3D(Canvas, recRect, iTopColor, iBottomColor, BevelWidth);
   end;
   Frame3D(Canvas, recRect, Color, Color, BorderWidth);
   if BevelInner <> bvNone then
   begin
      adjust_colors(BevelInner);
      Frame3D(Canvas, recRect, iTopColor, iBottomColor, BevelWidth);
   end;
   Canvas.Brush.Color := Color;
   Canvas.fillrect(recRect);
   Canvas.Brush.Style := bsClear;
   Canvas.Font := Self.Font;
   iFontHeight := Canvas.textheight('W');
   recRect.Top := ((recRect.Bottom + recRect.Top) - iFontHeight) div 2;
   recRect.Bottom := recRect.Top + iFontHeight;
   iFlags := DT_EXPANDTABS or DT_VCENTER or aiAlignments[Alignment];
   iFlags := DrawTextBiDiModeFlags(iFlags);
   drawtext(Canvas.Handle, pchar(Caption), -1, recRect, iFlags);
end;


Aber prinzipiell ist es egal was du malst. Sie kann natürlich auch deine grünen Rechtecke ausgeben.

Beste Grüße

Edit: Nee, nicht das OnPaint aufrufen, sondern die Ausgabe direkt in die paint Methode. Dafür ist sie ja da. :)