DevExpress VCL Skin Adapter

        DevExpress Skin 正常情况下只能对他自己的组件和系统组件添加皮肤效果,而第三方组件无法使用。如果程序里面使用了非DevExpress的组件,切换皮肤时会导致非DevExpress 组件与DevExpress组件界面不搭配。DevExpress VCL Skin Adapter 就是来解决这个问题的。

cxLookAndFeels 单元有一个RootLookAndFeel全局变量,替换此全局变量的OnChanged方法为自定义的方法,然后在自定义的OnChanged中通知其他组件程序皮肤已经切换,其他组件做对应的皮肤调整。

uDxSkinAdapter.pas 单元源码

unit uDxSkinAdapter;

interface
uses System.SysUtils,System.Classes,Winapi.Messages,Winapi.Windows,System.SyncObjs,cxLookAndFeels,dxSkinsForm;
type
  IcxLookAndFeelHandler = interface    //第三方组件继承此接口
    ['{8CB3F0DB-3B89-4D03-ADEA-A11735736205}']
    procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues); //当皮肤切换时调用此函数,组件做对应皮肤调整
  end;

  TDxSkinAdapter=class(TObject)
  private
    FLock:TCriticalSection;
    FList:TList;
    FSavLookAndFeelChanged: TcxLookAndFeelChangedEvent;
    procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
    procedure SetLookAndFeelChangedHandler(Attach: Boolean);
  public
    constructor Create();
    destructor Destroy; override;
    procedure AddHandler(Component: TComponent);//添加需要通知皮肤切换事件的组件
    procedure RemoveHandler(Component: TComponent);//删除组件的皮肤切换通知
  end;



var
  DxSkinAdapter:TDxSkinAdapter;//全局变量
implementation

procedure TDxSkinAdapter.SetLookAndFeelChangedHandler(Attach: Boolean);
var
  CrtLookAndFeel: TcxLookAndFeel;
  IsAttached: Boolean;
begin
  CrtLookAndFeel := RootLookAndFeel();
  if CrtLookAndFeel <> nil then
  begin
    IsAttached :=
      (TMethod(CrtLookAndFeel.OnChanged).Data = Self) and
      (TMethod(CrtLookAndFeel.OnChanged).Code = @TDxSkinAdapter.LookAndFeelChanged);
    if Attach and not IsAttached then
    begin
      FSavLookAndFeelChanged := CrtLookAndFeel.OnChanged;
      CrtLookAndFeel.OnChanged := LookAndFeelChanged;
    end
    else if not Attach and IsAttached then
    begin
      CrtLookAndFeel.OnChanged := FSavLookAndFeelChanged;
      FSavLookAndFeelChanged := nil;
    end;
  end;

end;
procedure TDxSkinAdapter.LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
var
  i:Integer;
  Component: TComponent;
  AIntf:IcxLookAndFeelHandler;
begin
  FLock.Enter;
  try
    for i := 0 to FList.Count-1 do
    begin
      Component:=TComponent(FList[i]);
      if (Component<>nil) and (Component.GetInterface(IcxLookAndFeelHandler,AIntf)) then
      begin
        AIntf.LookAndFeelChanged(Sender,AChangedValues);
      end;
    end;
  finally
    FLock.Leave;
  end;
end;
procedure TDxSkinAdapter.AddHandler(Component: TComponent);
var
  AIntf:IcxLookAndFeelHandler;
begin
  FLock.Enter;
  try
    if (Component<>nil) and (Component.GetInterface(IcxLookAndFeelHandler,AIntf)) then FList.Add(Component);
  finally
    FLock.Leave;
  end;
end;
procedure TDxSkinAdapter.RemoveHandler(Component: TComponent);
var
  Index:Integer;
begin
  FLock.Enter;
  try
    Index:=FList.IndexOf(Component);
    if Index>=0 then FList.Delete(Index);
  finally
    FLock.Leave;
  end;
end;

constructor TDxSkinAdapter.Create();
begin
  FList:=TList.Create;
  FLock:=TCriticalSection.Create;
  SetLookAndFeelChangedHandler(True);
end;
destructor TDxSkinAdapter.Destroy;
begin
  SetLookAndFeelChangedHandler(False);
  FreeAndNil(FLock);
  FreeAndNil(FList);
end;


initialization
  DxSkinAdapter := TDxSkinAdapter.Create();//全局初始化

finalization
  FreeAndNil(DxSkinAdapter);

end.
使用方法

unit uChart;

interface
uses System.Classes,Vcl.Controls,VCLTee.Chart,uDxSkinAdapter,cxLookAndFeels;
type
  TAdvChart = class(TChart,IcxLookAndFeelHandler) //第三方组件继承接口
  private
    procedure ChangeLookAndFeel();
  public
    procedure LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);//接口函数,皮肤切换通知
    constructor Create(AOwner: TComponent);override;
    destructor Destroy;override;
  end;
  
implementation

procedure TAdvChart.ChangeLookAndFeel();
begin
  Gradient.StartColor := RootLookAndFeel.Painter.DefaultContentColor;
  Gradient.EndColor := RootLookAndFeel.Painter.DefaultContentColor;
end;

procedure TAdvChart.LookAndFeelChanged(Sender: TcxLookAndFeel; AChangedValues: TcxLookAndFeelValues);
begin
  ChangeLookAndFeel;
end;
constructor TAdvChart.Create(AOwner: TComponent);
begin
  inherited;
  Gradient.Visible:=True;
  View3DWalls:=False;
  View3D:=False;
  BevelOuter:=bvNone;
  ChangeLookAndFeel;
  DxSkinAdapter.AddHandler(Self);//此组件需要获取皮肤切换事件
end;
destructor TAdvChart.Destroy;
begin
  DxSkinAdapter.RemoveHandler(Self);//删除皮肤切换通知事件
  inherited;
end;


效果:

DevExpress VCL Skin Adapter_第1张图片

DevExpress VCL Skin Adapter_第2张图片

DevExpress VCL Skin Adapter_第3张图片


顺便贴上 TMS Component Skin 皮肤切换在第三方组件上的应用,详细介绍见http://www.tmssoftware.com/site/atbdev3.asp

unit AdvChart;

interface
uses
  Classes,TeeProcs, TeEngine, Chart,DBChart, Series, AdvStyleIF,Controls,Graphics;
type

  TAdvChart = class(TChart, ITMSStyle)
  public
   procedure SetComponentStyle(AStyle: TTMSStyle);
  end;
  TDBAdvChart = class(TDBChart, ITMSStyle)
  public
   procedure SetComponentStyle(AStyle: TTMSStyle);
  end;
implementation

