-
-
Notifications
You must be signed in to change notification settings - Fork 924
/
NewProgressBar.pas
155 lines (133 loc) · 4.34 KB
/
NewProgressBar.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
unit NewProgressBar;
{
Inno Setup
Copyright (C) 1997-2024 Jordan Russell
Portions by Martijn Laan
For conditions of distribution and use, see LICENSE.TXT.
TNewProgressBar component - a smooth 32 bit TProgressBar
Note: themed animated progress bars and don't immediately show changes.
This applies both to Position and State. For example if you set State while the
progress bar is still moving towards a new Position, the new State doesnt show until
the moving animation has finished.
}
interface
uses
Messages, Classes, Controls, ComCtrls;
type
TNewProgressBarState = (npbsNormal, npbsError, npbsPaused);
TNewProgressBarStyle = (npbstNormal, npbstMarquee);
TNewProgressBar = class(TWinControl)
private
FMin: LongInt;
FMax: LongInt;
FPosition: LongInt;
FState: TNewProgressBarState;
FStyle: TNewProgressBarStyle;
procedure SetMin(Value: LongInt);
procedure SetMax(Value: LongInt);
procedure SetPosition(Value: LongInt);
procedure SetState(Value: TNewProgressBarState);
procedure SetStyle(Value: TNewProgressBarStyle);
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
protected
procedure CreateParams(var Params: TCreateParams); override;
procedure CreateWnd; override;
public
constructor Create(AOwner: TComponent); override;
published
property Anchors;
property Min: LongInt read FMin write SetMin;
property Max: LongInt read FMax write SetMax;
property Position: LongInt read FPosition write SetPosition default 0;
property State: TNewProgressBarState read FState write SetState default npbsNormal;
property Style: TNewProgressBarStyle read FStyle write SetStyle default npbstMarquee;
property Visible default True;
end;
procedure Register;
implementation
uses
Windows, CommCtrl;
procedure Register;
begin
RegisterComponents('JR', [TNewProgressBar]);
end;
constructor TNewProgressBar.Create(AOwner: TComponent);
begin
inherited;
Width := 150;
Height := GetSystemMetrics(SM_CYVSCROLL);
FMin := 0;
FMax := 100;
end;
procedure TNewProgressBar.CreateParams(var Params: TCreateParams);
const
PBS_SMOOTH = 1;
PBS_MARQUEE = 8;
begin
InitCommonControls;
inherited;
CreateSubClass(Params, PROGRESS_CLASS);
Params.Style := Params.Style or PBS_SMOOTH;
if Style = npbstMarquee then
Params.Style := Params.Style or PBS_MARQUEE;
end;
procedure TNewProgressBar.CreateWnd;
const
PBM_SETMARQUEE = WM_USER+10;
begin
inherited CreateWnd;
SendMessage(Handle, PBM_SETRANGE, 0, MAKELPARAM(0, 65535));
SetPosition(FPosition);
SetState(FState);
SendMessage(Handle, PBM_SETMARQUEE, WPARAM(FStyle = npbstMarquee), 0);
end;
procedure TNewProgressBar.SetMin(Value: LongInt);
begin
FMin := Value;
SetPosition(FPosition);
end;
procedure TNewProgressBar.SetMax(Value: LongInt);
begin
FMax := Value;
SetPosition(FPosition);
end;
procedure TNewProgressBar.SetPosition(Value: LongInt);
begin
if Value < FMin then
Value := FMin
else if Value > FMax then
Value := FMax;
FPosition := Value;
if HandleAllocated and (FStyle <> npbstMarquee) then
SendMessage(Handle, PBM_SETPOS, MulDiv(Value - FMin, 65535, FMax - FMin), 0);
end;
procedure TNewProgressBar.SetState(Value: TNewProgressBarState);
const
PBST_NORMAL = $0001;
PBST_ERROR = $0002;
PBST_PAUSED = $0003;
PBM_SETSTATE = WM_USER+16;
States: array[TNewProgressBarState] of UINT = (PBST_NORMAL, PBST_ERROR, PBST_PAUSED);
begin
FState := Value;
if HandleAllocated then
SendMessage(Handle, PBM_SETSTATE, States[Value], 0);
end;
procedure TNewProgressBar.SetStyle(Value: TNewProgressBarStyle);
begin
if FStyle <> Value then begin
FStyle := Value;
RecreateWnd;
end;
end;
procedure TNewProgressBar.WMEraseBkgnd(var Message: TWMEraseBkgnd);
begin
{ Bypass TWinControl's default WM_ERASEBKGND handling.
On Windows Vista with COMCTL32 v6, a WM_ERASEBKGND message is sent every
time a progress bar's position changes. TWinControl.WMEraseBkgnd does a
FillRect on the whole client area, which results in ugly flickering.
Previous versions of Windows only sent a WM_ERASEBKGND message when a
progress bar moved backwards, so flickering was rarely apparent. }
DefaultHandler(Message);
end;
end.