Delphi XE2:在组件上禁用VCL样式

4

我试图按照示例禁用表单上控件的颜色。

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

但是,当我尝试注册或注销第三方控件(infopower TwwDBComboDlg)或标准VCL TEdit时,会出现异常。有人遇到过这个问题或有什么建议吗?


在上述调用中发生了访问冲突。这是在我尝试禁用组件的初始化部分发生的。 - mike
尝试使用TStyleManager.Engine.RegisterStyleHook(ClrMeans.TwwDBComboDLG, TStyleHook)注册样式钩子。 - RRUZ
我尝试了同样的方法,结果也一样。我的TwwDBComboDLG声明如下:TwwDBComboDLG = class( wwDotDot.TwwDBComboDLG); 我应该使用Infopower声明还是将其默认回标准的Delphi类型,比如TCustomEdit? - mike
相关:https://dev59.com/G2oy5IYBdhLWcg3wYM6B - Warren P
@mike,您是要在全局删除此控件的VCL样式,还是仅在一个窗体中删除? - RRUZ
嗨,迈克,我成功地让TEdit和你的TwwDBComboDLG不再使用主题了... - Warren P
1个回答

3
这里的链接解释了您需要知道的内容。
基本上,您需要放置一个“null hook”,这是您已经知道的,或者您需要放置一个“VCL颜色”钩子,这是您缺失的一半。另一半是您的空指针问题。
为了使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为nil,您应该检查并在不调用所调用的函数的情况下返回该代码。以下是您需要打开主题的位置,以防您错过了它:

enter image description here

有趣的副产品:获取VCL Styles utils库。以下是使用它更改内容颜色的示例:

 TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleColor(scEdit, clWindow);
 TCustomStyleExt(TStyleManager.ActiveStyle).SetStyleFontColor(sfEditBoxTextNormal
                   ,clWindowText);

您可以创建样式,并将这些样式应用于特定控件,甚至可以扩展主题引擎,可能可以使用VCL Styles Utils工具来获得所需的结果,但这并不容易。

这是一个数据库编辑器,但它包含子控件,甚至有自己的下拉WS_POPUP窗口,里面还有更多的控件。 - Warren P
我尝试只使用TEdit控件,但出现了相同的问题。当我在调试器中查看时,发现TStyleManager.engine为nil。这是否正确?我认为这可能是我的问题所在。你有任何修正的想法吗? - mike
如果您没有进入项目并启用VCL样式,则它将始终为nil。转到项目设置并打开样式。 - Warren P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接