TCustomButtonH =
class(TCustomButton);
// we need this helper to access some strict private fields
TButtonStyleHookHelper =
class Helper
for TButtonStyleHook
protected
function Pressed: Boolean;
function DropDown: Boolean;
end;
// to avoid writting a lot of extra code we are to use TButtonStyleHook class and override the paint method
TButtonStyleHookFix =
class(TButtonStyleHook)
protected
procedure Paint(Canvas: TCanvas);
override;
end;
implementation
{ TButtonStyleHookHelper }
function TButtonStyleHookHelper.DropDown: Boolean;
begin
Result := Self.FDropDown;
end;
function TButtonStyleHookHelper.Pressed: Boolean;
begin
Result := Self.FPressed;
end;
{ TButtonStyleHookFix }
procedure TButtonStyleHookFix.Paint(Canvas: TCanvas);
var
LDetails: TThemedElementDetails;
DrawRect: TRect;
pbuttonImagelist: BUTTON_IMAGELIST;
IW, IH, IY: Integer;
LTextFormatFlags: TTextFormatFlags;
ThemeTextColor: TColor;
Buffer:
string;
BufferLength: Integer;
SaveIndex: Integer;
X, Y, I: Integer;
BCaption:
String;
ctFocused: Boolean;
begin
if StyleServices.Available
then
begin
BCaption := Text;
ctFocused := Control.Focused;
if Pressed
then
LDetails := StyleServices.GetElementDetails(tbPushButtonPressed)
else if MouseInControl
and Control.Enabled
then
LDetails := StyleServices.GetElementDetails(tbPushButtonHot)
else if ctFocused
and Control.Enabled
then
LDetails := StyleServices.GetElementDetails(tbPushButtonDefaulted)
else if Control.Enabled
then
LDetails := StyleServices.GetElementDetails(tbPushButtonNormal)
else
LDetails := StyleServices.GetElementDetails(tbPushButtonDisabled);
DrawRect := Control.ClientRect;
StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);
if Button_GetImageList(
Handle, pbuttonImagelist)
and (pbuttonImagelist.himl <> 0)
and
ImageList_GetIconSize(pbuttonImagelist.himl, IW, IH)
then
begin
if (GetWindowLong(
Handle, GWL_STYLE)
and BS_COMMANDLINK) = BS_COMMANDLINK
then
IY := DrawRect.Top + 15
else
IY := DrawRect.Top + (DrawRect.Height - IH)
div 2;
// here the image is drawn properly according to the ImageAlignment value
case TCustomButton(Control).ImageAlignment
of
Vcl.StdCtrls.iaLeft:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Left + 3, IY, ILD_NORMAL);
Inc(DrawRect.Left, IW + 3);
end;
Vcl.StdCtrls.iaRight:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Right - IW - 3, IY, ILD_NORMAL);
Dec(DrawRect.Right, IW - 3);
end;
Vcl.StdCtrls.iaCenter:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW)
div 2, IY, ILD_NORMAL);
end;
Vcl.StdCtrls.iaTop:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW)
div 2, 3, ILD_NORMAL);
end;
Vcl.StdCtrls.iaBottom:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW)
div 2,
(DrawRect.Height - IH) - 3, ILD_NORMAL);
end;
end;
end;
if (GetWindowLong(
Handle, GWL_STYLE)
and BS_COMMANDLINK) = BS_COMMANDLINK
then
begin
if pbuttonImagelist.himl = 0
then
Inc(DrawRect.Left, 35);
Inc(DrawRect.Top, 15);
Inc(DrawRect.Left, 5);
Canvas.Font := TCustomButtonH(Control).Font;
Canvas.Font.Style := [];
Canvas.Font.Size := 12;
LTextFormatFlags := TTextFormatFlags(DT_LEFT);
if StyleServices.GetElementColor(LDetails, ecTextColor, ThemeTextColor)
then
Canvas.Font.Color := ThemeTextColor;
StyleServices.DrawText(Canvas.Handle, LDetails, BCaption, DrawRect, LTextFormatFlags, Canvas.Font.Color);
SetLength(Buffer, Button_GetNoteLength(
Handle) + 1);
if Length(Buffer) <> 0
then
begin
BufferLength := Length(Buffer);
if Button_GetNote(
Handle, PChar(Buffer), BufferLength)
then
begin
LTextFormatFlags := TTextFormatFlags(DT_LEFT
or DT_WORDBREAK);
Inc(DrawRect.Top, Canvas.TextHeight('
Wq') + 2);
Canvas.Font.Size := 8;
StyleServices.DrawText(Canvas.Handle, LDetails, Buffer, DrawRect, LTextFormatFlags, Canvas.Font.Color);
end;
end;
if pbuttonImagelist.himl = 0
then
begin
if Pressed
then
LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphPressed)
else if MouseInControl
then
LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphHot)
else if Control.Enabled
then
LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphNormal)
else
LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphDisabled);
DrawRect.Right := 35;
DrawRect.Left := 3;
DrawRect.Top := 10;
DrawRect.Bottom := DrawRect.Top + 32;
StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);
end;
end
else if (GetWindowLong(
Handle, GWL_STYLE)
and BS_SPLITBUTTON) = BS_SPLITBUTTON
then
begin
Dec(DrawRect.Right, 15);
DrawControlText(Canvas, LDetails, Text, DrawRect, DT_VCENTER
or DT_CENTER);
if DropDown
then
begin
LDetails := StyleServices.GetElementDetails(tbPushButtonPressed);
SaveIndex := SaveDC(Canvas.Handle);
try
IntersectClipRect(Canvas.Handle, Control.Width - 15, 0, Control.Width, Control.Height);
DrawRect := Rect(Control.Width - 30, 0, Control.Width, Control.Height);
StyleServices.DrawElement(Canvas.Handle, LDetails, DrawRect);
finally
RestoreDC(Canvas.Handle, SaveIndex);
end;
end;
with Canvas
do
begin
Pen.Color := StyleServices.GetSystemColor(clBtnShadow);
MoveTo(Control.Width - 15, 3);
LineTo(Control.Width - 15, Control.Height - 3);
if Control.Enabled
then
Pen.Color := StyleServices.GetSystemColor(clBtnHighlight)
else
Pen.Color := Font.Color;
MoveTo(Control.Width - 14, 3);
LineTo(Control.Width - 14, Control.Height - 3);
Pen.Color := Font.Color;
X := Control.Width - 8;
Y := Control.Height
div 2 + 1;
for I := 3
downto 0
do
begin
MoveTo(X - I, Y - I);
LineTo(X + I + 1, Y - I);
end;
end;
end
else
begin
// finally the text is aligned and drawn depending of the value of the ImageAlignment property
case TCustomButton(Control).ImageAlignment
of
Vcl.StdCtrls.iaLeft,
Vcl.StdCtrls.iaRight,
Vcl.StdCtrls.iaCenter:
DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_VCENTER
or DT_CENTER);
Vcl.StdCtrls.iaBottom:
DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_TOP
or DT_CENTER);
Vcl.StdCtrls.iaTop:
DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_BOTTOM
or DT_CENTER);
end;
end;
end;
end;
initialization
// AUSNAHMEN /FIX:
TStyleManager.Engine.RegisterStyleHook(TButton, TButtonStyleHookFix);
end.