Delen via


De Enumerator van het systeemapparaat gebruiken

[De functie die is gekoppeld aan deze pagina, DirectShow, is een verouderde functie. Het is vervangen door MediaPlayer, IMFMediaEngineen Audio/Video Capture in Media Foundation. Deze functies zijn geoptimaliseerd voor Windows 10 en Windows 11. Microsoft raadt ten zeerste aan om nieuwe code te gebruiken MediaPlayer, IMFMediaEngine en Audio/Video Capture in Media Foundation in plaats van DirectShow, indien mogelijk. Microsoft stelt voor dat bestaande code die gebruikmaakt van de verouderde API's, indien mogelijk opnieuw worden geschreven om de nieuwe API's te gebruiken.]

De System Device Enumerator biedt een uniforme manier om de filters op categorie op te sommen die zijn geregistreerd op het systeem van een gebruiker. Bovendien maakt het onderscheid tussen afzonderlijke hardwareapparaten, zelfs als hetzelfde filter deze ondersteunt. Dit is met name handig voor apparaten die gebruikmaken van het Windows Driver Model (WDM) en het KSProxy-filter. De gebruiker kan bijvoorbeeld verschillende WDM-videoopnameapparaten hebben, die allemaal worden ondersteund door hetzelfde filter. De Enumerator van het systeemapparaat behandelt deze als afzonderlijke apparaatexemplaren.

De Enumerator van het systeemapparaat werkt door een enumerator te maken voor een specifieke categorie, zoals audioopname of videocompressie. De categorie-enumerator retourneert een unieke moniker voor elk apparaat in de categorie. De categorie-opsommingsfunctie bevat automatisch alle relevante Plug en Play-apparaten in de categorie. Zie Filtercategorieënvoor een lijst met categorieën.

Gebruik de volgende stappen om de systeemapparaatenumerator te gebruiken:

  1. Maak de enumerator van het systeemapparaat door CoCreateInstance-aan te roepen. De klasse-id (CLSID) is CLSID_SystemDeviceEnum.
  2. Haal een categorie-enumerator op door ICreateDevEnum::CreateClassEnumerator aan te roepen met de CLSID van de gewenste categorie. Deze methode retourneert een IEnumMoniker interfaceaanwijzer. Als de categorie leeg is (of niet bestaat), retourneert de methode S_FALSE in plaats van een foutcode. Als dat het geval is, is de geretourneerde IEnumMoniker- pointer NULL- en derefereren ervan zal een uitzondering veroorzaken. Test daarom expliciet op S_OK wanneer u CreateClassEnumeratoraanroept, in plaats van de gebruikelijke macro SUCCEEDED te gebruiken.
  3. Gebruik de methode IEnumMoniker::Next om elke moniker te inventariseren. Met deze methode wordt een IMoniker- interfaceaanwijzer geretourneerd. Wanneer de methode Next het einde van de opsomming bereikt, wordt ook S_FALSE geretourneerd, dus controleer opnieuw op S_OK.
  4. Als u de beschrijvende naam van het apparaat wilt ophalen (bijvoorbeeld om weer te geven in de gebruikersinterface), roept u de methode IMoniker::BindToStorage aan.
  5. Als u het DirectShow-filter wilt maken en initialiseren dat het apparaat beheert, roept u IMoniker::BindToObject aan op de moniker. Roep IFilterGraph::AddFilter aan om het filter toe te voegen aan de grafiek.

In het volgende diagram ziet u dit proces.

apparaten enumereren

In het volgende voorbeeld ziet u hoe u de video compressoren opsommen die op het systeem van de gebruiker zijn geïnstalleerd. Ter beknoptheid voert het voorbeeld minimale foutcontrole uit.

// 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();

Apparaat monikers

Voor apparaatmonikers kunt u de moniker doorgeven aan de methode IFilterGraph2::AddSourceFilterForMoniker om een opnamefilter voor het apparaat te maken. Zie de documentatie voor die methode, bijvoorbeeld, voor een codevoorbeeld.

De methode IMoniker::GetDisplayName retourneert de weergavenaam van de moniker. Hoewel de weergavenaam leesbaar is, zou u deze doorgaans niet weergeven aan een eindgebruiker. Haal in plaats daarvan de vriendelijke naam uit de eigenschappenverzameling, zoals eerder beschreven.

De methode IMoniker::ParseDisplayName of de functie MkParseDisplayName kan worden gebruikt om een standaardapparaat-aanduiding te maken voor een bepaalde filtercategorie. Gebruik een weergavenaam met het formulier @device:*:{category-clsid}, waarbij category-clsid de tekenreeksweergave van de categorie-GUID is. De standaard moniker is de eerste moniker die door de apparaat-enumerator voor die categorie wordt geretourneerd.