{*******************************************************************} { } { Developer Express Visual Component Library } { ExpressBars components } { } { Copyright (c) 1998-2008 Developer Express Inc. } { ALL RIGHTS RESERVED } { } { The entire contents of this file is protected by U.S. and } { International Copyright Laws. Unauthorized reproduction, } { reverse-engineering, and distribution of all or any portion of } { the code contained in this file is strictly prohibited and may } { result in severe civil and criminal penalties and will be } { prosecuted to the maximum extent possible under the law. } { } { RESTRICTIONS } { } { THIS SOURCE CODE AND ALL RESULTING INTERMEDIATE FILES } { (DCU, OBJ, DLL, ETC.) ARE CONFIDENTIAL AND PROPRIETARY TRADE } { SECRETS OF DEVELOPER EXPRESS INC. THE REGISTERED DEVELOPER IS } { LICENSED TO DISTRIBUTE THE EXPRESSBARS AND ALL ACCOMPANYING VCL } { CONTROLS AS PART OF AN EXECUTABLE PROGRAM ONLY. } { } { THE SOURCE CODE CONTAINED WITHIN THIS FILE AND ALL RELATED } { FILES OR ANY PORTION OF ITS CONTENTS SHALL AT NO TIME BE } { COPIED, TRANSFERRED, SOLD, DISTRIBUTED, OR OTHERWISE MADE } { AVAILABLE TO OTHER INDIVIDUALS WITHOUT EXPRESS WRITTEN CONSENT } { AND PERMISSION FROM DEVELOPER EXPRESS INC. } { } { CONSULT THE END USER LICENSE AGREEMENT FOR INFORMATION ON } { ADDITIONAL RESTRICTIONS. } { } {*******************************************************************} unit dxBarSkin; {$I cxVer.inc} interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ImgList, ExtCtrls, cxGraphics, dxGDIPlusAPI; type TcxSkinRectType = (spt1x1, spt3x1, spt1x3, spt3x3); TdxCustomBarSkin = class; { TdxSkinnedRect } TdxSkin3x3Part = ( sp3x3TopLeft, sp3x3Top, sp3x3TopRight, sp3x3Left, sp3x3Center, sp3x3Right, sp3x3BottomLeft, sp3x3Bottom, sp3x3BottomRight ); { TdxSkinnedRect } TdxSkinnedRect = class private FAlphaValue: Byte; FCalculatedSize: TSize; FDrawPartSizes: array[TdxSkin3x3Part] of TSize; FFixedPartSize: TRect; FGPImage: GpBitmap; FGPCacheBitmap: GpBitmap; FID: Integer; FInterpolationMode: Integer; FLastSize: TSize; FMinSize: TSize; FName: string; FOpaque: Boolean; FOwner: TdxCustomBarSkin; FPartBounds: array[TdxSkin3x3Part] of TRect; FTextOffset: TRect; procedure CalculatePartBounds(const ARect: TRect); procedure CheckCachedImage; procedure CheckCalculate(AWidth, AHeight: Integer); procedure UpdateCacheImage; procedure UpdateSizes; protected procedure Calculate(AWidth, AHeight: Integer); virtual; procedure Clear; virtual; procedure DefaultDraw(DC: HDC; const R: TRect); virtual; procedure DoDraw(DC: HDC; const R: TRect); virtual; property CalculatedSize: TSize read FCalculatedSize; public constructor Create(AOpaque: Boolean = False); destructor Destroy; override; procedure Draw(DC: HDC; const R: TRect; AlphaValue: Byte = 255); function GetBitmap(const AWidth, AHeight: Integer; AUseAlphaChannel: Boolean = False): TBitmap; function GetTextBounds(const R: TRect): TRect; virtual; procedure LoadFromBitmap(ABitmap: GpBitmap; const ARect, AFixedPartSize: TRect); procedure LoadFromFile(const AFileName: string; const AFixedPartSize: TRect); overload; procedure LoadFromFile(const AFileName: string; const ARect, AFixedPartSize: TRect); overload; property AlphaValue: Byte read FAlphaValue write FAlphaValue default 255; property ID: Integer read FID write FID; property InterpolationMode: Integer read FInterpolationMode write FInterpolationMode default InterpolationModeDefault; property MinSize: TSize read FMinSize write FMinSize; property Name: string read FName write FName; property Opaque: Boolean read FOpaque write FOpaque; property Owner: TdxCustomBarSkin read FOwner; property TextOffset: TRect read FTextOffset write FTextOffset; end; { TdxCustomBarSkin } TdxCustomBarSkin = class(TList) private FName: string; function GetPart(Index: Integer): TdxSkinnedRect; protected function IsPersistent: Boolean; virtual; public constructor Create(const AName: string); procedure Clear; override; function Add(ASkinnedRect: TdxSkinnedRect): Integer; function AddPart1x1(ABitmap: GpBitmap; const R: TRect; AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; function AddPart1x3(ABitmap: GpBitmap; const R: TRect; ATop, ABottom, AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; function AddPart3x3(ABitmap: GpBitmap; const R, AFixedSize: TRect; AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; function PartByName(const AName: string): TdxSkinnedRect; function PartByID(const AID: Integer): TdxSkinnedRect; property Name: string read FName write FName; property Parts[Index: Integer]: TdxSkinnedRect read GetPart; default; end; { TcxSkinManager } TdxBarSkinManager = class(TPersistent) private FList: TList; function GetSkin(Index: Integer): TdxCustomBarSkin; function GetSkinCount: Integer; protected function CanDeleteSkin(ASkin: TdxCustomBarSkin): Boolean; procedure Changed; virtual; public constructor Create; destructor Destroy; override; function AddSkin(ASkin: TdxCustomBarSkin): Integer; function RemoveSkin(ASkin: TdxCustomBarSkin): Boolean; function SkinByName(const AName: string): TdxCustomBarSkin; property SkinCount: Integer read GetSkinCount; property Skins[Index: Integer]: TdxCustomBarSkin read GetSkin; default; end; function SkinManager: TdxBarSkinManager; function GetImageFromStream(AStream: TStream): GPImage; implementation uses {$IFDEF DELPHI6} Types, {$ENDIF} cxGeometry, dxOffice11, cxControls, dxBar, cxDWMApi, ActiveX; var FSkinManager: TdxBarSkinManager; function SkinManager: TdxBarSkinManager; begin if FSkinManager = nil then FSkinManager := TdxBarSkinManager.Create; Result := FSkinManager; end; function GetImageFromStream(AStream: TStream): GPImage; var Data: HGlobal; DataPtr: Pointer; AccessStream: IStream; begin Result := nil; if not CheckGdiPlus then Exit; Data := GlobalAlloc(GMEM_MOVEABLE + GMEM_DDESHARE, AStream.Size); try DataPtr := GlobalLock(Data); try AStream.Read(DataPtr^, AStream.Size); GdipCheck(CreateStreamOnHGlobal(Data, False, AccessStream) = s_OK); GdipCheck(GdipCreateBitmapFromStream(AccessStream, Result)); finally GlobalUnlock(Data); AccessStream := nil; end; finally GlobalFree(Data); end; end; function dxAlphaBlend(ADestDC: HDC; const ADestRect: TRect; ASrcDC: HDC; const ASrcRect: TRect; AlphaValue: Byte = 255): Boolean; begin if not IsWin95X then Result := SystemAlphaBlend(ADestDC, ASrcDC, ADestRect, ASrcRect, AlphaValue) else begin Result := True; cxAlphaBlend(ADestDC, ASrcDC, ADestRect, ASrcRect, False, AlphaValue); end; end; { TdxSkinnedRect } constructor TdxSkinnedRect.Create(AOpaque: Boolean = False); begin FAlphaValue := 255; FID := -1; FOpaque := AOpaque; FTextOffset := cxRect(8, 8, 8, 8); FInterpolationMode := InterpolationModeDefault; end; destructor TdxSkinnedRect.Destroy; begin if FGPImage <> nil then GdipDisposeImage(FGPImage); if FGPCacheBitmap <> nil then GdipDisposeImage(FGPCacheBitmap); inherited Destroy; end; procedure TdxSkinnedRect.Calculate(AWidth, AHeight: Integer); var W, H: Integer; begin if (FFixedPartSize.Left + FFixedPartSize.Right) >= AWidth then begin W := AWidth div 2; FDrawPartSizes[sp3x3TopLeft].cx := W; FDrawPartSizes[sp3x3BottomLeft].cx := W; FDrawPartSizes[sp3x3Left].cx := W; W := AWidth - W; FDrawPartSizes[sp3x3TopRight].cx := W; FDrawPartSizes[sp3x3BottomRight].cx := W; FDrawPartSizes[sp3x3Right].cx := W; //don't draw FDrawPartSizes[sp3x3Center].cx := 0; FDrawPartSizes[sp3x3Top].cx := 0; FDrawPartSizes[sp3x3Bottom].cx := 0; end else begin FDrawPartSizes[sp3x3TopLeft].cx := FFixedPartSize.Left; FDrawPartSizes[sp3x3Left].cx := FFixedPartSize.Left; FDrawPartSizes[sp3x3BottomLeft].cx := FFixedPartSize.Left; FDrawPartSizes[sp3x3TopRight].cx := FFixedPartSize.Right; FDrawPartSizes[sp3x3Right].cx := FFixedPartSize.Right; FDrawPartSizes[sp3x3BottomRight].cx := FFixedPartSize.Right; FDrawPartSizes[sp3x3Center].cx := AWidth - (FFixedPartSize.Right + FFixedPartSize.Left); FDrawPartSizes[sp3x3Top].cx := FDrawPartSizes[sp3x3Center].cx; FDrawPartSizes[sp3x3Bottom].cx := FDrawPartSizes[sp3x3Center].cx; end; if (FFixedPartSize.Top + FFixedPartSize.Bottom) >= AHeight then begin H := AHeight div 2; FDrawPartSizes[sp3x3TopLeft].cy := H; FDrawPartSizes[sp3x3TopRight].cy := H; FDrawPartSizes[sp3x3Top].cy := H; H := AHeight - H; FDrawPartSizes[sp3x3BottomLeft].cy := H; FDrawPartSizes[sp3x3BottomRight].cy := H; FDrawPartSizes[sp3x3Bottom].cy := H; //don't draw FDrawPartSizes[sp3x3Center].cy := 0; FDrawPartSizes[sp3x3Left].cy := 0; FDrawPartSizes[sp3x3Right].cy := 0; end else begin FDrawPartSizes[sp3x3TopLeft].cy := FFixedPartSize.Top; FDrawPartSizes[sp3x3Top].cy := FFixedPartSize.Top; FDrawPartSizes[sp3x3TopRight].cy := FFixedPartSize.Top; FDrawPartSizes[sp3x3BottomLeft].cy := FFixedPartSize.Bottom; FDrawPartSizes[sp3x3Bottom].cy := FFixedPartSize.Bottom; FDrawPartSizes[sp3x3BottomRight].cy := FFixedPartSize.Bottom; FDrawPartSizes[sp3x3Center].cy := AHeight - (FFixedPartSize.Bottom + FFixedPartSize.Top); FDrawPartSizes[sp3x3Left].cy := FDrawPartSizes[sp3x3Center].cy; FDrawPartSizes[sp3x3Right].cy := FDrawPartSizes[sp3x3Center].cy; end; end; procedure TdxSkinnedRect.Clear; begin FCalculatedSize := cxNullSize; end; procedure TdxSkinnedRect.DefaultDraw(DC: HDC; const R: TRect); begin FillRectByColor(DC, R, clBtnFace); end; procedure TdxSkinnedRect.DoDraw(DC: HDC; const R: TRect); var H, OldBitmap: HBITMAP; BDC: HDC; begin CheckCachedImage; GdipCreateHBITMAPFromBitmap(FGPCacheBitmap, H, 0); BDC := CreateCompatibleDC(DC); OldBitmap := SelectObject(BDC, H); if not FOpaque and not dxAlphaBlend(DC, R, BDC, cxRect(0, 0, CalculatedSize.cx, CalculatedSize.cy), AlphaValue) then cxBitBlt(DC, BDC, R, cxPoint(0, 0), srccopy); SelectObject(BDC, OldBitmap); DeleteDC(BDC); DeleteObject(H); end; procedure TdxSkinnedRect.Draw(DC: HDC; const R: TRect; AlphaValue: Byte = 255); begin FAlphaValue := AlphaValue; if (R.Right - R.Left <= 0) or (R.Bottom - R.Top <= 0) then Exit; CheckCalculate(R.Right - R.Left, R.Bottom - R.Top); if RectVisible(DC, R) then DoDraw(DC, R) end; function TdxSkinnedRect.GetBitmap(const AWidth, AHeight: Integer; AUseAlphaChannel: Boolean = False): TBitmap; begin Result := TcxBitmap.CreateSize(AWidth, AHeight);; if AUseAlphaChannel then Result.PixelFormat := pf32bit; Draw(Result.Canvas.Handle, cxRect(0, 0, AWidth, AHeight)); if AUseAlphaChannel then TcxBitmap(Result).RecoverAlphaChannel(clFuchsia); end; function TdxSkinnedRect.GetTextBounds(const R: TRect): TRect; begin Result := R; Inc(Result.Left, FTextOffset.Left); Inc(Result.Top, FTextOffset.Top); Dec(Result.Right, FTextOffset.Right); Dec(Result.Bottom, FTextOffset.Bottom); end; procedure TdxSkinnedRect.LoadFromBitmap(ABitmap: GpBitmap; const ARect, AFixedPartSize: TRect); var G: GpGraphics; begin Clear; GdipCheck(GdipCreateBitmapFromScan0(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, 0, PixelFormat32bppPARGB, nil, FGPImage)); GdipCheck(GdipGetImageGraphicsContext(FGPImage, G)); GdipCheck(GdipSetInterpolationMode(G, InterpolationModeNearestNeighbor)); GdipCheck(GdipSetCompositingMode(G, CompositingModeSourceCopy)); GdipCheck(GdipDrawImageRectRectI(G, ABitmap, 0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, ARect.Left, ARect.Top, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, UnitPixel, nil, nil, nil)); GdipCheck(GdipDeleteGraphics(G)); FFixedPartSize := AFixedPartSize; CalculatePartBounds(ARect); UpdateSizes; end; procedure TdxSkinnedRect.LoadFromFile(const AFileName: string; const AFixedPartSize: TRect); var ARect: TRect; begin Clear; FFixedPartSize := AFixedPartSize; ARect.Left := 0; ARect.Top := 0; GdipCheck(GdipLoadImageFromFile(PWideChar(WideString(AFileName)), FGPImage)); GdipCheck(GdipGetImageWidth(FGPImage, ARect.Right)); GdipCheck(GdipGetImageHeight(FGPImage, ARect.Bottom)); CalculatePartBounds(ARect); UpdateSizes; end; procedure TdxSkinnedRect.LoadFromFile(const AFileName: string; const ARect, AFixedPartSize: TRect); var B: GpBitmap; G: GpGraphics; begin Clear; FFixedPartSize := AFixedPartSize; GdipCheck(GdipLoadImageFromFile(PWideChar(WideString(AFileName)), B)); GdipCheck(GdipCreateBitmapFromScan0(ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, 0, PixelFormat32bppPARGB, nil, FGPImage)); GdipCheck(GdipGetImageGraphicsContext(FGPImage, G)); GdipCheck(GdipDrawImageRectRectI(G, B, 0, 0, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, ARect.Left, ARect.Top, ARect.Right - ARect.Left, ARect.Bottom - ARect.Top, UnitPixel, nil, nil, nil)); GdipCheck(GdipDeleteGraphics(G)); GdipCheck(GdipDisposeImage(B)); CalculatePartBounds(ARect); UpdateSizes; end; procedure TdxSkinnedRect.CalculatePartBounds(const ARect: TRect); var I: TdxSkin3x3Part; R: TRect; begin for I := sp3x3TopLeft to sp3x3BottomRight do begin case I of sp3x3TopLeft: R := cxRectBounds(ARect.Left, ARect.Top, FFixedPartSize.Left, FFixedPartSize.Top); sp3x3Top: R := cxRect(ARect.Left + FFixedPartSize.Left, ARect.Top, ARect.Right - FFixedPartSize.Right, ARect.Top + FFixedPartSize.Top); sp3x3TopRight: R := cxRect(ARect.Right - FFixedPartSize.Right, ARect.Top, ARect.Right, ARect.Top + FFixedPartSize.Top); sp3x3Left: R := cxRect(ARect.Left, ARect.Top + FFixedPartSize.Top, ARect.Left + FFixedPartSize.Left, ARect.Bottom - FFixedPartSize.Bottom); sp3x3Center: R := cxRect(ARect.Left + FFixedPartSize.Left, ARect.Top + FFixedPartSize.Top, ARect.Right - FFixedPartSize.Right, ARect.Bottom - FFixedPartSize.Bottom); sp3x3Right: R := cxRect(ARect.Right - FFixedPartSize.Right, ARect.Top + FFixedPartSize.Top, ARect.Right, ARect.Bottom - FFixedPartSize.Bottom); sp3x3BottomLeft: R := cxRect(ARect.Left, ARect.Bottom - FFixedPartSize.Bottom, ARect.Left + FFixedPartSize.Left, ARect.Bottom); sp3x3Bottom: R := cxRect(ARect.Left + FFixedPartSize.Left, ARect.Bottom - FFixedPartSize.Bottom, ARect.Right - FFixedPartSize.Right, ARect.Bottom); else R := cxRect(ARect.Right - FFixedPartSize.Right, ARect.Bottom - FFixedPartSize.Bottom, ARect.Right, ARect.Bottom); end; FPartBounds[I] := cxRectBounds(R.Left - ARect.Left, R.Top - ARect.Top, R.Right - R.Left, R.Bottom - R.Top); end; end; procedure TdxSkinnedRect.CheckCachedImage; begin if (FLastSize.cx = CalculatedSize.cx) and (FLastSize.cy = CalculatedSize.cy) then Exit; FLastSize := CalculatedSize; if FGPCacheBitmap <> nil then GdipDisposeImage(FGPCacheBitmap); GdipCreateBitmapFromScan0(CalculatedSize.cx, CalculatedSize.cy, 0, PixelFormat32bppPARGB, nil, FGPCacheBitmap); UpdateCacheImage; end; procedure TdxSkinnedRect.CheckCalculate(AWidth, AHeight: Integer); begin if (AWidth <> CalculatedSize.cx) or (AHeight <> CalculatedSize.cy) then begin Calculate(AWidth, AHeight); FCalculatedSize.cx := AWidth; FCalculatedSize.cy := AHeight; end; end; procedure TdxSkinnedRect.UpdateCacheImage; var X, Y: Integer; G: GpGraphics; procedure StretchDraw(X, Y, W, H: Integer; const ASrcRect: TRect); var ASrcWidth, ASrcHeight: Integer; begin ASrcWidth := ASrcRect.Right - ASrcRect.Left; ASrcHeight := ASrcRect.Bottom - ASrcRect.Top; if (ASrcWidth > 1) and (W > ASrcWidth) then Dec(ASrcWidth); if (ASrcHeight > 1) and (H > ASrcHeight) then Dec(ASrcHeight); GdipDrawImageRectRectI(G, FGPImage, X, Y, W, H, ASrcRect.Left, ASrcRect.Top, ASrcWidth, ASrcHeight, UnitPixel, nil, nil, nil); end; procedure DrawPart(var X: Integer; Y: Integer; APart: TdxSkin3x3Part); var W, H: Integer; begin W := FDrawPartSizes[APart].cx; H := FDrawPartSizes[APart].cy; if (W > 0) and (H > 0) then StretchDraw(X, Y, W, H, FPartBounds[APart]); Inc(X, W); end; begin GdipGetImageGraphicsContext(FGPCacheBitmap, G); GdipSetInterpolationMode(G, FInterpolationMode); GdipSetCompositingMode(G, CompositingModeSourceCopy); X := 0; Y := 0; DrawPart(X, Y, sp3x3TopLeft); DrawPart(X, Y, sp3x3Top); DrawPart(X, Y, sp3x3TopRight); X := 0; Inc(Y, FDrawPartSizes[sp3x3TopLeft].cy); DrawPart(X, Y, sp3x3Left); DrawPart(X, Y, sp3x3Center); DrawPart(X, Y, sp3x3Right); X := 0; Inc(Y, FDrawPartSizes[sp3x3Left].cy); DrawPart(X, Y, sp3x3BottomLeft); DrawPart(X, Y, sp3x3Bottom); DrawPart(X, Y, sp3x3BottomRight); GdipDeleteGraphics(G); end; procedure TdxSkinnedRect.UpdateSizes; begin FTextOffset := FFixedPartSize; FMinSize.cx := FTextOffset.Left + FTextOffset.Right; FMinSize.cy := FTextOffset.Top + FTextOffset.Bottom; end; { TdxCustomBarSkin } constructor TdxCustomBarSkin.Create(const AName: string); begin FName := AName; end; function TdxCustomBarSkin.Add(ASkinnedRect: TdxSkinnedRect): Integer; var I: Integer; // j: TdxSkin3x3Part; // R: TRect; begin Result := -1; if ASkinnedRect = nil then Exit; for I := 0 to Count - 1 do with Parts[I] do if (ASkinnedRect.ID <> -1) and (ASkinnedRect.ID = ID) then raise Exception.CreateFmt('ERROR: Duplicate part''s ID = %d', [ASkinnedRect.ID]) else if (ASkinnedRect.Name <> '') and (AnsiSameText(ASkinnedRect.Name, Name)) then raise Exception.CreateFmt('ERROR: Duplicate part''s name = "%s"', [ASkinnedRect.Name]); Result := inherited Add(ASkinnedRect); // for j := sp3x3TopLeft to sp3x3BottomRight do // with ASkinnedRect.FPartBounds[j] do // begin // if (Bottom - Top = 1) or (Right - Left = 1) then // raise Exception.CreateFmt('ERROR: Duplicate part''s ID = %d', [ASkinnedRect.ID]) // end; end; function TdxCustomBarSkin.AddPart1x1(ABitmap: GpBitmap; const R: TRect; AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; var P: TdxSkinnedRect; begin P := TdxSkinnedRect.Create; P.LoadFromBitmap(ABitmap, R, cxNullRect); P.ID := AID; P.Name := AName; P.InterpolationMode := AInterpolationMode; Result := Add(P); end; function TdxCustomBarSkin.AddPart1x3(ABitmap: GpBitmap; const R: TRect; ATop, ABottom, AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; var P: TdxSkinnedRect; begin P := TdxSkinnedRect.Create; P.LoadFromBitmap(ABitmap, R, cxRect(0, ATop, 0, ABottom)); P.ID := AID; P.Name := AName; P.InterpolationMode := AInterpolationMode; Result := Add(P); end; function TdxCustomBarSkin.AddPart3x3(ABitmap: GpBitmap; const R, AFixedSize: TRect; AID: Integer; const AName: string = ''; AInterpolationMode: Integer = InterpolationModeDefault): Integer; var P: TdxSkinnedRect; begin P := TdxSkinnedRect.Create; P.LoadFromBitmap(ABitmap, R, AFixedSize); P.ID := AID; P.Name := AName; P.InterpolationMode := AInterpolationMode; Result := Add(P); end; procedure TdxCustomBarSkin.Clear; var I: Integer; begin for I := 0 to Count - 1 do Parts[I].Free; inherited Clear; end; function TdxCustomBarSkin.PartByID(const AID: Integer): TdxSkinnedRect; var I: Integer; begin Result := nil; for I := 0 to Count - 1 do if AID = Parts[I].ID then begin Result := Parts[I]; Break; end; end; function TdxCustomBarSkin.PartByName(const AName: string): TdxSkinnedRect; var I: Integer; begin Result := nil; for I := 0 to Count - 1 do if AnsiSameText(AName, Parts[I].Name) then begin Result := Parts[I]; Break; end; end; function TdxCustomBarSkin.IsPersistent: Boolean; begin Result := False; end; function TdxCustomBarSkin.GetPart(Index: Integer): TdxSkinnedRect; begin Result := TdxSkinnedRect(List^[Index]); end; { TdxBarSkinManager } constructor TdxBarSkinManager.Create; begin FList := TList.Create; end; destructor TdxBarSkinManager.Destroy; var I: Integer; begin for I := 0 to FList.Count - 1 do Skins[I].Free; FList.Free; inherited Destroy; end; function TdxBarSkinManager.AddSkin(ASkin: TdxCustomBarSkin): Integer; var I: Integer; begin Result := -1; if not CheckGdiPlus then Exit; if (ASkin <> nil) and (ASkin.Name <> '') then begin for I := 0 to SkinCount - 1 do if AnsiSameText(ASkin.Name, Skins[I].Name) then Exit; Result := FList.Add(ASkin); Changed; end end; function TdxBarSkinManager.CanDeleteSkin(ASkin: TdxCustomBarSkin): Boolean; begin Result := not ASkin.IsPersistent; end; procedure TdxBarSkinManager.Changed; begin end; function TdxBarSkinManager.GetSkin(Index: Integer): TdxCustomBarSkin; begin Result := TdxCustomBarSkin(FList[Index]); end; function TdxBarSkinManager.RemoveSkin(ASkin: TdxCustomBarSkin): Boolean; var I: Integer; begin Result := CanDeleteSkin(ASkin); if Result then begin I := FList.IndexOf(ASkin); if I >= 0 then begin ASkin.Free; FList.Delete(I); Changed; end; end; end; function TdxBarSkinManager.SkinByName(const AName: string): TdxCustomBarSkin; var I: Integer; begin Result := nil; for I := 0 to SkinCount - 1 do if AnsiSameText(AName, Skins[I].Name) then begin Result := Skins[I]; Break; end; end; function TdxBarSkinManager.GetSkinCount: Integer; begin Result := FList.Count; end; procedure DestroySkinManager; begin FreeAndNil(FSkinManager); end; initialization finalization DestroySkinManager; end.