TTrackBarで動作の軽そうな動画シークバー的な何かを作ってみる


概要

そんな感じで。
プレイヤーとか描画周りは基本的にDirectShow依存なので、Windows向け。
目的は、動画の再生時間とって、それに合わせてTTrackBarをシークバーっぽく。
やることはTTrackBarのOnChange()イベントを切ってしまおうということになります。

事前に

事前準備として、TTrackBarが置いてあるということ
動画の現在位置が分かっている必要があります。
TTrackBar->Position を制御するのはTimer()です。

OnChange()

OnChange()はTTrackBar->Positionを動かすと自動で呼ばれるイベントです。

もしこれをやらないと

Timer()のIntervalごとに呼ばれるので一気に動作が重くなります。
具体的には動画がカクつき、同時にBGMもカクついてとぎれとぎれになります。

ソースコード

file01.cpp
    // 再生時であれば、シークバーと動画の進捗を対応させる
    if (SeekBar->Position < movie_length_) {

        /* << Notifyは切っておく >>
         * Notifyはポジションが変わると常に呼び出されるイベント
         * Notifyを許すと、毎回呼びだされて動画がガタつきます
         */
        TNotifyEvent tmp = SeekBar->OnChange;
        SeekBar->OnChange = NULL;
        SeekBar->Position = media_player_->get_current_position(); // 動画の現在再生時間を取得します
        SeekBar->OnChange = tmp;
    }

コレの問題点

 Position変更時のイベントを切っているので、例えばシークバーを動かして、動画の前の方に移動とかが当然効かなくなります。

そこで

 別にOnChangeを使わなくても、もっと軽い感じで実装すればいいじゃんとなります。以下のコード。

ソースコード2

file02.cpp
    // シークバーの位置に動画を同期させる
    if (SeekBar->Position != now_position_) {
      // 動画の時間をセットする処理(SeekBar->Position);
    }

    // 再生時であれば、シークバーと動画の進捗を対応させる
    if (SeekBar->Position < movie_length_) {
      /* << Notifyは切っておく >>
       * Notifyはポジションが変わると常に呼び出されるイベント
       * Notifyを許すと、毎回呼びだされて動画がガタつきます
       */
       TNotifyEvent tmp = SeekBar->OnChange;
       SeekBar->OnChange = NULL;
       SeekBar->Position = media_player_->get_current_position(); // 動画の現在再生時間を取得します
       SeekBar->OnChange = tmp;
    }
    // TimerでIntervalごとに現在の位置をメンバか何かに得ておく
    now_position_ = SeekBar->Position;