Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How I can change the color of a TPanel with the VCL Styles enabled?

I need to change the color of a TPanel when the VCL styles are enabled. I tried using and modifying the code listed in the article Changing the color of Edit Controls with VCL Styles Enabled, but it is not working for a TPanel. How I can change the color of a TPanel with the VCL Styles enabled?

like image 746
Salvador Avatar asked Apr 25 '12 04:04

Salvador


3 Answers

The TPanel doesn't use a style hook to draw the control, so you can't use the technique described in the article. instead you must override the paint method.

Check this sample using a interposer class.

type

  TPanel=Class(Vcl.ExtCtrls.TPanel)
  protected
    procedure Paint; override;
  End;


Uses
  Vcl.Styles,
  Vcl.Themes;

{$R *.dfm}

{ TPanel }

procedure TPanel.Paint;
const
  Alignments: array[TAlignment] of Longint = (DT_LEFT, DT_RIGHT, DT_CENTER);
  VerticalAlignments: array[TVerticalAlignment] of Longint = (DT_TOP, DT_BOTTOM, DT_VCENTER);
var
  Rect: TRect;
  LColor: TColor;
  LStyle: TCustomStyleServices;
  LDetails: TThemedElementDetails;
  TopColor        : TColor;
  BottomColor     : TColor;
  LBaseColor      : TColor;
  LBaseTopColor   : TColor;
  LBaseBottomColor: TColor;
  Flags: Longint;

  procedure AdjustColors(Bevel: TPanelBevel);
  begin
    TopColor := LBaseTopColor;
    if Bevel = bvLowered then
      TopColor := LBaseBottomColor;
    BottomColor := LBaseBottomColor;
    if Bevel = bvLowered then
      BottomColor := LBaseTopColor;
  end;

begin
  Rect := GetClientRect;

  LBaseColor := Color;//use the color property value to get the background color.
  LBaseTopColor := clBtnHighlight;
  LBaseBottomColor := clBtnShadow;
  LStyle := StyleServices;
  if LStyle.Enabled then
  begin
    LDetails := LStyle.GetElementDetails(tpPanelBevel);
    if LStyle.GetElementColor(LDetails, ecEdgeHighLightColor, LColor) and (LColor <> clNone) then
      LBaseTopColor := LColor;
    if LStyle.GetElementColor(LDetails, ecEdgeShadowColor, LColor) and (LColor <> clNone) then
      LBaseBottomColor := LColor;
  end;

  if BevelOuter <> bvNone then
  begin
    AdjustColors(BevelOuter);
    Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
  end;
  if not (LStyle.Enabled and (csParentBackground in ControlStyle)) then
    Frame3D(Canvas, Rect, LBaseColor, LBaseColor, BorderWidth)
  else
    InflateRect(Rect, -Integer(BorderWidth), -Integer(BorderWidth));
  if BevelInner <> bvNone then
  begin
    AdjustColors(BevelInner);
    Frame3D(Canvas, Rect, TopColor, BottomColor, BevelWidth);
  end;
  with Canvas do
  begin
    if not LStyle.Enabled or not ParentBackground then
    begin
      Brush.Color := LBaseColor;
      FillRect(Rect);
    end;

    if ShowCaption and (Caption <> '') then
    begin
      Brush.Style := bsClear;
      Font := Self.Font;
      Flags := DT_EXPANDTABS or DT_SINGLELINE or
        VerticalAlignments[VerticalAlignment] or Alignments[Alignment];
      Flags := DrawTextBiDiModeFlags(Flags);
      if LStyle.Enabled then
      begin
        LDetails := LStyle.GetElementDetails(tpPanelBackground);
        if not LStyle.GetElementColor(LDetails, ecTextColor, LColor) or (LColor = clNone) then
          LColor := Font.Color;
        LStyle.DrawText(Handle, LDetails, Caption, Rect, TTextFormatFlags(Flags), LColor)
      end
      else
        DrawText(Handle, Caption, -1, Rect, Flags);
    end;
  end;
end;

enter image description here

like image 156
RRUZ Avatar answered Oct 21 '22 18:10

RRUZ


In XE5, if you turn off the seClient flag in the StyleElements property, then the Color property works again as expected.

like image 31
costa Avatar answered Oct 21 '22 17:10

costa


Based on @costa's answer, use:

StyleElements := StyleElements - [seClient];

in the constructor of your TPanel descendent class

or if you just have some TPanel (or descendent class) instance you can do:

with myPanel do StyleElements := StyleElements - [seClient];

The -[...] syntax is used since the StyleElements is a set

For more on StyleElements read this article:

Tuning VCL Styles for Forms and Controls - http://edn.embarcadero.com/article/42812

like image 22
George Birbilis Avatar answered Oct 21 '22 16:10

George Birbilis