Bagikan melalui


Menerapkan Bilah Pencarian

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Bagian ini menjelaskan cara mengimplementasikan bilah pencarian untuk aplikasi pemutar media. Bilah pencarian diimplementasikan sebagai kontrol trackbar. Untuk gambaran umum pencarian di DirectShow, lihat Mencari Grafik Filter.

Saat aplikasi dimulai, inisialisasi trackbar:

void InitSlider(HWND hwnd) 
{
    // Initialize the trackbar range, but disable the 
    // control until the user opens a file.
    hScroll = GetDlgItem(hwnd, IDC_SLIDER1);
    EnableWindow(hScroll, FALSE);
    SendMessage(hScroll, TBM_SETRANGE, TRUE, MAKELONG(0, 100));
}

Trackbar dinonaktifkan hingga pengguna membuka file media. Rentang trackbar diatur dari 0 hingga 100. Selama pemutaran file, aplikasi akan menghitung posisi pemutaran sebagai persentase durasi file, dan memperbarui trackbar yang sesuai. Misalnya, posisi trackbar "50" selalu sesuai dengan tengah file.

Saat pengguna membuka file, buat grafik pemutaran file menggunakan RenderFile. Kode untuk ini ditampilkan dalam Cara Memainkan File. Kemudian kueri Filter Graph Manager untuk antarmuka IMediaSeeking dan simpan penunjuk antarmuka:

IMediaSeeking *g_pSeek = 0;
hr = pGraph->QueryInterface(IID_IMediaSeeking, (void**)&g_pSeek);

Untuk menentukan apakah file dapat dicari, panggil metode IMediaSeeking::CheckCapabilities atau metode IMediaSeeking::GetCapabilities . Metode ini melakukan hal yang hampir sama, tetapi semantiknya sedikit berbeda. Contoh berikut menggunakan CheckCapabilites:

// Determine if the source is seekable.
BOOL  bCanSeek = FALSE;
DWORD caps = AM_SEEKING_CanSeekAbsolute | AM_SEEKING_CanGetDuration; 
bCanSeek = (S_OK == pSeek->CheckCapabilities(&caps));
if (bCanSeek)
{
    // Enable the trackbar.
    EnableWindow(hScroll, TRUE);

    // Find the file duration.
    pSeek->GetDuration(&g_rtTotalTime);
}

Bendera AM_SEEKING_CanSeekAbsolute memeriksa apakah file sumber dapat dicari, dan bendera AM_SEEKING_CanGetDuration memeriksa apakah durasi file dapat ditentukan terlebih dahulu. Jika kedua kemampuan didukung, aplikasi mengaktifkan trackbar dan mengambil durasi file.

Jika grafik dapat dicari, aplikasi akan menggunakan timer untuk memperbarui posisi trackbar selama pemutaran. Saat Anda menjalankan grafik filter untuk memutar file, mulai peristiwa timer dengan memanggil salah satu fungsi timer Windows, seperti SetTimer. Untuk informasi selengkapnya tentang timer, lihat topik "Timer" di Platform SDK.

void StartPlayback(HWND hwnd) 
{
    pControl->Run();
    if (bCanSeek)
    {
        StopTimer(); // Make sure an old timer is not still active.
        nTimerID = SetTimer(hwnd, IDT_TIMER1, TICK_FREQ, (TIMERPROC)NULL);
        if (nTimerID == 0)
        {
            /* Handle Error */
        }
    }
}

void StopTimer() 
{
    if (wTimerID != 0)
    {
        KillTimer(g_hwnd, wTimerID);
        wTimerID = 0;
    }
}

Gunakan peristiwa timer untuk memperbarui posisi trackbar. Panggil IMediaSeeking::GetCurrentPosition untuk mengambil posisi pemutaran kismis, lalu hitung posisi sebagai persentase durasi file:

case WM_TIMER:
    if (wParam == IDT_TIMER1)
    {
        // Timer should not be running unless we really can seek.
        ASSERT(bCanSeek == TRUE);

        REFERENCE_TIME timeNow;
        if (SUCCEEDED(pSeek->GetCurrentPosition(&timeNow)))
        {
            long sliderTick = (long)((timeNow * 100) / g_rtTotalTime);
            SendMessage( hScroll, TBM_SETPOS, TRUE, sliderTick );
        }
    }
    break;

Pengguna juga dapat memindahkan trackbar untuk mencari file. Saat pengguna menyeret atau mengklik kontrol trackbar, aplikasi menerima peristiwa WM_HSCROLL. Kata rendah dari parameter wParam adalah pesan pemberitahuan trackbar. Misalnya, TB_ENDTRACK dikirim di akhir tindakan trackbar, dan TB_THUMBTRACK dikirim terus menerus saat pengguna menyeret trackbar. Kode berikut menunjukkan salah satu cara untuk menangani pesan WM_HSCROLL:

static OAFilterState state;
static BOOL bStartOfScroll = TRUE;

case WM_HSCROLL:
    short int userReq = LOWORD(wParam);
    if (userReq == TB_ENDTRACK || userReq == TB_THUMBTRACK)
    {
        DWORD dwPosition  = SendMessage(hTrackbar, TBM_GETPOS, 0, 0);
        // Pause when the scroll action begins.
        if (bStartOfScroll) 
        {
            pControl->GetState(10, &state);
            bStartOfScroll = FALSE;
            pControl->Pause();
        }
        // Update the position continuously.
        REFERENCE_TIME newTime = (g_rtTotalTime/100) * dwPosition;
        pSeek->SetPositions(&newTime, AM_SEEKING_AbsolutePositioning,
            NULL, AM_SEEKING_NoPositioning);

        // Restore the state at the end.
        if (userReq == TB_ENDTRACK)
        {
            if (state == State_Stopped)
                pControl->Stop();
            else if (state == State_Running) 
                pControl->Run();
            bStartOfScroll = TRUE;
        }
    }
}

Jika pengguna menyeret trackbar, aplikasi mengeluarkan serangkaian perintah pencarian, satu untuk setiap pesan TB_THUMBTRACK yang diterimanya. Untuk membuat operasi pencarian semulus mungkin, aplikasi menjeda grafik. Menjeda pemutaran grafik tetapi memastikan bahwa jendela video diperbarui. Ketika aplikasi menerima pesan TB_ENDTRACK, aplikasi memulihkan grafik ke keadaan semula.