我創建了下面這個類,試圖改善滾動條的回應。原因是,如果滾動條的onchange事件中的代碼稍顯緩慢,那么直到您停止拖動拇指,更新才會生效。例如,如果在onchange事件中重繪畫布,這就很煩人。然而,在TTimer事件中更新畫布就很順利。我的猜測是,這與TScrollBar的OnChange事件是同步的,而TTimer事件是異步的有關。我的代碼試圖通過使用 TTimer 觸發事件來解決 TScrollBar 的問題,該事件通過 MouseDown 事件啟用,通過 MouseUp 事件禁用。
問題是,OnMouseDown 事件根本沒有觸發。我還嘗試在設計時向表單添加一個 TScrollBar 組件,然后檢查其 MouseDown 或 MouseUp 事件是否被觸發,但它們也沒有被觸發。我設法找到了2013年的一個類似的問題,但該問題從未得到解答。
https://codeverge.com/embarcadero.delphi.firemonkey/help-how-to-trap-mouse-down-mou/1057945
那么,這些事件沒有被觸發的原因是什么呢?我怎樣才能使它們被觸發呢?
另外,如果有什么問題,請聯系我們。
此外,如果有其他方法可以改善標準 TScrollBar 的回應,那么請讓我知道?我使用的是Delphi 10.4.
。unit ScrollBarSmoothUnit。
介面
使用
System.Classes, System.UITypes, FMX.StdCtrls, FMX.Types。
型別
TScrollBarSmooth = class(TScrollBar)
private[/span
FTimer : TTimer;
FLastValue : Single;
procedure ScrollMouseDown(Sender: TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
procedure ScrollMouseUp(Sender: TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
procedure DoChange(Sender: TObject);
public
OnChangeSmooth : TNotifyEvent;
constructor Create(AOwner: TComponent); override。
end;
implementation; implementation
constructor TScrollBarSmooth.Create(AOwner: TComponent);
begin
inherited Create(AOwner)。
AutoCapture := True;
HitTest := True;
onm ouseDown := ScrollMouseDown;
onm ouseUp := ScrollMouseUp;
FTimer := TTimer.Create(Self);
FTimer.Interval := 40;
FTimer.Enabled := False;
FTimer.OnTimer := DoChange;
FLastValue := -1;
end。
procedure TScrollBarSmooth.ScrollMouseDown(Sender。TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
begin
FTimer.Enabled := True。
end;
procedure TScrollBarSmooth.ScrollMouseUp(Sender。TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
begin
FTimer.Enabled := False;
DoChange(Self);
end;
procedure TScrollBarSmooth.DoChange(Sender: TObject);
begin
if Value = FLastValue then Exit; // no change
FLastValue := Value;
if Assigned(OnChangeSmooth) then OnChangeSmooth(Self)。
end;
end.
uj5u.com熱心網友回復:
下面的頁面為我回答了這個問題(從日文翻譯過來后)。
https://www.gesource.jp/weblog/?p=6206
TScrollBar包含一個Track物件,它又包含一個Thumb物件。回應滑鼠事件的是這些物件而不是滾動條。這些物件在TScrollBar建構式中還不存在,所以我在Paint程序中設定了滑鼠事件。滑鼠事件隨后被觸發,這就解決了我的性能問題。現在拖動滾動條可以更順暢地更新我的畫布。
unit ScrollBarSmoothUnit。
介面
使用
System.Classes, System.UITypes, FMX.StdCtrls, FMX.Types。
型別
//A scroll bar with smoother response if OnChange event is slow。
TScrollBarSmooth = class(TScrollBar)
private[/span
FTimer : TTimer;
FLastValue : Single;
FMouseEventsSet : Boolean;
FOnChangeSmooth : TNotifyEvent;
procedure ScrollMouseDown(Sender: TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
procedure ScrollMouseUp(Sender: TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
procedure DoChange(Sender: TObject);
protected
procedure Paint; override;
public
constructor Create(AOwner: TComponent); override。
property OnChangeSmooth : TNotifyEvent write FOnChangeSmooth;
end;
implementation
constructor TScrollBarSmooth.Create(AOwner: TComponent);
begin
inherited Create(AOwner)。
FTimer := TTimer.Create(Self);
FTimer.Interval := 40;
FTimer.Enabled := False;
FTimer.OnTimer := DoChange;
FLastValue := -1;
FMouseEventsSet := False;
end。
procedure TScrollBarSmooth.Paint;
begin.
inherited;
// Track和Buttons在建構式中沒有被分配,所以要在第一次畫圖時設定滑鼠事件。
if not FMouseEventsSet and Assigned(Track.Thumb)
and Assigned(MinButton) and Assigned(MaxButton) then begin
Track.OnMouseDown := ScrollMouseDown。
Track.OnMouseUp := ScrollMouseUp;
Track.Thumb.OnMouseDown := ScrollMouseDown;
Track.Thumb.OnMouseUp := ScrollMouseUp;
MinButton.OnMouseDown := ScrollMouseDown;
MinButton.OnMouseUp := ScrollMouseUp;
MaxButton.OnMouseDown := ScrollMouseDown;
MaxButton.OnMouseUp := ScrollMouseUp;
FMouseEventsSet := True。
end。
end;
procedure TScrollBarSmooth.ScrollMouseDown(Sender。TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
begin
FTimer.Enabled := True。
end;
procedure TScrollBarSmooth.ScrollMouseUp(Sender。TObject; Button: TMouseButton;
Shift。TShiftState; X, Y: Single);?
begin
FTimer.Enabled := False;
DoChange(Self);
end;
procedure TScrollBarSmooth.DoChange(Sender: TObject);
begin
if Value = FLastValue then Exit; // no change
FLastValue := Value;
if Assigned(FOnChangeSmooth) then FOnChangeSmooth(Self)。
end;
end.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/329636.html
標籤:
