📄 jvqspecialprogress.pas
字号:
for I := 0 to LBlockCount - 1 do
begin
FBuffer.Canvas.FillRect(Bounds(X, 1, 1, ClientHeight - 2));
Inc(X, FBlockWidth);
end;
end;
procedure TJvSpecialProgress.PaintRectangle;
var
Rect: TRect;
begin
Rect := ClientRect;
if BorderStyle = bsNone then
begin
FBuffer.Canvas.Brush.Color := Color;
FrameRect(FBuffer.Canvas, Rect);
end
else
begin
Frame3D(FBuffer.Canvas, Rect, clBtnFace, clBtnFace, 1);
Frame3D(FBuffer.Canvas, Rect, clBtnShadow, clBtnHighlight, 1);
Frame3D(FBuffer.Canvas, Rect, cl3DDkShadow, clBtnFace, 1);
end;
end;
procedure TJvSpecialProgress.PaintSolid;
var
RedInc, BlueInc, GreenInc: Real;
I: Integer;
begin
if FBlock = 0 then
Exit;
if FStart = FEnd then
begin
{ No gradient fill because the start color equals the end color }
FBuffer.Canvas.Brush.Color := FStart;
FBuffer.Canvas.Brush.Style := bsSolid;
FBuffer.Canvas.FillRect(Rect(1, 1, 1 + FBlock, ClientHeight - 1));
end
else
begin
RedInc := (GetRValue(FEnd) - GetRValue(FStart)) / FBlock;
GreenInc := (GetGValue(FEnd) - GetGValue(FStart)) / FBlock;
BlueInc := (GetBValue(FEnd) - GetBValue(FStart)) / FBlock;
FBuffer.Canvas.Brush.Style := bsSolid;
{ Fill the progressbar with slices of 1 width }
for I := 1 to FBlock do
begin
FBuffer.Canvas.Brush.Color := RGB(
Round(GetRValue(FStart) + ((I - 1) * RedInc)),
Round(GetGValue(FStart) + ((I - 1) * GreenInc)),
Round(GetBValue(FStart) + ((I - 1) * BlueInc)));
FBuffer.Canvas.FillRect(Rect(I, 1, I + 1, ClientHeight - 1));
end;
end;
end;
procedure TJvSpecialProgress.PaintText;
var
S: string;
X, Y: Integer;
LBlock: Integer;
begin
case TextOption of
toPercent:
S := Format('%d%%', [PercentDone]);
toFormat:
S := Format(Caption, [PercentDone]);
toCaption:
S := Caption;
else {toNoText}
Exit;
end;
if TextCentered then
LBlock := ClientWidth
else
LBlock := FBlock;
X := (LBlock - FBuffer.Canvas.TextWidth(S)) div 2;
if X < 0 then
X := 0;
Y := (ClientHeight - FBuffer.Canvas.TextHeight(S)) div 2;
if Y < 0 then
Y := 0;
SetBkMode(FBuffer.Canvas.Handle, QWindows.TRANSPARENT);
// FBuffer.Canvas.Brush.Color := clNone;
// FBuffer.Canvas.Brush.Style := bsClear;
FBuffer.Canvas.TextOut(X, Y, S);
end;
procedure TJvSpecialProgress.SetBorderStyle(Value: TBorderStyle);
begin
if FBorderStyle <> Value then
begin
FBorderStyle := Value;
FIsChanged := True;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetEndColor(const Value: TColor);
begin
if FEndColor <> Value then
begin
FEndColor := Value;
FEnd := ColorToRGB(FEndColor);
FIsChanged := True;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetGradientBlocks(const Value: Boolean);
begin
if Value <> FGradientBlocks then
begin
FGradientBlocks := Value;
if not Solid then
begin
FIsChanged := True;
UpdateBuffer;
end;
end;
end;
procedure TJvSpecialProgress.SetMaximum(const Value: Integer);
var
OldPercentageDone: Integer;
begin
if FMaximum <> Value then
begin
OldPercentageDone := GetPercentDone;
FMaximum := Value;
if FMaximum < FMinimum then
FMaximum := FMinimum;
if FPosition > Value then
FPosition := Value;
{ If the percentage has changed we must update, otherwise check in
UpdateBlock if we must update }
FIsChanged := (TextOption in [toPercent, toFormat]) and (OldPercentageDone <> GetPercentDone);
UpdateBlock;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetMinimum(const Value: Integer);
var
OldPercentageDone: Integer;
begin
if FMinimum <> Value then
begin
OldPercentageDone := GetPercentDone;
FMinimum := Value;
if FMinimum > FMaximum then
FMinimum := FMaximum;
if FPosition < Value then
FPosition := Value;
{ If the percentage has changed we must update, otherwise check in
UpdateBlock if we must update }
FIsChanged := (TextOption in [toPercent, toFormat]) and (OldPercentageDone <> GetPercentDone);
UpdateBlock;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetPosition(const Value: Integer);
var
OldPercentageDone: Integer;
begin
if FPosition <> Value then
begin
OldPercentageDone := GetPercentDone;
FPosition := Value;
if FPosition > FMaximum then
FPosition := FMaximum
else
if FPosition < FMinimum then
FPosition := FMinimum;
{ If the percentage has changed we must update, otherwise check in
UpdateBlock if we must update }
FIsChanged := (TextOption in [toPercent, toFormat]) and (OldPercentageDone <> GetPercentDone);
UpdateBlock;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetSolid(const Value: Boolean);
begin
if FSolid <> Value then
begin
FSolid := Value;
FIsChanged := True;
UpdateBlock;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetStartColor(const Value: TColor);
begin
if FStartColor <> Value then
begin
FStartColor := Value;
FStart := ColorToRGB(FStartColor);
FIsChanged := True;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.SetTextCentered(const Value: Boolean);
begin
if FTextCentered <> Value then
begin
FTextCentered := Value;
if TextOption <> toNoText then
begin
FIsChanged := True;
UpdateBuffer;
end;
end;
end;
procedure TJvSpecialProgress.SetTextOption(const Value: TJvTextOption);
begin
if FTextOption <> Value then
begin
FTextOption := Value;
FIsChanged := True;
UpdateBuffer;
end;
end;
procedure TJvSpecialProgress.StepIt;
begin
if FPosition + FStep > FMaximum then
Position := FMaximum
else
if FPosition + FStep < FMinimum then
Position := FMinimum
else
Position := FPosition + FStep;
end;
procedure TJvSpecialProgress.UpdateBuffer;
begin
if not FIsChanged or (csLoading in ComponentState) then
Exit;
FIsChanged := False;
if (ClientWidth <= 0) or (ClientHeight <= 0) then
Exit;
FBuffer.Width := ClientWidth;
FBuffer.Height := ClientHeight;
FBuffer.Canvas.start;
if FSolid then
PaintSolid
else
PaintNonSolid;
PaintBackground;
PaintText;
PaintRectangle;
FBuffer.Canvas.Stop;
Repaint;
end;
procedure TJvSpecialProgress.UpdateBlock;
var
NewBlock: Integer;
NextBlockWidth: Integer;
begin
if csLoading in ComponentState then
Exit;
if (FMaximum = FMinimum) or (ClientWidth < 2) then
Exit;
{ Max width of the progressbar is ClientWidth -2 [-2 for the border],
NewBlock specifies the new length of the progressbar }
NewBlock := (ClientWidth - 2) * (FPosition - FMinimum) div (FMaximum - FMinimum);
if not FSolid then
begin
{ The Block of a solid bar can have a different size than the Block
of a non-solid bar }
FBlockWidth := Round(ClientHeight * 2 div 3);
if FBlockWidth = 0 then
NewBlock := 0
else
begin
{ The block count equals 'Block div blockwidth'. We add 1 to
that number if the Block is further than 1/2 of the next block.
Note that the next block doesn't have to be of size FBlockWidth,
because it can be the last block, which can be smaller than
FBlockWidth }
FBlockCount := NewBlock div FBlockWidth;
NextBlockWidth := ClientWidth - 2 - (FBlockCount * FBlockWidth);
if NextBlockWidth > FBlockWidth then
NextBlockWidth := FBlockWidth;
if 2 * (NewBlock mod FBlockWidth) > NextBlockWidth then
begin
Inc(FBlockCount);
FLastBlockPartial := NextBlockWidth < FBlockWidth;
FLastBlockWidth := NextBlockWidth;
NewBlock := FBlockWidth * FBlockCount;
{ If FLastBlockPartial equals True then the progressbar is totally
filled: }
if FLastBlockPartial then
NewBlock := ClientWidth - 2;
end
else
begin
FLastBlockPartial := False;
NewBlock := FBlockWidth * FBlockCount;
end;
end;
end;
if NewBlock = FBlock then
Exit;
FBlock := NewBlock;
FIsChanged := True;
UpdateBuffer;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$RCSfile: JvQSpecialProgress.pas,v $';
Revision: '$Revision: 1.20 $';
Date: '$Date: 2004/12/01 22:53:20 $';
LogPath: 'JVCL\run'
);
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -