delphi – 在VCL风格的表单上禁用TButton问题
发布时间:2020-12-15 10:08:40 所属栏目:大数据 来源:网络整理
导读:当我尝试禁用一个风格的VCL上的按钮使用下面的代码行 TButton(Sender).enabled:= False; 我得到这个结果(在运行时禁用了按钮) 而不是这个! (设计时按钮禁用) 让两个或更多个具有相同颜色的按钮彼此相互混淆确实令人困惑,一个被禁用,另一个被启用 解决方法
|
当我尝试禁用一个风格的VCL上的按钮使用下面的代码行
TButton(Sender).enabled:= False; 我得到这个结果(在运行时禁用了按钮) 而不是这个! (设计时按钮禁用) 让两个或更多个具有相同颜色的按钮彼此相互混淆确实令人困惑,一个被禁用,另一个被启用 解决方法
此问题的原因位于
TButtonStyleHook(在Vcl.StdCtrls单元)样式hook类的Paint方法中.
在方法中找到此代码 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); 并替换此代码 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); 另一个选项是重写TButton的Style钩子: 检查这个代码在这篇文章Fixing a VCL Style bug in the TButton component.这个代码的优点是你正在修复两个问题103708和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,Canvas.Handle,DrawRect.Left + 3,IY,ILD_NORMAL);
Inc(DrawRect.Left,IW + 3);
end;
iaRight :
begin
ImageList_Draw(pbuttonImagelist.himl,DrawRect.Right - IW -3,ILD_NORMAL);
Dec(DrawRect.Right,IW - 3);
end;
iaCenter:
begin
ImageList_Draw(pbuttonImagelist.himl,(DrawRect.Right - IW) div 2,ILD_NORMAL);
end;
iaTop :
begin
ImageList_Draw(pbuttonImagelist.himl,3,ILD_NORMAL);
end;
iaBottom:
begin
ImageList_Draw(pbuttonImagelist.himl,(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,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,Buffer,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,DrawRect);
end;
end
else
if (GetWindowLong(Handle,GWL_STYLE) and BS_SPLITBUTTON) = BS_SPLITBUTTON then
begin
Dec(DrawRect.Right,15);
DrawControlText(Canvas,Text,DT_VCENTER or DT_CENTER);
if DropDown then
begin
LDetails := StyleServices.GetElementDetails(tbPushButtonPressed);
SaveIndex := SaveDC(Canvas.Handle);
try
IntersectClipRect(Canvas.Handle,Control.Width - 15,Control.Width,Control.Height);
DrawRect := Rect(Control.Width - 30,Control.Height);
StyleServices.DrawElement(Canvas.Handle,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,DT_VCENTER or DT_CENTER);
iaBottom : DrawControlText(Canvas,DT_TOP or DT_CENTER);
iaTop : DrawControlText(Canvas,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);
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
