Skip to content

Styled Buttons and Panels with VCL Styles Demo ​

Overview ​

In the first page of this demo shows a comprehensive side-by-side comparison of standard VCL buttons and TStyledButton across all installed VCL Styles, demonstrating how StyledComponents maintain consistent appearance regardless of the active VCL Style.

The second page shows a comprehensive side-by-side comparison of the standard VCL panels and TStyledPanel across all installed VCL styles, demonstrating how StyledComponents maintain a consistent look regardless of the active VCL style.

What You'll Learn ​

  • How TStyledButton renders independently of VCL Styles
  • Comparison with standard TButton across all VCL Styles
  • Different button styles (PushButton, SplitButton, CommandLink)
  • Creating hundreds of buttons dynamically
  • FAB (Floating Action Button) mode
  • TStyledPanel rendering with VCL Styles
  • Per-button VCL Style assignment (Delphi 10.4+)

Demo Layout ​

The demo has two main tabs:

1. Styled Buttons Tab ​

Styled Button VCL Styles Demo

Two side-by-side scrollable panels:

Left Panel: Standard VCL Buttons ​

  • One TButton for each installed VCL Style
  • Buttons use StyleName property (Delphi 10.4+)
  • Shows how each VCL Style affects standard buttons
  • Renders differently based on active style

Right Panel: TStyledButton ​

  • One TStyledButton for each VCL Style name
  • Uses StyleClass to identify each style
  • Consistent rendering regardless of active VCL Style
  • Modern, predictable appearance

2. Styled Panels Tab ​

Styled Panel VCL Styles Demo

Similar layout comparing:

  • Standard TPanel (left)
  • TStyledPanel (right)

Both with StyleName for each VCL Style.

Render Options ​

Same as VCL (AsVCLComponent) ​

pascal
StyledButton.AsVCLComponent := True;

Renders like standard VCL button (maintains VCL Style appearance).

Rounded Buttons ​

pascal
// All buttons with btRounded
RenderRadioGroup.ItemIndex := RENDER_ROUNDED;

Round Rectangle Buttons ​

pascal
// All buttons with btRoundRect
RenderRadioGroup.ItemIndex := RENDER_ROUNDRECT;

Rectangle Buttons ​

pascal
// All buttons with btRect
RenderRadioGroup.ItemIndex := RENDER_RECTANGLE;

FAB (Floating Action Buttons) ​

pascal
// Circular icon buttons
RenderRadioGroup.ItemIndex := RENDER_FAB;
Button.StyleDrawType := btEllipse;
Button.Images := ImageList;
Button.ImageAlignment := iaCenter;

Button Style Options ​

Push Button (bsPushButton) ​

Standard clickable button:

pascal
Button.Style := bsPushButton;

Split Button (bsSplitButton) ​

Button with dropdown menu:

pascal
Button.Style := bsSplitButton;
Button.DropDownMenu := PopupMenu1;

Button with main caption and hint:

pascal
Button.Style := bsCommandLink;
Button.Caption := 'Action';
Button.CommandLinkHint := 'Description of action...';

Command links are taller and include explanatory text.

Dynamic Button Creation ​

The demo creates buttons dynamically for all installed VCL Styles:

Get Available Styles ​

pascal
procedure BuildStyleList;
var
  I: integer;
begin
  FStyleNames := TStringList.Create;
  for I := 0 to High(TStyleManager.StyleNames) do
    FStyleNames.Add(TStyleManager.StyleNames[i]);
  FStyleNames.Sorted := True;
end;

Create VCL Buttons ​

pascal
procedure CreateVCLButton(AColumn, ATop: Integer; AStyleName: string);
var
  LButton: TButton;
begin
  LButton := TButton.Create(Self);
  LButton.SetBounds(AColumn * LWidth + MARGIN,
    ATop, LWidth, LHeight);
  LButton.Style := bsPushButton;  // or bsSplitButton, bsCommandLink
  {$IFDEF D10_4+}
  LButton.StyleName := AStyleName;  // Per-button style
  {$ENDIF}
  LButton.Caption := AStyleName;
  LButton.Parent := LeftScrollBox;
end;

Create Styled Buttons ​

pascal
procedure CreateStyledButton(AColumn, ATop: Integer; AStyleName: string);
var
  LButton: TStyledButton;
  LAsVcl: Boolean;
begin
  LAsVcl := RenderRadioGroup.ItemIndex = RENDER_SAME_AS_VCL;

  LButton := TStyledButton.CreateStyled(Self,
    DEFAULT_CLASSIC_FAMILY,
    AStyleName,  // Use style name as class
    DEFAULT_APPEARANCE,
    DEFAULT_STYLEDRAWTYPE,
    DEFAULT_CURSOR,
    not LAsVcl);  // AsVCLComponent parameter

  LButton.SetBounds(AColumn * LWidth + MARGIN,
    ATop, LWidth, LHeight);

  case RenderRadioGroup.ItemIndex of
    RENDER_ROUNDED: LButton.StyleDrawType := btRounded;
    RENDER_ROUNDRECT: LButton.StyleDrawType := btRoundRect;
    RENDER_RECTANGLE: LButton.StyleDrawType := btRect;
    RENDER_FAB:
    begin
      LButton.StyleDrawType := btEllipse;
      LButton.Images := ImageList;
      LButton.ImageAlignment := iaCenter;
      LButton.ImageIndex := I mod ImageList.Count;
    end;
  end;

  LButton.Caption := AStyleName;
  LButton.Parent := RightScrollBox;
end;

Layout Algorithm ​

Buttons are arranged in a grid:

pascal
LColumn := (I mod ButtonsInColumn);  // Column position
LRow := (I div ButtonsInColumn);     // Row position
Top := LRow * (ButtonHeight + MARGIN);
Left := LColumn * (ButtonWidth + MARGIN);

The number of columns adjusts based on panel width.

Responsive Resizing ​

The demo recalculates layout on resize:

pascal
procedure TfmStyledButtonVCLStyles.FormResize(Sender: TObject);
begin
  if LeftPanel.Width <> ClientWidth div 2 then
  begin
    LeftPanel.Width := ClientWidth div 2;
    CreateAllButtons(False);  // Rebuild layout
  end;
end;

Mouse Wheel Scrolling ​

Enhanced scrolling for large button lists:

pascal
procedure ScrollBoxMouseWheel(Sender: TObject; Shift: TShiftState;
  WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
var
  msg, code: Cardinal;
  i, n: Integer;
begin
  Handled := True;
  if ssShift in Shift then
    msg := WM_HSCROLL
  else
    msg := WM_VSCROLL;

  if WheelDelta > 0 then
    code := SB_LINEUP
  else
    code := SB_LINEDOWN;

  n := Mouse.WheelScrollLines * 4;  // Speed up
  for i := 1 to n do
  begin
    LeftScrollBox.Perform(msg, code, 0);
    RightScrollBox.Perform(msg, code, 0);
  end;

  LeftScrollBox.Perform(msg, SB_ENDSCROLL, 0);
  RightScrollBox.Perform(msg, SB_ENDSCROLL, 0);
end;

VCL Styles Comparison ​

The demo shows how each VCL Style affects rendering:

Standard TButton ​

  • Appearance changes with active VCL Style
  • Each button can have StyleName (10.4+)
  • Inconsistent across styles
  • Limited customization

TStyledButton ​

  • Consistent appearance across all VCL Styles
  • Independent rendering (GDI+)
  • Full customization options
  • Modern, predictable look

Key Observations ​

1. Independence from VCL Styles ​

TStyledButton renders the same regardless of:

  • Active VCL Style
  • Windows theme
  • System colors

2. Per-Button Styling (Delphi 10.4+) ​

Standard TButton can use StyleName:

pascal
Button1.StyleName := 'Windows10 Blue';
Button2.StyleName := 'Glow';

But still limited compared to TStyledButton customization.

3. AsVCLComponent Property ​

When set to True, TStyledButton mimics VCL rendering:

pascal
StyledButton.AsVCLComponent := True;

Useful for gradual migration or hybrid interfaces.

Styled Panels Comparison ​

The second tab shows TStyledPanel vs. TPanel:

Standard TPanel ​

  • Uses VCL Style colors
  • Requires ParentBackground := False for styling
  • Appearance varies by style

TStyledPanel ​

  • Consistent styled rendering
  • Independent of VCL Styles
  • Full customization options

Interactive Controls ​

For Buttons ​

  • Render Options: Same as VCL, Rounded, RoundRect, Rectangle, FAB
  • Style Options: PushButton, SplitButton, CommandLink
  • Enabled Checkbox: Enable/disable all buttons
  • Outline Checkbox: Use outline appearance

For Panels ​

  • Render Options: Same as VCL, Rounded, RoundRect, Rectangle
  • Show Caption: Toggle panel captions
  • Outline Checkbox: Use outline appearance

Performance ​

The demo creates hundreds of buttons:

  • ~50+ VCL Styles × 2 = 100+ buttons total
  • Dynamic creation/destruction
  • Efficient layout calculation
  • Smooth scrolling

Use Cases ​

1. Style Independence ​

Applications that must look the same regardless of VCL Style.

2. Custom Branding ​

Corporate colors and styles that don't match any VCL Style.

3. Modern UI ​

Web-like or Material Design interfaces.

4. Consistent Multi-Platform ​

Same look across different Windows versions.

Technical Details ​

Source Location ​

Demos/source/StyledButtonVCLStylesForm.pas

Supported Versions ​

  • All Delphi versions (XE6+)
  • Per-button StyleName requires Delphi 10.4+

Key Constants ​

pascal
const
  RENDER_SAME_AS_VCL = 0;
  RENDER_ROUNDED = 1;
  RENDER_ROUNDRECT = 2;
  RENDER_RECTANGLE = 3;
  RENDER_FAB = 4;

  STYLE_PUSHBUTTON = 0;
  STYLE_SPLITBUTTON = 1;
  STYLE_COMMANDLINK = 2;

Button Sizing ​

  • Width: 150px (180px for CommandLinks)
  • Height: 28px (68px for CommandLinks)
  • Margin: 4px
  • FAB: 56x56px

Best Practices ​

1. Consistent Rendering ​

Use TStyledButton when you need:

  • Same look across VCL Styles
  • Custom branding
  • Modern appearance

2. VCL Compatibility ​

Use AsVCLComponent := True when:

  • Migrating gradually
  • Need VCL Style integration
  • Hybrid interfaces

3. Performance ​

For large button counts:

  • Create dynamically
  • Use flow panels
  • Implement virtual scrolling

See Also ​

Released under Apache License, Version 2.0.