delphi – 在VCL风格的表单上禁用TButton问题

前端之家收集整理的这篇文章主要介绍了delphi – 在VCL风格的表单上禁用TButton问题前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当我尝试禁用一个风格的VCL上的按钮使用下面的代码
  1. TButton(Sender).enabled:= False;

我得到这个结果(在运行时禁用了按钮)

而不是这个! (设计时按钮禁用)

让两个或更多个具有相同颜色的按钮彼此相互混淆确实令人困惑,一个被禁用,另一个被启用

解决方法

此问题的原因位于 TButtonStyleHook(在Vcl.StdCtrls单元)样式hook类的Paint方法中.

方法中找到此代码

  1. if FPressed then
  2. Details := StyleServices.GetElementDetails(tbPushButtonPressed)
  3. else if MouseInControl then //this condition is triggered even if the button is disabled
  4. Details := StyleServices.GetElementDetails(tbPushButtonHot)
  5. else if Focused then //this condition is triggered even if the button is disabled
  6. Details := StyleServices.GetElementDetails(tbPushButtonDefaulted)
  7. else if Control.Enabled then
  8. Details := StyleServices.GetElementDetails(tbPushButtonNormal)
  9. else
  10. Details := StyleServices.GetElementDetails(tbPushButtonDisabled);

并替换此代码

  1. if FPressed then
  2. Details := StyleServices.GetElementDetails(tbPushButtonPressed)
  3. else if MouseInControl and Control.Enabled then
  4. Details := StyleServices.GetElementDetails(tbPushButtonHot)
  5. else if Focused and Control.Enabled then
  6. Details := StyleServices.GetElementDetails(tbPushButtonDefaulted)
  7. else if Control.Enabled then
  8. Details := StyleServices.GetElementDetails(tbPushButtonNormal)
  9. else
  10. Details := StyleServices.GetElementDetails(tbPushButtonDisabled);

另一个选项是重写TButton的Style钩子:

检查这个代码在这篇文章Fixing a VCL Style bug in the TButton component.这个代码的优点是你正在修复两个问题103708103962.

  1. Uses
  2. Winapi.CommCtrl,Vcl.Themes,Vcl.Styles;
  3.  
  4. type
  5. TCustomButtonH=class(TCustomButton);
  6.  
  7. //we need this helper to access some strict private fields
  8. TButtonStyleHookHelper = class Helper for TButtonStyleHook
  9. protected
  10. function Pressed : Boolean;
  11. function DropDown: Boolean;
  12. end;
  13.  
  14. //to avoid writting a lot of extra code we are to use TButtonStyleHook class and override the paint method
  15. TButtonStyleHookFix = class(TButtonStyleHook)
  16. protected
  17. procedure Paint(Canvas: TCanvas); override;
  18. end;
  19.  
  20.  
  21. { TButtonStyleHookFix }
  22.  
  23. procedure TButtonStyleHookFix.Paint(Canvas: TCanvas);
  24. var
  25. LDetails : TThemedElementDetails;
  26. DrawRect : TRect;
  27. pbuttonImagelist : BUTTON_IMAGELIST;
  28. IW,IH,IY : Integer;
  29. LTextFormatFlags : TTextFormatFlags;
  30. ThemeTextColor : TColor;
  31. Buffer : string;
  32. BufferLength : Integer;
  33. SaveIndex : Integer;
  34. X,Y,I : Integer;
  35. BCaption : String;
  36. begin
  37.  
  38. if StyleServices.Available then
  39. begin
  40. BCaption := Text;
  41.  
  42. if Pressed then
  43. LDetails := StyleServices.GetElementDetails(tbPushButtonPressed)
  44. else
  45. if MouseInControl and Control.Enabled then
  46. LDetails := StyleServices.GetElementDetails(tbPushButtonHot)
  47. else
  48. if Focused and Control.Enabled then
  49. LDetails := StyleServices.GetElementDetails(tbPushButtonDefaulted)
  50. else
  51. if Control.Enabled then
  52. LDetails := StyleServices.GetElementDetails(tbPushButtonNormal)
  53. else
  54. LDetails := StyleServices.GetElementDetails(tbPushButtonDisabled);
  55.  
  56. DrawRect := Control.ClientRect;
  57. StyleServices.DrawElement(Canvas.Handle,LDetails,DrawRect);
  58.  
  59. if Button_GetImageList(handle,pbuttonImagelist) and (pbuttonImagelist.himl <> 0) and ImageList_GetIconSize(pbuttonImagelist.himl,IW,IH) then
  60. begin
  61. if (GetWindowLong(Handle,GWL_STYLE) and BS_COMMANDLINK) = BS_COMMANDLINK then
  62. IY := DrawRect.Top + 15
  63. else
  64. IY := DrawRect.Top + (DrawRect.Height - IH) div 2;
  65.  
  66. //here the image is drawn properly according to the ImageAlignment value
  67. case TCustomButton(Control).ImageAlignment of
  68. iaLeft :
  69. begin
  70. ImageList_Draw(pbuttonImagelist.himl,Canvas.Handle,DrawRect.Left + 3,IY,ILD_NORMAL);
  71. Inc(DrawRect.Left,IW + 3);
  72. end;
  73. iaRight :
  74. begin
  75. ImageList_Draw(pbuttonImagelist.himl,DrawRect.Right - IW -3,ILD_NORMAL);
  76. Dec(DrawRect.Right,IW - 3);
  77. end;
  78.  
  79. iaCenter:
  80. begin
  81. ImageList_Draw(pbuttonImagelist.himl,(DrawRect.Right - IW) div 2,ILD_NORMAL);
  82. end;
  83.  
  84.  
  85. iaTop :
  86. begin
  87. ImageList_Draw(pbuttonImagelist.himl,3,ILD_NORMAL);
  88. end;
  89.  
  90.  
  91. iaBottom:
  92. begin
  93. ImageList_Draw(pbuttonImagelist.himl,(DrawRect.Height - IH) - 3,ILD_NORMAL);
  94. end;
  95.  
  96. end;
  97.  
  98.  
  99. end;
  100.  
  101. if (GetWindowLong(Handle,GWL_STYLE) and BS_COMMANDLINK) = BS_COMMANDLINK then
  102. begin
  103. if pbuttonImagelist.himl = 0 then
  104. Inc(DrawRect.Left,35);
  105.  
  106. Inc(DrawRect.Top,15);
  107. Inc(DrawRect.Left,5);
  108. Canvas.Font := TCustomButtonH(Control).Font;
  109. Canvas.Font.Style := [];
  110. Canvas.Font.Size := 12;
  111. LTextFormatFlags := TTextFormatFlags(DT_LEFT);
  112. if StyleServices.GetElementColor(LDetails,ecTextColor,ThemeTextColor) then
  113. Canvas.Font.Color := ThemeTextColor;
  114. StyleServices.DrawText(Canvas.Handle,BCaption,DrawRect,LTextFormatFlags,Canvas.Font.Color);
  115. SetLength(Buffer,Button_GetNoteLength(Handle) + 1);
  116. if Length(Buffer) <> 0 then
  117. begin
  118. BufferLength := Length(Buffer);
  119. if Button_GetNote(Handle,PChar(Buffer),BufferLength) then
  120. begin
  121. LTextFormatFlags := TTextFormatFlags(DT_LEFT or DT_WORDBREAK);
  122. Inc(DrawRect.Top,Canvas.TextHeight('Wq') + 2);
  123. Canvas.Font.Size := 8;
  124. StyleServices.DrawText(Canvas.Handle,Buffer,Canvas.Font.Color);
  125. end;
  126. end;
  127.  
  128. if pbuttonImagelist.himl = 0 then
  129. begin
  130. if Pressed then
  131. LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyPHPressed)
  132. else if MouseInControl then
  133. LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphHot)
  134. else if Control.Enabled then
  135. LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphNormal)
  136. else
  137. LDetails := StyleServices.GetElementDetails(tbCommandLinkGlyphDisabled);
  138. DrawRect.Right := 35;
  139. DrawRect.Left := 3;
  140. DrawRect.Top := 10;
  141. DrawRect.Bottom := DrawRect.Top + 32;
  142. StyleServices.DrawElement(Canvas.Handle,DrawRect);
  143. end;
  144.  
  145. end
  146. else
  147. if (GetWindowLong(Handle,GWL_STYLE) and BS_SPLITBUTTON) = BS_SPLITBUTTON then
  148. begin
  149. Dec(DrawRect.Right,15);
  150. DrawControlText(Canvas,Text,DT_VCENTER or DT_CENTER);
  151. if DropDown then
  152. begin
  153. LDetails := StyleServices.GetElementDetails(tbPushButtonPressed);
  154. SaveIndex := SaveDC(Canvas.Handle);
  155. try
  156. IntersectClipRect(Canvas.Handle,Control.Width - 15,Control.Width,Control.Height);
  157. DrawRect := Rect(Control.Width - 30,Control.Height);
  158. StyleServices.DrawElement(Canvas.Handle,DrawRect);
  159. finally
  160. RestoreDC(Canvas.Handle,SaveIndex);
  161. end;
  162. end;
  163.  
  164. with Canvas do
  165. begin
  166. Pen.Color := StyleServices.GetSystemColor(clBtnShadow);
  167. MoveTo(Control.Width - 15,3);
  168. LineTo(Control.Width - 15,Control.Height - 3);
  169. if Control.Enabled then
  170. Pen.Color := StyleServices.GetSystemColor(clBtnHighLight)
  171. else
  172. Pen.Color := Font.Color;
  173. MoveTo(Control.Width - 14,3);
  174. LineTo(Control.Width - 14,Control.Height - 3);
  175. Pen.Color := Font.Color;
  176. X := Control.Width - 8;
  177. Y := Control.Height div 2 + 1;
  178. for i := 3 downto 0 do
  179. begin
  180. MoveTo(X - I,Y - I);
  181. LineTo(X + I + 1,Y - I);
  182. end;
  183. end;
  184.  
  185. end
  186. else
  187. begin
  188. //finally the text is aligned and drawn depending of the value of the ImageAlignment property
  189. case TCustomButton(Control).ImageAlignment of
  190. iaLeft,iaRight,iaCenter : DrawControlText(Canvas,DT_VCENTER or DT_CENTER);
  191. iaBottom : DrawControlText(Canvas,DT_TOP or DT_CENTER);
  192. iaTop : DrawControlText(Canvas,DT_BOTTOM or DT_CENTER);
  193. end;
  194. end;
  195. end;
  196. end;
  197.  
  198. { TButtonStyleHookHelper }
  199.  
  200. function TButtonStyleHookHelper.DropDown: Boolean;
  201. begin
  202. Result:=Self.FDropDown;
  203. end;
  204.  
  205. function TButtonStyleHookHelper.Pressed: Boolean;
  206. begin
  207. Result:=Self.FPressed;
  208. end;
  209.  
  210.  
  211. initialization
  212. TStyleManager.Engine.RegisterStyleHook(TButton,TButtonStyleHookFix);

猜你在找的Delphi相关文章