当我使用pbstMarquee的进度条控制与VCL样式,字幕动画不工作。重现步骤:1.文件〉新建〉VCL应用程序1.将TProgressBar放在主窗体上〉TProgressBar.Style := pbstMarquee1.项目选项〉外观〉设置自定义样式〉设置默认样式
pbstMarquee
TProgressBar
TProgressBar.Style := pbstMarquee
uurv41yg1#
这是TProgressBarStyleHook中没有实现的特性。不幸的是,当处于选框模式时,Windows不会向进度条控件发送任何消息来指示进度条的位置是否发生了变化,因此您必须自己实现一种机制来模仿PBS_MARQUEE样式,这可以很容易地通过创建一个新的样式挂钩并在样式挂钩内使用TTimer来完成。检查Style钩子的基本实现
uses Vcl.Styles, Vcl.Themes, Winapi.CommCtrl; {$R *.dfm} type TProgressBarStyleHookMarquee=class(TProgressBarStyleHook) private Timer : TTimer; FStep : Integer; procedure TimerAction(Sender: TObject); protected procedure PaintBar(Canvas: TCanvas); override; public constructor Create(AControl: TWinControl); override; destructor Destroy; override; end; constructor TProgressBarStyleHookMarquee.Create(AControl: TWinControl); begin inherited; FStep:=0; Timer := TTimer.Create(nil); Timer.Interval := 100;//TProgressBar(Control).MarqueeInterval; Timer.OnTimer := TimerAction; Timer.Enabled := TProgressBar(Control).Style=pbstMarquee; end; destructor TProgressBarStyleHookMarquee.Destroy; begin Timer.Free; inherited; end; procedure TProgressBarStyleHookMarquee.PaintBar(Canvas: TCanvas); var FillR, R: TRect; W, Pos: Integer; Details: TThemedElementDetails; begin if (TProgressBar(Control).Style=pbstMarquee) and StyleServices.Available then begin R := BarRect; InflateRect(R, -1, -1); if Orientation = pbHorizontal then W := R.Width else W := R.Height; Pos := Round(W * 0.1); FillR := R; if Orientation = pbHorizontal then begin FillR.Right := FillR.Left + Pos; Details := StyleServices.GetElementDetails(tpChunk); end else begin FillR.Top := FillR.Bottom - Pos; Details := StyleServices.GetElementDetails(tpChunkVert); end; FillR.SetLocation(FStep*FillR.Width, FillR.Top); StyleServices.DrawElement(Canvas.Handle, Details, FillR); Inc(FStep,1); if FStep mod 10=0 then FStep:=0; end else inherited; end; procedure TProgressBarStyleHookMarquee.TimerAction(Sender: TObject); var Canvas: TCanvas; begin if StyleServices.Available and (TProgressBar(Control).Style=pbstMarquee) and Control.Visible then begin Canvas := TCanvas.Create; try Canvas.Handle := GetWindowDC(Control.Handle); PaintFrame(Canvas); PaintBar(Canvas); finally ReleaseDC(Handle, Canvas.Handle); Canvas.Handle := 0; Canvas.Free; end; end else Timer.Enabled := False; end; initialization TStyleManager.Engine.RegisterStyleHook(TProgressBar, TProgressBarStyleHookMarquee); end.
您可以查看此风格钩子here的演示
1条答案
按热度按时间uurv41yg1#
这是TProgressBarStyleHook中没有实现的特性。不幸的是,当处于选框模式时,Windows不会向进度条控件发送任何消息来指示进度条的位置是否发生了变化,因此您必须自己实现一种机制来模仿PBS_MARQUEE样式,这可以很容易地通过创建一个新的样式挂钩并在样式挂钩内使用TTimer来完成。
检查Style钩子的基本实现
您可以查看此风格钩子here的演示