procedure TAdvChart.SetComponentStyle(AStyle: TTMSStyle);
begin
  Gradient.Visible:=True;
  View3DWalls:=False;
  View3D:=False;
  BevelOuter:=bvNone;
  case AStyle of
    tsOffice2003Blue:
      begin
        Gradient.StartColor := $00FDEADA;
        Gradient.EndColor := $00E4AE88;
      end;
    tsOffice2003Silver:
      begin
        Gradient.StartColor := $00F7F3F3;
        Gradient.EndColor := $00E6D8D8;
      end;
    tsOffice2003Olive:
      begin
        Gradient.StartColor := $00CFF0EA;
        Gradient.EndColor := $008CC0B1;
      end;
    tsOffice2003Classic:
      begin
        Gradient.StartColor := clWhite;
        Gradient.EndColor := $00C9D1D5;
      end;
    tsOffice2007Luna:
      begin
        Gradient.StartColor := $FAF1E9;
        Gradient.EndColor := $EDD8C7;

      end;
    tsOffice2007Obsidian:
      begin
        Gradient.StartColor := $CFC6C1;
        Gradient.EndColor := $C5BBB4;
      end;
    tsWindowsXP:
      begin
        Gradient.StartColor := clBtnFace;
        Gradient.EndColor := clBtnFace;
      end;
    tsWhidbey:
      begin
        Gradient.StartColor := clWhite;
        Gradient.EndColor := $00D9E9EC;
      end;
    tsCustom: ;
    tsOffice2007Silver:
      begin
        Gradient.StartColor := $F6F1EE;
        Gradient.EndColor := $E7DCD5;

      end;
    tsWindowsVista:
      begin
        Gradient.StartColor := $FDF8F1;
        Gradient.EndColor := $FCEFD5;

      end;
    tsWindows7:
      begin
        Gradient.StartColor := $FCEBDC;
        Gradient.EndColor := $FCDBC1;
      end;

    tsTerminal:
      begin
        Gradient.StartColor := clBtnFace;
        Gradient.EndColor := clBtnFace;
      end;
    tsOffice2010Blue:
      begin
        Gradient.StartColor := $FDF6EF;
        Gradient.EndColor := $F0DAC7;
      end;
    tsOffice2010Silver:
      begin
        Gradient.StartColor := $FFFFFF;
        Gradient.EndColor := $EDE5E0;
      end;
    tsOffice2010Black:
      begin
        Gradient.StartColor := $BFBFBF;
        Gradient.EndColor := $919191;
      end;
  end;
end;
procedure TDBAdvChart.SetComponentStyle(AStyle: TTMSStyle);
begin
  Gradient.Visible:=True;
  View3DWalls:=False;
  View3D:=False;
  BevelOuter:=bvNone;
  case AStyle of
    tsOffice2003Blue:
      begin
        Gradient.StartColor := $00FDEADA;
        Gradient.EndColor := $00E4AE88;
      end;
    tsOffice2003Silver:
      begin
        Gradient.StartColor := $00F7F3F3;
        Gradient.EndColor := $00E6D8D8;
      end;
    tsOffice2003Olive:
      begin
        Gradient.StartColor := $00CFF0EA;
        Gradient.EndColor := $008CC0B1;
      end;
    tsOffice2003Classic:
      begin
        Gradient.StartColor := clWhite;
        Gradient.EndColor := $00C9D1D5;
      end;
    tsOffice2007Luna:
      begin
        Gradient.StartColor := $FAF1E9;
        Gradient.EndColor := $EDD8C7;

      end;
    tsOffice2007Obsidian:
      begin
        Gradient.StartColor := $CFC6C1;
        Gradient.EndColor := $C5BBB4;
      end;
    tsWindowsXP:
      begin
        Gradient.StartColor := clBtnFace;
        Gradient.EndColor := clBtnFace;
      end;
    tsWhidbey:
      begin
        Gradient.StartColor := clWhite;
        Gradient.EndColor := $00D9E9EC;
      end;
    tsCustom: ;
    tsOffice2007Silver:
      begin
        Gradient.StartColor := $F6F1EE;
        Gradient.EndColor := $E7DCD5;

      end;
    tsWindowsVista:
      begin
        Gradient.StartColor := $FDF8F1;
        Gradient.EndColor := $FCEFD5;

      end;
    tsWindows7:
      begin
        Gradient.StartColor := $FCEBDC;
        Gradient.EndColor := $FCDBC1;
      end;

    tsTerminal:
      begin
        Gradient.StartColor := clBtnFace;
        Gradient.EndColor := clBtnFace;
      end;
    tsOffice2010Blue:
      begin
        Gradient.StartColor := $FDF6EF;
        Gradient.EndColor := $F0DAC7;
      end;
    tsOffice2010Silver:
      begin
        Gradient.StartColor := $FFFFFF;
        Gradient.EndColor := $EDE5E0;
      end;
    tsOffice2010Black:
      begin
        Gradient.StartColor := $BFBFBF;
        Gradient.EndColor := $919191;
      end;
  end;
end;
end.




你可能感兴趣的:(Delphi)