The cause of this issue is located in the Paint method of the TButtonStyleHook
(in the Vcl.StdCtrls unit) style hook class.
Locate this code in the method
if FPressed then
Details := StyleServices.GetElementDetails(tbPushButtonPressed)
else if MouseInControl then //this condition is triggered even if the button is disabled
Details := StyleServices.GetElementDetails(tbPushButtonHot)
else if Focused then //this condition is triggered even if the button is disabled
Details := StyleServices.GetElementDetails(tbPushButtonDefaulted)
else if Control.Enabled then
Details := StyleServices.GetElementDetails(tbPushButtonNormal)
else
Details := StyleServices.GetElementDetails(tbPushButtonDisabled);
And replace for this code
if FPressed then
Details := StyleServices.GetElementDetails(tbPushButtonPressed)
else if MouseInControl and Control.Enabled then
Details := StyleServices.GetElementDetails(tbPushButtonHot)
else if Focused and Control.Enabled then
Details := StyleServices.GetElementDetails(tbPushButtonDefaulted)
else if Control.Enabled then
Details := StyleServices.GetElementDetails(tbPushButtonNormal)
else
Details := StyleServices.GetElementDetails(tbPushButtonDisabled);
Another option is rewrite the Style hook for the TButton :
Check this code based in this article Fixing a VCL Style bug in the TButton component. The advantage of ths code is which you are fixing two issues 103708 and 103962.
Uses
Winapi.CommCtrl,
Vcl.Themes,
Vcl.Styles;
type
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;
{ 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;
begin
if StyleServices.Available then
begin
BCaption := Text;
if Pressed then
LDetails := StyleServices.GetElementDetails(tbPushButtonPressed)
else
if MouseInControl and Control.Enabled then
LDetails := StyleServices.GetElementDetails(tbPushButtonHot)
else
if Focused 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
iaLeft :
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Left + 3, IY, ILD_NORMAL);
Inc(DrawRect.Left, IW + 3);
end;
iaRight :
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, DrawRect.Right - IW -3, IY, ILD_NORMAL);
Dec(DrawRect.Right, IW - 3);
end;
iaCenter:
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW) div 2, IY, ILD_NORMAL);
end;
iaTop :
begin
ImageList_Draw(pbuttonImagelist.himl, 0, Canvas.Handle, (DrawRect.Right - IW) div 2, 3, ILD_NORMAL);
end;
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
iaLeft,
iaRight,
iaCenter : DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_VCENTER or DT_CENTER);
iaBottom : DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_TOP or DT_CENTER);
iaTop : DrawControlText(Canvas, LDetails, BCaption, DrawRect, DT_BOTTOM or DT_CENTER);
end;
end;
end;
end;
{ TButtonStyleHookHelper }
function TButtonStyleHookHelper.DropDown: Boolean;
begin
Result:=Self.FDropDown;
end;
function TButtonStyleHookHelper.Pressed: Boolean;
begin
Result:=Self.FPressed;
end;
initialization
TStyleManager.Engine.RegisterStyleHook(TButton, TButtonStyleHookFix);