我正在尝试按照有关禁用表单控件颜色的示例进行操作。

TStyleManager.Engine.RegisterStyleHook(ClrMeans.TwwDBComboDLG, TEditStyleHook);

但是在注册或取消注册第 3 方控件(infopower TwwDBComboDlg)或标准 VCL TEdit 时,我遇到了异常。任何人对此有任何问题或任何建议

最佳答案

这里的 link 解释了您需要知道的内容。

基本上,您需要放入一个“空钩子(Hook)”,这是您已经知道的,或者您需要放入一个“VCL 颜色”钩子(Hook),这是您缺少的一半。另一半是你的 nil 指针问题。

为了使 TEdit 衍生品(如您的)看起来像 VCL 标准颜色,您需要使其与您的控件一起使用的代码是这样的:

uses
  Winapi.Messages,
  Vcl.Controls,
  Vcl.StdCtrls,
  Vcl.Forms,
  Vcl.Themes,
  Vcl.Styles;

type

TEditStyleHookColor = class(TEditStyleHook)
  private
    procedure UpdateColors;
  protected
    procedure WndProc(var Message: TMessage); override;
    constructor Create(AControl: TWinControl); override;
  end;

implementation


type
 TWinControlH= class(TWinControl);


constructor TEditStyleHookColor.Create(AControl: TWinControl);
begin
  inherited;
  //call the UpdateColors method to use the custom colors
  UpdateColors;
end;

//Here you set the colors of the style hook
procedure TEditStyleHookColor.UpdateColors;
var
  LStyle: TCustomStyleServices;
begin
 if Control.Enabled then
 begin
  Brush.Color := TWinControlH(Control).Color; //use the Control color
  FontColor   := TWinControlH(Control).Font.Color;//use the Control font color
 end
 else
 begin
  //if the control is disabled use the colors of the style
  LStyle := StyleServices;
  Brush.Color := LStyle.GetStyleColor(scEditDisabled);
  FontColor := LStyle.GetStyleFontColor(sfEditBoxTextDisabled);
 end;
end;

//Handle the messages of the control
procedure TEditStyleHookColor.WndProc(var Message: TMessage);
begin
  case Message.Msg of
    CN_CTLCOLORMSGBOX..CN_CTLCOLORSTATIC:
      begin
        //Get the colors
        UpdateColors;
        SetTextColor(Message.WParam, ColorToRGB(FontColor));
        SetBkColor(Message.WParam, ColorToRGB(Brush.Color));
        Message.Result := LRESULT(Brush.Handle);
        Handled := True;
      end;
    CM_ENABLEDCHANGED:
      begin
        //Get the colors
        UpdateColors;
        Handled := False;
      end
  else
    inherited WndProc(Message);
  end;
end;

Procedure ApplyVCLColorsStyleHook(ControlClass :TClass);
begin
    if Assigned(TStyleManager.Engine) then
       TStyleManager.Engine.RegisterStyleHook(ControlClass, TEditStyleHookColor);
end;

initialization
     ApplyVCLColorsStyleHook(TwwDBComboDlg);

您对 NIL 的问题是,如果您没有打开 VCL 主题,那么 Engine 为零,您应该检查并从该代码返回而不调用您正在调用的那个函数。这是您打开主题的地方,以防您错过它:

有趣的东西:获取 the VCL Styles utils 库。这是一个使用它来改变东西颜色的例子:
 TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleColor(scEdit, clWindow);
 TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleFontColor(sfEditBoxTextNormal
                   ,clWindowText);

您可以创建样式,并将这些样式应用到特定控件,甚至扩展主题引擎,使用 VCL Styles Utils 工具可能会得到您想要的结果,但这并非易事。

关于Delphi XE2 : Disabling vcl Style on a component,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9130945/

10-12 05:33