Delphi XE2: Disabling vcl Style on a component

谁都会走 提交于 2019-12-06 05:13:38

问题


I am trying to follow the example about to disable the color on a control on my form.

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

But I am getting an exception when either registering or unregistering either a the 3rd party control (infopower TwwDBComboDlg) or a standard VCL TEdit. Anybody had any issues with this or any suggestions


回答1:


The link here explains what you need to know.

Basically, you need to either put a "null hook" in, which is what you already knew, or you need to put a "VCL colors" hook in, which is half of what you are missing. The other half is your nil pointer problem.

To make TEdit derivatives (like yours) look like VCL standard colors the code you need to make it work with your control is this:

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);

Your problem with NIL is that if you don't have VCL themes turned on, then Engine is nil, and you should check and just return from that code without calling that function you're calling. Here's where you turn on the themes, in case you missed it:

Interesting side stuff: Get the VCL Styles utils library. Here's an example of using it to change colors of stuff:

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

You can create styles, and apply those styles to particular controls, and even expand the theming engine, it might be possible to use the VCL Styles Utils tool to get your desired result, but it will not be trivial.



来源:https://stackoverflow.com/questions/9130945/delphi-xe2-disabling-vcl-style-on-a-component

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!