Menggunakan Enumerator Perangkat Sistem

[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.]

Enumerator Perangkat Sistem menyediakan cara yang seragam untuk menghitung, berdasarkan kategori, filter yang terdaftar pada sistem pengguna. Selain itu, ini membedakan antara perangkat keras individual, bahkan jika filter yang sama mendukungnya. Ini sangat berguna untuk perangkat yang menggunakan Windows Driver Model (WDM) dan filter KSProxy. Misalnya, pengguna mungkin memiliki beberapa perangkat pengambilan video WDM, semuanya didukung oleh filter yang sama. Enumerator Perangkat Sistem memperlakukannya sebagai instans perangkat terpisah.

Enumerator Perangkat Sistem bekerja dengan membuat enumerator untuk kategori tertentu, seperti pengambilan audio atau kompresi video. Enumerator kategori mengembalikan moniker unik untuk setiap perangkat dalam kategori. Enumerator kategori secara otomatis mencakup perangkat Plug and Play yang relevan dalam kategori. Untuk daftar kategori, lihat Kategori Filter.

Untuk menggunakan Enumerator Perangkat Sistem, lakukan hal berikut:

  1. Buat enumerator perangkat sistem dengan memanggil CoCreateInstance. Pengidentifikasi kelas (CLSID) CLSID_SystemDeviceEnum.
  2. Dapatkan enumerator kategori dengan memanggil ICreateDevEnum::CreateClassEnumerator dengan CLSID dari kategori yang diinginkan. Metode ini mengembalikan penunjuk antarmuka IEnumMoniker . Jika kategori kosong (atau tidak ada), metode mengembalikan S_FALSE daripada kode kesalahan. Jika demikian, penunjuk IEnumMoniker yang dikembalikan adalah NULL dan mendereferensikannya akan menyebabkan pengecualian. Oleh karena itu, uji secara eksplisit untuk S_OK ketika Anda memanggil CreateClassEnumerator, alih-alih memanggil makro BERHASIL yang biasa.
  3. Gunakan metode IEnumMoniker::Next untuk menghitung setiap moniker. Metode ini mengembalikan penunjuk antarmuka IMoniker . Ketika metode Berikutnya mencapai akhir enumerasi, metode tersebut juga mengembalikan S_FALSE, jadi sekali lagi periksa S_OK.
  4. Untuk mengambil nama perangkat yang mudah diingat (misalnya, untuk ditampilkan di antarmuka pengguna), panggil metode IMoniker::BindToStorage .
  5. Untuk membuat dan menginisialisasi filter DirectShow yang mengelola perangkat, panggil IMoniker::BindToObject di moniker. Panggil IFilterGraph::AddFilter untuk menambahkan filter ke grafik.

Diagram berikut mengilustrasikan hubungan ini.

menghitung perangkat

Contoh berikut menunjukkan cara menghitung kompresor video yang diinstal pada sistem pengguna. Untuk keringkasan, contohnya melakukan pemeriksaan kesalahan minimal.

// Create the System Device Enumerator.
HRESULT hr;
ICreateDevEnum *pSysDevEnum = NULL;
hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
    IID_ICreateDevEnum, (void **)&pSysDevEnum);
if (FAILED(hr))
{
    return hr;
}

// Obtain a class enumerator for the video compressor category.
IEnumMoniker *pEnumCat = NULL;
hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);

if (hr == S_OK) 
{
    // Enumerate the monikers.
    IMoniker *pMoniker = NULL;
    ULONG cFetched;
    while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
    {
        IPropertyBag *pPropBag;
        hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, 
            (void **)&pPropBag);
        if (SUCCEEDED(hr))
        {
            // To retrieve the filter's friendly name, do the following:
            VARIANT varName;
            VariantInit(&varName);
            hr = pPropBag->Read(L"FriendlyName", &varName, 0);
            if (SUCCEEDED(hr))
            {
                // Display the name in your UI somehow.
            }
            VariantClear(&varName);

            // To create an instance of the filter, do the following:
            IBaseFilter *pFilter;
            hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
                (void**)&pFilter);
            // Now add the filter to the graph. 
            //Remember to release pFilter later.
            pPropBag->Release();
        }
        pMoniker->Release();
    }
    pEnumCat->Release();
}
pSysDevEnum->Release();

Moniker Perangkat

Untuk moniker perangkat, Anda dapat meneruskan moniker ke metode IFilterGraph2::AddSourceFilterForMoniker untuk membuat filter pengambilan untuk perangkat. Misalnya kode, lihat dokumentasi untuk metode tersebut.

Metode IMoniker::GetDisplayName mengembalikan nama tampilan moniker. Meskipun nama tampilan dapat dibaca, Anda biasanya tidak akan menampilkannya kepada pengguna akhir. Dapatkan nama yang mudah diingat dari tas properti sebagai gantinya, seperti yang dijelaskan sebelumnya.

Metode IMoniker::P arseDisplayName atau fungsi MkParseDisplayName dapat digunakan untuk membuat moniker perangkat default untuk kategori filter tertentu. Gunakan nama tampilan dengan formulir @device:*:{category-clsid}, di mana category-clsid adalah representasi string dari KATEGORI GUID. Moniker default adalah moniker pertama yang dikembalikan oleh enumerator perangkat untuk kategori tersebut.