4

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

Warren P
  • 65,725
  • 40
  • 181
  • 316
mike
  • 49
  • 1
  • 3
  • Its an access violation on the call above. its in the initialization portion of the form I am trying to disable the component. – mike Feb 03 '12 at 17:07
  • Try TStyleManager.Engine.RegisterStyleHook(ClrMeans.TwwDBComboDLG, TStyleHook); – RRUZ Feb 03 '12 at 17:15
  • I tried that with same results. My declaration for the TwwDBComboDLG is this TwwDBComboDLG = class( wwDotDot.TwwDBComboDLG); should I be using the infopower declaration or should I default it back to a standard delphi type, say TCustomEdit. – mike Feb 03 '12 at 19:02
  • Related: http://stackoverflow.com/questions/8598728/how-to-disable-vcl-styles-in-delphi – Warren P Feb 03 '12 at 19:06
  • @mike Do you want remove the vcl style globally for this control or just in a form? – RRUZ Feb 03 '12 at 19:10
  • Hey mike, I managed to get TEdit and your TwwDBComboDLG to not be themed.... – Warren P Feb 06 '12 at 20:38

1 Answers1

3

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:

enter image description here

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.

Warren P
  • 65,725
  • 40
  • 181
  • 316
  • It is a DB Edit, but it contains sub-controls, and even its own drop-down WS_POPUP window with even more controls inside. – Warren P Feb 03 '12 at 19:17
  • I tried it with just a TEdit control, and got the same issue. The TStyleManager.engine is nil when I looked at it in the debugger. does that sound correct. I'm thinking that might be my issue. Any idea on how to correct it. – mike Feb 03 '12 at 19:29
  • It will always be nil if you didn't go into your project and enable a VCL style. Go to the project settings and turn on the styles. – Warren P Feb 03 '12 at 20:16