⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dxbarskin.pas

📁 胜天进销存源码,国产优秀的进销存
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{*******************************************************************}
{                                                                   }
{       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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -