Delphi XE2: отключение стиля vcl для компонента

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

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

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


person mike    schedule 03.02.2012    source источник
comment
Это нарушение прав доступа при вызове выше. в части инициализации формы я пытаюсь отключить компонент.   -  person mike    schedule 03.02.2012
comment
Попробуйте TStyleManager.Engine.RegisterStyleHook(ClrMeans.TwwDBComboDLG, TStyleHook);   -  person RRUZ    schedule 03.02.2012
comment
Я пробовал это с теми же результатами. Мое объявление для TwwDBComboDLG таково: TwwDBComboDLG = class(wwDotDot.TwwDBComboDLG); должен ли я использовать объявление infopower или я должен по умолчанию вернуться к стандартному типу delphi, скажем, TCustomEdit.   -  person mike    schedule 03.02.2012
comment
Связанный: stackoverflow.com/questions /8598728/   -  person Warren P    schedule 03.02.2012
comment
@mike Вы хотите удалить стиль vcl глобально для этого элемента управления или только в форме?   -  person RRUZ    schedule 03.02.2012
comment
Привет, Майк, мне удалось сделать так, чтобы TEdit и твой TwwDBComboDLG не были тематическими....   -  person Warren P    schedule 07.02.2012


Ответы (1)


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

По сути, вам нужно либо добавить «нулевой хук», о чем вы уже знали, либо вам нужно добавить хук «цвета 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 равен нулю, и вы должны проверить и просто вернуться из этого кода, не вызывая ту функцию, которую вы вызываете. Вот где вы включаете темы, если вы пропустили это:

введите здесь описание изображения

Интересный дополнительный материал: скачайте библиотеку утилит VCL Styles. Вот пример его использования для изменения цвета вещей:

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

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

person Warren P    schedule 03.02.2012
comment
Это DB Edit, но он содержит вложенные элементы управления и даже собственное раскрывающееся окно WS_POPUP с еще большим количеством элементов управления внутри. - person Warren P; 03.02.2012
comment
Я попробовал это только с элементом управления TEdit и получил ту же проблему. TStyleManager.engine равен нулю, когда я смотрел на него в отладчике. правильно ли это звучит. Я думаю, что это может быть моя проблема. Любая идея о том, как это исправить. - person mike; 03.02.2012
comment
Он всегда будет нулевым, если вы не вошли в свой проект и не включили стиль VCL. Заходим в настройки проекта и включаем стили. - person Warren P; 04.02.2012