Delphi XE2: отключение стиля vcl для компонента - PullRequest
4 голосов
/ 03 февраля 2012

Я пытаюсь следовать примеру об отключении цвета для элемента управления в моей форме.

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

Но яполучение исключения при регистрации или отмене регистрации либо стороннего элемента управления (infopower TwwDBComboDlg), либо стандартного VCL TEdit.У кого-нибудь были какие-либо проблемы с этим или любые предложения

1 Ответ

3 голосов
/ 03 февраля 2012

Здесь ссылка объясняет, что вам нужно знать.

По сути, вам нужно либо поставить «нулевой хук», что вы уже знали, либо вам нужновставьте крючок "VCL colors", что составляет половину того, что вам не хватает.Другая половина - ваша проблема с нулевым указателем.

Чтобы производные 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 использует библиотеку .Вот пример использования его для изменения цвета вещей:

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

Вы можете создавать стили, применять эти стили к конкретным элементам управления и даже расширять механизм создания тем, возможно, можно будет использовать стили VCLИспользует инструмент, чтобы получить желаемый результат, но он не будет тривиальным.

...