2016-07-28 14 views
0

私はDelphi 10 SeattleのTScrollBarのイベント(OnScroll)ハンドラの解決策を見つけられませんでした。私はそれがPanelやDBGridのようなコンテンツを入れるTScrollBoxではないので、私はそれを選択しました。マウスの動きを検出するだけです(MouseUp/Down/Side-to-Sideのいずれも動作していません)。ファイルシークツールとして使用され、多数のTeeChartを強制的にアップデートしますスクロールの方向に移動します。これまでのところ私はWindowsMessagesからなる不可解な例(WM_HSCROLL)に遭遇しているFMXのTScrollBarに相当するOnScrollイベントは何ですか?

とVLC.StdCtrls.TScrollBar.OnScroll

のOnChange以外に移動するスクロールバーを検出するための効率的な方法は何ですか?

スクロールバーを操作して、途中で自分自身をリセットすることができれば助かります。 Min = -50とMax = 50(0)を設定した場合と同じように値を設定した場合とよく似ています

+0

タイマーを使用する際に

OnChangeイベントハンドラOnChangeイベントは、正常に動作する必要があります。OnScrollと同じように動作します。最小値と最大値のプロパティを任意の値に設定できます。 –

+0

私はあなたの質問を忘れていない、なぜあなたはOnChange *以外に何かを探しているのですか? OnChangeはあなたが使うはずのものです。中にリセットするには、 'sb.Value:=(sb.max + sb.min)/ 2;を設定してください。 –

+0

私はあなたの提案を実装しましたが、私は自分自身を十分にはっきりさせていないのではないかと心配しています。スクロールバーを移動した後、スクロールバーを元の位置(中央)に戻したい[リンク](http://stackoverflow.com/questions/1269799/)このリンクには、OnScroll(VCL)の追加プロパティが表示されます。私はonChangeが匹敵しないと思った。 –

答えて

0

FMX TScrollBarの制限を克服するために、 (あなたが提供したリンクに部分的に触発されています)。

スクロールバーでスクロールするコントロールが現在のスクロール位置を格納するプロパティを持っている(または装備できる)場合は、/の/ definedを使用できます。テストのために私はそれをフォームのプライベートプロパティとして定義し、それをsbIncrementalと呼んでいます。

その後、OnChangeイベントは私のテストでは、このようになります

Max = 100SmallChange = 10Orientation = Verticalとして及び Min = -100私は TScrollBarのプロパティを設定します。中央にスクロールバーの位置をリセットするには

procedure TForm6.ScrollBarChange(Sender: TObject); 
var 
    sb: TScrollBar; 
    sbOnChange: TNotifyEvent; 
begin 
    sb := (Sender as TScrollBar); 
    sbIncremental := sbIncremental + sb.Value; 

    Label1.Text := FloatToStr(sbIncremental); // Use the new value 

    sbOnChange := sb.OnChange; // Disable OnChange event 
    sb.OnChange := nil;   // -"- 
    sb.Value := (sb.Min + sb.Max)/2; // Reset position 
    sb.OnChange := sbOnChange; // Re-enable OnChange event 
end; 

OnChangeイベントを一時的に無効にする必要があります。


コメント後の更新。

私が今理解しているように、値が(OnChange内で)0に変更されても、スクロールバーの視覚的外観が0の位置に戻らないという問題があります(最小= -100、最大=ゼロ位置は中央にある)。矢印ボタンをクリックしたときに表示されますが、サムグリップをドラッグするか、サムグリップのいずれかの側をクリックしても表示されません。ビジュアル更新は、OnChangeイベント内のこれらの2つのケースでは防止されているようです。また、ScrollBar.Repaintを呼び出しても外観は更新されません。 OnMouseDown/OnMouseUpイベントを使用する方法が見つかりませんでした。彼らは内部的にリンクされているように見えませんか?

これは次の(ハッキーな)解決策を私たちに残します。タイマーを小さな遅延、たとえば300msで起動させます。タイムアウトが発生すると、スクロールバーは新しい値の変更を受け入れ、視覚的に更新できる状態になります。また、タイマーにはプラスの効果があり、クリックするとサムグリップが動いてから後退します。間に時間がなければ、何かが起こるという視覚的な指示はありません。

procedure TForm6.ScrollBarChange(Sender: TObject); 
begin 
    // Use the scrollbar value 
    Label1.Text := FloatToStr((Sender as TScrollBar).Value); 

    // Enable reset timer 
    ScrollBarTimer.Enabled := False; 
    ScrollBarTimer.Enabled := True; 
end; 

とのOnTimerイベント

procedure TForm6.ScrollBarTimerTimer(Sender: TObject); 
var 
    sbOnChange: TNotifyEvent; 
begin 
    ScrollBarTimer.Enabled := False; 

    sbOnChange := ScrollBar.OnChange; // store OnChange event 
    ScrollBar.OnChange := nil;  // disable OnChange event 
    ScrollBar.Value := (ScrollBar.Min + ScrollBar.Max)/2; // reset position 
    ScrollBar.OnChange := sbOnChange; // re-enable OnChange event 
end; 
+0

これは単なるテストだと思いますが、ポイントsbIncrementは何ですか?これは、単にスクロールバーが向いている方向を永久にインクリメント/デクリメントするw/eに加算/減算するだけです。スクロールバーがリセットされていないと思うのは、(1)ScrollBar1と(2)sb(ローカル変数)です。ローカル変数のみがローカルobjに影響を与えることはない、つまり、OnChangeを関数外に移動してグローバルScrollBar1に影響を与える必要があります。 –

+0

最初のSender:TObjectはグローバルScrollBar1へのコピーまたはポインタですか? –

+0

ローカルの 'sb'は実際の' ScrollBar'への参照にすぎません。これは 'Sender'パラメータです。目的は '**(Sender as TScrollBar)'を常に**、**または**を(Sender as TScrollBar)doを使って書くことを回避することです。 –

関連する問題