📄 dxbarskin.pas
字号:
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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -