I've used this TPanel descendant occasionally. You could adapt it as needed.
unit captionPanel;
{$mode objfpc}{$H+}
interface
uses
Classes, Graphics, ExtCtrls, Controls, LCLIntf;
type
{ TCaptionPanel }
TCaptionPanel = class(TPanel)
private
FTextLayout: TTextLayout;
procedure SetTextLayout(AValue: TTextLayout);
protected
procedure Paint; override;
public
constructor Create(TheOwner: TComponent); override;
published
property Layout: TTextLayout read FTextLayout write SetTextLayout default tlCenter;
end;
implementation
{ TCaptionPanel }
procedure TCaptionPanel.SetTextLayout(AValue: TTextLayout);
begin
if FTextLayout=AValue then Exit;
FTextLayout:=AValue;
Invalidate;
end;
procedure TCaptionPanel.Paint;
var
ARect: TRect;
TS : TTextStyle;
begin
ARect := GetClientRect;
if (BevelOuter <> bvNone) then
Canvas.Frame3d(ARect, BevelWidth, BevelOuter);
InflateRect(ARect, -BorderWidth, -BorderWidth);
if (BevelInner <> bvNone) then
Canvas.Frame3d(ARect, BevelWidth, BevelInner);
if (Caption <> '') then
begin
TS := Canvas.TextStyle;
TS.Alignment := BidiFlipAlignment(Self.Alignment, UseRightToLeftAlignment);
if BiDiMode<>bdLeftToRight then
TS.RightToLeft:= True;
TS.Layout:= FTextLayout;
TS.Opaque:= False;
TS.Clipping:= False;
TS.SystemFont:=Canvas.Font.IsDefault;
if Enabled then
Canvas.Font.Color := Font.Color
else begin
Canvas.Font.Color := clBtnHighlight;
OffsetRect(ARect, 1, 1);
Canvas.TextRect(ARect, ARect.Left, ARect.Top, Caption, TS);
Canvas.Font.Color := clBtnShadow;
OffsetRect(ARect, -1, -1);
end;
Canvas.TextRect(ARect,ARect.Left,ARect.Top, Caption, TS);
end;
end;
constructor TCaptionPanel.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FTextLayout:=tlCenter;
end;
end.