Utilisation de l’énumérateur d’appareil système

L’énumérateur d’appareil système fournit un moyen uniforme d’énumérer, par catégorie, les filtres inscrits sur le système d’un utilisateur. En outre, il différencie les appareils matériels individuels, même si le même filtre les prend en charge. Cela est particulièrement utile pour les appareils qui utilisent le modèle de pilote Windows (WDM) et le filtre KSProxy. Par exemple, l’utilisateur peut avoir plusieurs appareils de capture vidéo WDM, tous pris en charge par le même filtre. L’énumérateur d’appareil système les traite comme des instances d’appareil distinctes.

L’énumérateur d’appareil système fonctionne en créant un énumérateur pour une catégorie spécifique, telle que la capture audio ou la compression vidéo. L’énumérateur de catégorie retourne un moniker unique pour chaque appareil de la catégorie. L’énumérateur de catégorie inclut automatiquement tous les appareils Plug-and-Play pertinents de la catégorie. Pour obtenir la liste des catégories, consultez Filtrer les catégories.

Pour utiliser l’énumérateur d’appareil système, procédez comme suit :

  1. Créez l’énumérateur d’appareil système en appelant CoCreateInstance. L’identificateur de classe (CLSID) est CLSID_SystemDeviceEnum.
  2. Obtenez un énumérateur de catégorie en appelant ICreateDevEnum::CreateClassEnumerator avec le CLSID de la catégorie souhaitée. Cette méthode retourne un pointeur d’interface IEnumMoniker . Si la catégorie est vide (ou n’existe pas), la méthode retourne S_FALSE plutôt qu’un code d’erreur. Si c’est le cas, le pointeur IEnumMoniker retourné est NULL et le déreferencing qu’il provoque une exception. Par conséquent, testez explicitement les S_OK lorsque vous appelez CreateClassEnumerator au lieu d’appeler la macro SUCCEEDED habituelle.
  3. Utilisez la méthode IEnumMoniker::Next pour énumérer chaque moniker. Cette méthode retourne un pointeur d’interface IMoniker . Lorsque la méthode Next atteint la fin de l’énumération, elle retourne également S_FALSE, donc vérifiez à nouveau S_OK.
  4. Pour récupérer le nom convivial de l’appareil (par exemple, pour l’afficher dans l’interface utilisateur), appelez la méthode IMoniker::BindToStorage .
  5. Pour créer et initialiser le filtre DirectShow qui gère l’appareil, appelez IMoniker::BindToObject sur le moniker. Appelez IFilterGraph::AddFilter pour ajouter le filtre au graphe.

Le diagramme suivant illustre ce processus.

enumerating devices

L’exemple suivant montre comment énumérer les compresseurs vidéo installés sur le système de l’utilisateur. Par souci de concision, l’exemple effectue une vérification d’erreur minimale.

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

Monikers d’appareil

Pour les monikers d’appareil, vous pouvez transmettre le moniker à la méthode IFilterGraph2::AddSourceFilterForMoniker pour créer un filtre de capture pour l’appareil. Pour obtenir un exemple de code, consultez la documentation de cette méthode.

La méthode IMoniker::GetDisplayName retourne le nom complet du moniker. Bien que le nom d’affichage soit lisible, vous ne l’afficheriez généralement pas à un utilisateur final. Obtenez plutôt le nom convivial du conteneur de propriétés, comme décrit précédemment.

La méthode IMoniker::P arseDisplayName ou la fonction MkParseDisplayName peut être utilisée pour créer un moniker d’appareil par défaut pour une catégorie de filtre donnée. Utilisez un nom complet avec le formulaire @device:*:{category-clsid}, où category-clsid est la représentation sous forme de chaîne du GUID de catégorie. Le moniker par défaut est le premier moniker retourné par l’énumérateur d’appareil pour cette catégorie.