535 lines
14 KiB
ObjectPascal
535 lines
14 KiB
ObjectPascal
|
unit dwProgressBar;
|
||
|
|
||
|
interface
|
||
|
|
||
|
{$INCLUDE 'DelphiVersions.inc'}
|
||
|
|
||
|
uses
|
||
|
SysUtils, Classes, Controls, ComCtrls, Messages, Graphics,
|
||
|
dwTaskbarComponents;
|
||
|
|
||
|
const
|
||
|
ICC_PROGRESS_CLASS = $00000020;
|
||
|
|
||
|
const
|
||
|
PBS_SMOOTH = $01;
|
||
|
PBS_VERTICAL = $04;
|
||
|
PBS_MARQUEE = $08;
|
||
|
PBS_SMOOTHREVERSE = $10;
|
||
|
|
||
|
const
|
||
|
PBM_SETMARQUEE = WM_USER + 10;
|
||
|
PBM_SETSTATE = WM_USER + 16;
|
||
|
PBM_GETSTATE = WM_USER + 17;
|
||
|
|
||
|
const
|
||
|
PBST_NORMAL = $0001;
|
||
|
PBST_ERROR = $0002;
|
||
|
PBST_PAUSED = $0003;
|
||
|
|
||
|
type
|
||
|
TdwProgressBarState = (pbstMarquee = 0, pbstNormal = 1, pbstError = 2, pbstPaused = 3);
|
||
|
|
||
|
TdwProgressBar = class(TdwTaskbarWinControl)
|
||
|
private // CodeGear :: ProgressBar
|
||
|
FMin: Integer;
|
||
|
FMax: Integer;
|
||
|
FPosition: Integer;
|
||
|
FStep: Integer;
|
||
|
FOrientation: TProgressBarOrientation;
|
||
|
FSmooth: Boolean;
|
||
|
FSmoothReverse: Boolean;
|
||
|
FBarColor: TColor;
|
||
|
FBackgroundColor: TColor;
|
||
|
|
||
|
function GetMin: Integer;
|
||
|
function GetMax: Integer;
|
||
|
function GetPosition: Integer;
|
||
|
procedure SetParams(AMin, AMax: Integer);
|
||
|
procedure SetMin(Value: Integer);
|
||
|
procedure SetMax(Value: Integer);
|
||
|
procedure SetPosition(Value: Integer);
|
||
|
procedure SetStep(Value: Integer);
|
||
|
procedure SetOrientation(Value: TProgressBarOrientation);
|
||
|
procedure SetSmooth(Value: Boolean);
|
||
|
procedure SetSmoothReverse(Value: Boolean);
|
||
|
procedure SetBarColor(Value: TColor);
|
||
|
procedure SetBackgroundColor(Value: TColor);
|
||
|
procedure WMEraseBkGnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
|
||
|
|
||
|
private
|
||
|
{$IFDEF Delphi2006_UP}
|
||
|
const LIMIT_16 = 65535;
|
||
|
{$ENDIF}
|
||
|
class procedure ProgressLimitError;
|
||
|
|
||
|
private
|
||
|
FMsgUpdateTaskbar: Cardinal;
|
||
|
FProgressBarState: TdwProgressBarState;
|
||
|
FMarqueeEnabled: Boolean;
|
||
|
FMarqueeInterval: Integer;
|
||
|
FShowInTaskbar: Boolean;
|
||
|
|
||
|
procedure SetProgressBarState(const Value: TdwProgressBarState);
|
||
|
procedure SetMarqueeInterval(const Value: Integer);
|
||
|
procedure SetShowInTaskbar(const Value: Boolean);
|
||
|
procedure SetMarqueeEnabled(const Value: Boolean);
|
||
|
|
||
|
protected // CodeGear :: ProgressBar
|
||
|
procedure CreateParams(var Params: TCreateParams); override;
|
||
|
procedure CreateWnd; override;
|
||
|
procedure DestroyWnd; override;
|
||
|
|
||
|
protected
|
||
|
class function GetComCtrlClass: Integer; override;
|
||
|
class function GetComCtrlClassName: PChar; override;
|
||
|
|
||
|
procedure WndProc(var Msg: TMessage); override;
|
||
|
|
||
|
public // CodeGear ProgressBar
|
||
|
constructor Create(AOwner: TComponent); override;
|
||
|
procedure StepIt;
|
||
|
procedure StepBy(Delta: Integer);
|
||
|
|
||
|
published // CodeGear ProgressBar
|
||
|
property Align;
|
||
|
property Anchors;
|
||
|
property BorderWidth;
|
||
|
property DragCursor;
|
||
|
property DragKind;
|
||
|
property DragMode;
|
||
|
property Enabled;
|
||
|
property Hint;
|
||
|
property Constraints;
|
||
|
property Min: Integer read GetMin write SetMin default 0;
|
||
|
property Max: Integer read GetMax write SetMax default 100;
|
||
|
property Orientation: TProgressBarOrientation read FOrientation write SetOrientation default pbHorizontal;
|
||
|
property ParentShowHint;
|
||
|
property PopupMenu;
|
||
|
property Position: Integer read GetPosition write SetPosition default 0;
|
||
|
property Smooth: Boolean read FSmooth write SetSmooth default False;
|
||
|
property SmoothReverse: Boolean read FSmoothReverse write SetSmoothReverse default False;
|
||
|
property Step: Integer read FStep write SetStep default 10;
|
||
|
property BarColor: TColor read FBarColor write SetBarColor default clDefault;
|
||
|
property BackgroundColor: TColor read FBackgroundColor write SetBackgroundColor default clDefault;
|
||
|
property ShowHint;
|
||
|
property TabOrder;
|
||
|
property TabStop;
|
||
|
property Visible;
|
||
|
property OnContextPopup;
|
||
|
property OnDragDrop;
|
||
|
property OnDragOver;
|
||
|
property OnEndDock;
|
||
|
property OnEndDrag;
|
||
|
property OnEnter;
|
||
|
property OnExit;
|
||
|
{$IFDEF Delphi2006_UP}
|
||
|
property OnMouseActivate;
|
||
|
property OnMouseEnter;
|
||
|
property OnMouseLeave;
|
||
|
{$ENDIF}
|
||
|
property OnMouseDown;
|
||
|
property OnMouseMove;
|
||
|
property OnMouseUp;
|
||
|
property OnStartDock;
|
||
|
property OnStartDrag;
|
||
|
property DoubleBuffered;
|
||
|
{$IFDEF Delphi2009_Up}
|
||
|
property ParentDoubleBuffered;
|
||
|
{$ENDIF}
|
||
|
|
||
|
published
|
||
|
property ProgressBarState: TdwProgressBarState read FProgressBarState write SetProgressBarState default pbstNormal;
|
||
|
property MarqueeEnabled: Boolean read FMarqueeEnabled write SetMarqueeEnabled default False;
|
||
|
property MarqueeInterval: Integer read FMarqueeInterval write SetMarqueeInterval default 75;
|
||
|
property ShowInTaskbar: Boolean read FShowInTaskbar write SetShowInTaskbar default False;
|
||
|
end;
|
||
|
|
||
|
procedure Register;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
uses
|
||
|
Consts,
|
||
|
Themes, CommCtrl, Windows,
|
||
|
dwTaskbarList;
|
||
|
|
||
|
{$IFNDEF Delphi2006_UP}
|
||
|
const LIMIT_16 = 65535;
|
||
|
{$ENDIF}
|
||
|
|
||
|
procedure Register;
|
||
|
begin
|
||
|
RegisterComponents('Windows 6+', [TdwProgressBar]);
|
||
|
end;
|
||
|
|
||
|
{ TdwProgressBar }
|
||
|
|
||
|
constructor TdwProgressBar.Create(AOwner: TComponent);
|
||
|
begin
|
||
|
inherited Create(AOwner);
|
||
|
|
||
|
Width := 150;
|
||
|
Height := GetSystemMetrics(SM_CYVSCROLL);
|
||
|
FMin := 0;
|
||
|
FMax := 100;
|
||
|
FStep := 10;
|
||
|
FOrientation := pbHorizontal;
|
||
|
FBarColor := clDefault;
|
||
|
FBackgroundColor := clDefault;
|
||
|
FMarqueeInterval := 10;
|
||
|
FSmooth := False;
|
||
|
FSmoothReverse := False;
|
||
|
FMarqueeInterval := 50;
|
||
|
FProgressBarState := pbstNormal;
|
||
|
FShowInTaskbar := False;
|
||
|
|
||
|
FMsgUpdateTaskbar := RegisterWindowMessage('dw.Control.Update.Taskbar');
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.CreateParams(var Params: TCreateParams);
|
||
|
begin
|
||
|
inherited CreateParams(Params);
|
||
|
|
||
|
with Params do
|
||
|
begin
|
||
|
if FOrientation = pbVertical then
|
||
|
Style := Style or PBS_VERTICAL;
|
||
|
if FSmooth then
|
||
|
Style := Style or PBS_SMOOTH;
|
||
|
if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) then
|
||
|
Style := Style or PBS_MARQUEE;
|
||
|
if FSmoothReverse and ThemeServices.ThemesEnabled and CheckWin32Version(6, 0) then
|
||
|
Style := Style or PBS_SMOOTHREVERSE;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.CreateWnd;
|
||
|
begin
|
||
|
inherited CreateWnd;
|
||
|
|
||
|
if In32BitMode then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETRANGE32, FMin, FMax);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETRANGE, 0, MakeLong(FMin, FMax));
|
||
|
end;
|
||
|
|
||
|
SendMessage(Handle, PBM_SETSTEP, FStep, 0);
|
||
|
Position := FPosition;
|
||
|
BarColor := FBarColor;
|
||
|
BackgroundColor := FBackgroundColor;
|
||
|
ProgressBarState := FProgressBarState;
|
||
|
|
||
|
if ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) then
|
||
|
begin
|
||
|
if FProgressBarState = pbstMarquee then
|
||
|
SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.DestroyWnd;
|
||
|
begin
|
||
|
FPosition := Position;
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
class function TdwProgressBar.GetComCtrlClass: Integer;
|
||
|
begin
|
||
|
Result := ICC_PROGRESS_CLASS;
|
||
|
end;
|
||
|
|
||
|
class function TdwProgressBar.GetComCtrlClassName: PChar;
|
||
|
begin
|
||
|
Result := PROGRESS_CLASS;
|
||
|
end;
|
||
|
|
||
|
function TdwProgressBar.GetMax: Integer;
|
||
|
begin
|
||
|
if HandleAllocated and In32BitMode then
|
||
|
Result := SendMessage(Handle, PBM_GETRANGE, 0, 0)
|
||
|
else
|
||
|
Result := FMax;
|
||
|
end;
|
||
|
|
||
|
function TdwProgressBar.GetMin: Integer;
|
||
|
begin
|
||
|
if HandleAllocated and In32BitMode then
|
||
|
Result := SendMessage(Handle, PBM_GETRANGE, 1, 0)
|
||
|
else
|
||
|
Result := FMin;
|
||
|
end;
|
||
|
|
||
|
function TdwProgressBar.GetPosition: Integer;
|
||
|
begin
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
if In32BitMode then
|
||
|
Result := SendMessage(Handle, PBM_GETPOS, 0, 0)
|
||
|
else
|
||
|
Result := SendMessage(Handle, PBM_DELTAPOS, 0, 0);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
Result := FPosition;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
class procedure TdwProgressBar.ProgressLimitError;
|
||
|
begin
|
||
|
raise Exception.CreateFmt(SOutOfRange, [0, LIMIT_16]);
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetBackgroundColor(Value: TColor);
|
||
|
var
|
||
|
ColorRef: TColorRef;
|
||
|
begin
|
||
|
if FBackgroundColor <> Value then
|
||
|
begin
|
||
|
FBackgroundColor := Value;
|
||
|
if Value = clDefault then
|
||
|
ColorRef := TColorRef($FF000000)
|
||
|
else
|
||
|
ColorRef := TColorRef(ColorToRGB(Color));
|
||
|
|
||
|
if HandleAllocated then
|
||
|
SendMessage(Handle, PBM_SETBKCOLOR, 0, ColorRef);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetBarColor(Value: TColor);
|
||
|
var
|
||
|
ColorRef: TColorRef;
|
||
|
begin
|
||
|
if FBarColor <> Value then
|
||
|
begin
|
||
|
FBarColor := Value;
|
||
|
if Value = clDefault then
|
||
|
ColorRef := TColorRef($FF000000)
|
||
|
else
|
||
|
ColorRef := TColorRef(ColorToRGB(Color));
|
||
|
|
||
|
if HandleAllocated then
|
||
|
SendMessage(Handle, PBM_SETBARCOLOR, 0, ColorRef);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetMarqueeEnabled(const Value: Boolean);
|
||
|
begin
|
||
|
if FMarqueeEnabled <> Value then
|
||
|
begin
|
||
|
FMarqueeEnabled := Value;
|
||
|
if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) and HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetMarqueeInterval(const Value: Integer);
|
||
|
begin
|
||
|
if FMarqueeInterval <> Value then
|
||
|
begin
|
||
|
FMarqueeInterval := Value;
|
||
|
if (FProgressBarState = pbstMarquee) and ThemeServices.ThemesEnabled and CheckWin32Version(5, 1) and HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETMARQUEE, Integer(BOOL(FMarqueeEnabled)), FMarqueeInterval);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetMax(Value: Integer);
|
||
|
begin
|
||
|
if FMax <> Value then
|
||
|
begin
|
||
|
SetParams(FMin, Value);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetMin(Value: Integer);
|
||
|
begin
|
||
|
if FMin <> Value then
|
||
|
begin
|
||
|
SetParams(Value, FMax);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetOrientation(Value: TProgressBarOrientation);
|
||
|
begin
|
||
|
if FOrientation <> Value then
|
||
|
begin
|
||
|
FOrientation := Value;
|
||
|
RecreateWnd;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetParams(AMin, AMax: Integer);
|
||
|
begin
|
||
|
if AMax < AMin then
|
||
|
raise EInvalidOperation.CreateFmt(SPropertyOutOfRange, [Self.ClassName]);
|
||
|
|
||
|
if not In32BitMode and ((AMin < 0) or (AMax > LIMIT_16)) then
|
||
|
ProgressLimitError;
|
||
|
|
||
|
if (FMin <> AMin) or (FMax <> AMax) then
|
||
|
begin
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
if In32BitMode then
|
||
|
SendMessage(Handle, PBM_SETRANGE32, AMin, AMax)
|
||
|
else
|
||
|
SendMessage(Handle, PBM_SETRANGE, 0, MakeLong(AMin, AMax));
|
||
|
|
||
|
if FMin > FMax then
|
||
|
SendMessage(Handle, PBM_SETPOS, AMin, 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
FMin := AMin;
|
||
|
FMax := AMax;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetPosition(Value: Integer);
|
||
|
begin
|
||
|
if not In32BitMode and ((Value < 0) or (Value > LIMIT_16)) then
|
||
|
ProgressLimitError;
|
||
|
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETPOS, Value, 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
FPosition := Value;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetProgressBarState(const Value: TdwProgressBarState);
|
||
|
var
|
||
|
DoRecreate: Boolean;
|
||
|
begin
|
||
|
DoRecreate := (FProgressBarState <> Value);
|
||
|
FProgressBarState := Value;
|
||
|
if DoRecreate then
|
||
|
begin
|
||
|
RecreateWnd;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
if CheckWin32Version(6, 0) and HandleAllocated then
|
||
|
SendMessage(Handle, PBM_SETSTATE, Integer(Value), 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetShowInTaskbar(const Value: Boolean);
|
||
|
begin
|
||
|
if FShowInTaskbar <> Value then
|
||
|
begin
|
||
|
FShowInTaskbar := Value;
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetSmooth(Value: Boolean);
|
||
|
begin
|
||
|
if FSmooth <> Value then
|
||
|
begin
|
||
|
FSmooth := Value;
|
||
|
RecreateWnd;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetSmoothReverse(Value: Boolean);
|
||
|
begin
|
||
|
if FSmoothReverse <> Value then
|
||
|
begin
|
||
|
FSmoothReverse := Value;
|
||
|
RecreateWnd;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.SetStep(Value: Integer);
|
||
|
begin
|
||
|
if FStep <> Value then
|
||
|
begin
|
||
|
FStep := Value;
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_SETSTEP, FStep, 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.StepBy(Delta: Integer);
|
||
|
begin
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_DELTAPOS, Delta, 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.StepIt;
|
||
|
begin
|
||
|
if HandleAllocated then
|
||
|
begin
|
||
|
SendMessage(Handle, PBM_STEPIT, 0, 0);
|
||
|
PostMessage(Handle, FMsgUpdateTaskbar, 0, 0);
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.WMEraseBkGnd(var Message: TWMEraseBkgnd);
|
||
|
begin
|
||
|
DefaultHandler(Message);
|
||
|
end;
|
||
|
|
||
|
procedure TdwProgressBar.WndProc(var Msg: TMessage);
|
||
|
var
|
||
|
FormHandle: THandle;
|
||
|
begin
|
||
|
if Msg.Msg = FMsgUpdateTaskbar then
|
||
|
begin
|
||
|
if CheckWin32Version(6, 1) and (TaskbarList3 <> nil) then
|
||
|
begin
|
||
|
FormHandle := TaskBarEntryHandle;
|
||
|
if FormHandle <> INVALID_HANDLE_VALUE then
|
||
|
begin
|
||
|
if ShowInTaskbar then
|
||
|
begin
|
||
|
case FProgressBarState of
|
||
|
pbstMarquee:
|
||
|
begin
|
||
|
TaskbarList3.SetProgressState(FormHandle, TBPF_NORMAL);
|
||
|
if FMarqueeEnabled then
|
||
|
TaskbarList3.SetProgressState(FormHandle, TBPF_INDETERMINATE)
|
||
|
else
|
||
|
TaskbarList3.SetProgressState(FormHandle, TBPF_NOPROGRESS);
|
||
|
end;
|
||
|
pbstNormal: TaskbarList3.SetProgressState(FormHandle, TBPF_NORMAL);
|
||
|
pbstError: TaskbarList3.SetProgressState(FormHandle, TBPF_ERROR);
|
||
|
pbstPaused: TaskbarList3.SetProgressState(FormHandle, TBPF_PAUSED);
|
||
|
end;
|
||
|
if FProgressBarState in [pbstNormal, pbstError, pbstPaused] then
|
||
|
begin
|
||
|
TaskbarList3.SetProgressValue(FormHandle, Position - Min, Max - Min);
|
||
|
end;
|
||
|
end
|
||
|
else
|
||
|
begin
|
||
|
TaskbarList3.SetProgressState(FormHandle, TBPF_NOPROGRESS);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
inherited;
|
||
|
end;
|
||
|
|
||
|
end.
|