📄 bsskinexctrls.pas
字号:
{*******************************************************************}
{ }
{ Almediadev Visual Component Library }
{ BusinessSkinForm }
{ Version 6.07 }
{ }
{ Copyright (c) 2000-2007 Almediadev }
{ ALL RIGHTS RESERVED }
{ }
{ Home: http://www.almdev.com }
{ Support: support@almdev.com }
{ }
{*******************************************************************}
unit bsSkinExCtrls;
{$P+,S-,W-,R-}
{$WARNINGS OFF}
{$HINTS OFF}
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Menus, ExtCtrls, bsSkinData, bsUtils, bsSkinCtrls;
type
TbsSkinAnimateGauge = class(TbsSkinCustomControl)
protected
FImitation: Boolean;
FCountFrames: Integer;
FAnimationFrame: Integer;
FAnimationPauseTimer: TTimer;
FAnimationTimer: TTimer;
FAnimationPause: Integer;
FProgressText: String;
FShowProgressText: Boolean;
procedure OnAnimationPauseTimer(Sender: TObject);
procedure OnAnimationTimer(Sender: TObject);
procedure SetShowProgressText(Value: Boolean);
procedure SetProgressText(Value: String);
procedure GetSkinData; override;
procedure CreateImage(B: TBitMap);
procedure DrawProgressText(C: TCanvas);
procedure CreateControlDefaultImage(B: TBitMap); override;
procedure CreateControlSkinImage(B: TBitMap); override;
procedure WMEraseBkgnd(var Msg: TWMEraseBkgnd); message WM_ERASEBKGND;
function GetAnimationFrameRect: TRect;
procedure CalcSize(var W, H: Integer); override;
function CalcProgressRect: TRect;
procedure StartInternalAnimation;
procedure StopInternalAnimation;
public
ProgressRect, ProgressArea: TRect;
NewProgressArea: TRect;
BeginOffset, EndOffset: Integer;
FontName: String;
FontStyle: TFontStyles;
FontHeight: Integer;
FontColor: TColor;
ProgressTransparent: Boolean;
ProgressTransparentColor: TColor;
ProgressStretch: Boolean;
AnimationBeginOffset,
AnimationEndOffset: Integer;
//
AnimationSkinRect: TRect;
AnimationCountFrames: Integer;
AnimationTimerInterval: Integer;
//
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure StartAnimation;
procedure StopAnimation;
procedure SetAnimationPause(Value: Integer);
procedure ChangeSkinData; override;
published
property ProgressText: String read FProgressText write SetProgressText;
property ShowProgressText: Boolean read FShowProgressText write SetShowProgressText;
property AnimationPause: Integer
read FAnimationPause write SetAnimationPause;
property Align;
property Enabled;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnResize;
property PopupMenu;
property ShowHint;
end;
implementation
const
DEF_GAUGE_FRAMES = 10;
// TbsSkinAnimateGauge
constructor TbsSkinAnimateGauge.Create;
begin
inherited;
Width := 100;
Height := 20;
BeginOffset := 0;
EndOffset := 0;
FProgressText := '';
FShowProgressText := False;
FSkinDataName := 'gauge';
FAnimationPause := 1000;
FAnimationPauseTimer := nil;
FAnimationTimer := nil;
FAnimationFrame := 0;
FCountFrames := 0;
FImitation := False;
end;
destructor TbsSkinAnimateGauge.Destroy;
begin
if FAnimationPauseTimer <> nil then FAnimationPauseTimer.Free;
if FAnimationTimer <> nil then FAnimationTimer.Free;
inherited;
end;
procedure TbsSkinAnimateGauge.OnAnimationPauseTimer(Sender: TObject);
begin
StartInternalAnimation;
end;
procedure TbsSkinAnimateGauge.OnAnimationTimer(Sender: TObject);
begin
Inc(FAnimationFrame);
if FAnimationFrame > FCountFrames
then
StopInternalAnimation;
RePaint;
end;
procedure TbsSkinAnimateGauge.SetAnimationPause;
begin
if Value >= 0
then
FAnimationPause := Value;
end;
procedure TbsSkinAnimateGauge.StartInternalAnimation;
begin
if FAnimationPauseTimer <> nil then FAnimationPauseTimer.Enabled := False;
FAnimationFrame := 0;
FAnimationTimer.Enabled := True;
RePaint;
end;
procedure TbsSkinAnimateGauge.StopInternalAnimation;
begin
if FAnimationPauseTimer <> nil then FAnimationPauseTimer.Enabled := True;
FAnimationTimer.Enabled := False;
FAnimationFrame := 0;
RePaint;
end;
procedure TbsSkinAnimateGauge.StartAnimation;
begin
if (FIndex = -1) or ((FIndex <> -1) and
IsNullRect(Self.AnimationSkinRect))
then
begin
FImitation := True;
FCountFrames := DEF_GAUGE_FRAMES + 5;
end
else
begin
FImitation := False;
if AnimationCountFrames = 1
then
FCountFrames := (RectWidth(NewProgressArea) + RectWidth(AnimationSkinRect) * 2)
div (RectWidth(AnimationSkinRect) div 3)
else
FCountFrames := AnimationCountFrames;
end;
if FAnimationPauseTimer <> nil then FAnimationPauseTimer.Free;
if FAnimationTimer <> nil then FAnimationTimer.Free;
FAnimationPauseTimer := TTimer.Create(Self);
FAnimationPauseTimer.Enabled := False;
FAnimationPauseTimer.OnTimer := OnAnimationPauseTimer;
FAnimationPauseTimer.Interval := FAnimationPause;
FAnimationPauseTimer.Enabled := True;
FAnimationTimer := TTimer.Create(Self);
FAnimationTimer.Enabled := False;
FAnimationTimer.OnTimer := OnAnimationTimer;
if FImitation
then
FAnimationTimer.Interval := 40
else
FAnimationTimer.Interval := Self.AnimationTimerInterval;
StartInternalAnimation;
end;
procedure TbsSkinAnimateGauge.StopAnimation;
begin
FAnimationFrame := 0;
if FAnimationTimer = nil then Exit;
if FAnimationPauseTimer <> nil
then
begin
FAnimationPauseTimer.Enabled := False;
FAnimationPauseTimer.Free;
FAnimationPauseTimer := nil;
end;
if FAnimationTimer <> nil
then
begin
FAnimationTimer.Enabled := False;
FAnimationTimer.Free;
FAnimationTimer := nil;
end;
RePaint;
end;
procedure TbsSkinAnimateGauge.WMEraseBkgnd;
begin
if not FromWMPaint
then
PaintWindow(Msg.DC);
end;
procedure TbsSkinAnimateGauge.DrawProgressText;
var
S: String;
TX, TY: Integer;
F: TLogFont;
begin
if (FIndex = -1)
then
C.Font.Assign(FDefaultFont)
else
if (FIndex <> -1) and not FUseSkinFont
then
begin
C.Font.Assign(FDefaultFont);
C.Font.Color := FontColor;
end
else
with C do
begin
Font.Name := FontName;
Font.Height := FontHeight;
Font.Style := FontStyle;
Font.Color := FontColor;
end;
if (SkinData <> nil) and (SkinData.ResourceStrData <> nil)
then
C.Font.Charset := SkinData.ResourceStrData.CharSet
else
C.Font.CharSet := FDefaultFont.Charset;
S := '';
if FShowProgressText then S := S + FProgressText;
if S = '' then Exit;
with C do
begin
TX := Width div 2 - TextWidth(S) div 2;
TY := Height div 2 - TextHeight(S) div 2;
Brush.Style := bsClear;
TextOut(TX, TY, S);
end;
end;
procedure TbsSkinAnimateGauge.SetShowProgressText;
begin
FShowProgressText := Value;
RePaint;
end;
procedure TbsSkinAnimateGauge.SetProgressText;
begin
FProgressText := Value;
RePaint;
end;
procedure TbsSkinAnimateGauge.CalcSize;
var
Offset: Integer;
W1, H1: Integer;
begin
inherited;
if ResizeMode > 0
then
begin
Offset := W - RectWidth(SkinRect);
NewProgressArea := ProgressArea;
Inc(NewProgressArea.Right, Offset);
end
else
NewProgressArea := ProgressArea;
if (FIndex <> -1) and not IsNullRect(AnimationSkinRect) and
(Self.AnimationCountFrames = 1)
then
begin
FCountFrames := (RectWidth(NewProgressArea) + RectWidth(AnimationSkinRect) * 2)
div (RectWidth(AnimationSkinRect) div 3);
if (FAnimationTimer <> nil) and FAnimationTimer.Enabled
then
if FAnimationFrame > FCountFrames then FAnimationFrame := 1;
end;
end;
function TbsSkinAnimateGauge.GetAnimationFrameRect;
var
fs: Integer;
begin
if RectWidth(AnimationSkinRect) > RectWidth(AnimationSkinRect)
then
begin
fs := RectWidth(AnimationSkinRect) div AnimationCountFrames;
Result := Rect(AnimationSkinRect.Left + (FAnimationFrame - 1) * fs,
AnimationSkinRect.Top,
AnimationSkinRect.Left + FAnimationFrame * fs,
AnimationSkinRect.Bottom);
end
else
begin
fs := RectHeight(AnimationSkinRect) div AnimationCountFrames;
Result := Rect(AnimationSkinRect.Left,
AnimationSkinRect.Top + (FAnimationFrame - 1) * fs,
AnimationSkinRect.Right,
AnimationSkinRect.Top + FAnimationFrame * fs);
end;
end;
function TbsSkinAnimateGauge.CalcProgressRect: TRect;
var
R: TRect;
FrameWidth: Integer;
begin
R.Top := NewProgressArea.Top;
R.Bottom := R.Top + RectHeight(ProgressRect);
FrameWidth := Width div DEF_GAUGE_FRAMES;
R.Left := NewProgressArea.Left + (FAnimationFrame - 1) * FrameWidth - 3 * FrameWidth;
R.Right := R.Left + FrameWidth;
Result := R;
end;
procedure TbsSkinAnimateGauge.CreateControlSkinImage;
var
Buffer: TBitMap;
R, R1: TRect;
X, Y: Integer;
XStep: Integer;
begin
inherited;
if (FAnimationTimer = nil) or (FCountFrames = 0) or (FAnimationFrame = 0)
then
begin
if ShowProgressText then DrawProgressText(B.Canvas);
Exit;
end;
if FImitation
then
begin
R := CalcProgressRect;
R.Left := R.Left - RectWidth(R) div 2;
R.Right := R.Right + RectWidth(R) div 2;
Buffer := TBitMap.Create;
Buffer.Width := RectWidth(R);
Buffer.Height := RectHeight(R);
CreateHSkinImage(BeginOffset, EndOffset, Buffer, Picture, ProgressRect,
Buffer.Width, Buffer.Height, ProgressStretch);
if ProgressTransparent
then
begin
Buffer.Transparent := True;
Buffer.TransparentMode := tmFixed;
Buffer.TransparentColor := ProgressTransparentColor;
end;
IntersectClipRect(B.Canvas.Handle,
NewProgressArea.Left, NewProgressArea.Top,
NewProgressArea.Right, NewProgressArea.Bottom);
B.Canvas.Draw(R.Left, R.Top, Buffer);
if ShowProgressText then DrawProgressText(B.Canvas);
Buffer.Free;
end
else
if not FImitation and (AnimationCountFrames > 1)
then
begin
R := NewProgressArea;
R1 := GetAnimationFrameRect;
Buffer := TBitMap.Create;
Buffer.Width := RectWidth(R);
Buffer.Height := RectHeight(R);
CreateHSkinImage(AnimationBeginOffset,
AnimationEndOffset, Buffer, Picture, R1,
Buffer.Width, Buffer.Height, True);
IntersectClipRect(B.Canvas.Handle,
NewProgressArea.Left, NewProgressArea.Top,
NewProgressArea.Right, NewProgressArea.Bottom);
B.Canvas.Draw(R.Left, R.Top, Buffer);
if ShowProgressText then DrawProgressText(B.Canvas);
Buffer.Free;
end
else
if not FImitation and (AnimationCountFrames = 1)
then
begin
FCountFrames := (RectWidth(NewProgressArea) + RectWidth(AnimationSkinRect) * 2)
div (RectWidth(AnimationSkinRect) div 3);
if FAnimationFrame > FCountFrames then FAnimationFrame := 1;
Buffer := TBitMap.Create;
Buffer.Width := RectWidth(AnimationSkinRect);
Buffer.Height := RectHeight(AnimationSkinRect);
Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height), Picture.Canvas,
AnimationSkinRect);
XStep := RectWidth(AnimationSkinRect) div 3;
X := NewProgressArea.Left + XStep * (FAnimationFrame - 1) -
RectWidth(AnimationSkinRect);
Y := NewProgressArea.Top;
IntersectClipRect(B.Canvas.Handle,
NewProgressArea.Left, NewProgressArea.Top,
NewProgressArea.Right, NewProgressArea.Bottom);
B.Canvas.Draw(X, Y, Buffer);
if ShowProgressText then DrawProgressText(B.Canvas);
Buffer.Free;
end;
end;
procedure TbsSkinAnimateGauge.CreateImage;
begin
CreateSkinControlImage(B, Picture, SkinRect);
end;
procedure TbsSkinAnimateGauge.CreateControlDefaultImage(B: TBitMap);
var
R, PR: TRect;
V: Integer;
begin
R := ClientRect;
B.Canvas.Brush.Color := clWindow;
B.Canvas.FillRect(R);
Frame3D(B.Canvas, R, clbtnShadow, clbtnShadow, 1);
DrawProgressText(B.Canvas);
end;
procedure TbsSkinAnimateGauge.GetSkinData;
begin
inherited;
if FIndex <> -1
then
if TbsDataSkinControl(FSD.CtrlList.Items[FIndex]) is TbsDataSkinGaugeControl
then
with TbsDataSkinGaugeControl(FSD.CtrlList.Items[FIndex]) do
begin
Self.ProgressRect := ProgressRect;
Self.ProgressArea := ProgressArea;
Self.BeginOffset := BeginOffset;
Self.EndOffset := EndOffset;
Self.FontName := FontName;
Self.FontStyle := FontStyle;
Self.FontHeight := FontHeight;
Self.FontColor := FontColor;
Self.ProgressTransparent := ProgressTransparent;
Self.ProgressTransparentColor := ProgressTransparentColor;
Self.ProgressStretch := ProgressStretch;
Self.AnimationSkinRect := AnimationSkinRect;
Self.AnimationCountFrames := AnimationCountFrames;
Self.AnimationTimerInterval := AnimationTimerInterval;
Self.AnimationBeginOffset := AnimationBeginOffset;
Self.AnimationEndOffset := AnimationEndOffset;
end;
end;
procedure TbsSkinAnimateGauge.ChangeSkinData;
var
FAnimation: Boolean;
begin
FAnimation := FAnimationTimer <> nil;
if FAnimation then StopAnimation;
inherited;
if FAnimation then StartAnimation;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -