Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен на MediaPlayer, IMFMediaEngineи аудио- и видеозахват на платформе Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
Перечислитель системных устройств предоставляет универсальный способ перечисления по категориям фильтров, зарегистрированных в системе пользователя. Кроме того, он отличается от отдельных аппаратных устройств, даже если один и тот же фильтр поддерживает их. Это особенно полезно для устройств, использующих модель драйвера Windows (WDM) и фильтр KSProxy. Например, у пользователя может быть несколько устройств записи видео WDM, которые поддерживаются одинаковым фильтром. Перечислитель системных устройств обрабатывает их как отдельные экземпляры устройств.
Перечислитель системных устройств работает путем создания перечислителя для определенной категории, например захвата звука или сжатия видео. Перечислитель категорий возвращает уникальный моникер для каждого устройства в категории. Перечислитель категорий автоматически включает все соответствующие устройства Plug and Play в категорию. Список категорий см. в разделе Категории фильтров.
Чтобы использовать перечислитель системных устройств, сделайте следующее:
- Создайте перечислитель системного устройства путем вызова CoCreateInstance. Идентификатор класса (CLSID) CLSID_SystemDeviceEnum.
- Получите перечислитель категорий путем вызова ICreateDevEnum::CreateClassEnumerator с помощью CLSID требуемой категории. Этот метод возвращает указатель интерфейса IEnumMoniker. Если категория пуста (или не существует), метод возвращает S_FALSE вместо кода ошибки. В этом случае возвращенный указатель IEnumMoniker является NULL, и его разыменование вызовет исключение. Таким образом, явно проверяйте S_OK при вызове CreateClassEnumeratorвместо обычного вызова макроса SUCCEEDED.
- Используйте метод IEnumMoniker::Next для перечисления каждого моникера. Этот метод возвращает указатель интерфейса IMoniker. Когда метод Next достигает конца перечисления, он также возвращает S_FALSE, поэтому снова убедитесь в наличии S_OK.
- Чтобы получить понятное имя устройства (например, для отображения в пользовательском интерфейсе), вызовите метод IMoniker::BindToStorage.
- Чтобы создать и инициализировать фильтр DirectShow, который управляет устройством, вызовите IMoniker::BindToObject на моникере. Вызовите IFilterGraph::AddFilter, чтобы добавить фильтр в граф.
На следующей схеме показан этот процесс.
В следующем примере показано, как перечислить видеокомпрессоры, установленные в системе пользователя. Для краткости пример выполняет минимальную проверку ошибок.
// 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();
Моникеры устройств
Для обозначений устройств вы можете передать моникер в метод IFilterGraph2::AddSourceFilterForMoniker для создания захватного фильтра для устройства. Пример кода см. в документации по данному методу.
Метод IMoniker::GetDisplayName возвращает отображаемое имя моникера. Хотя отображаемое имя доступно для чтения, обычно оно не отображается для конечного пользователя. Получите понятное имя из контейнера свойств, как описано ранее.
Метод IMoniker::ParseDisplayName или функция MkParseDisplayName могут быть использованы для создания моникера устройства по умолчанию для заданной категории фильтров. Используйте отображаемое имя в формате @device:*:{category-clsid}, где category-clsid — это строковое представление GUID категории. Моникер по умолчанию — это первый моникер, возвращаемый перечислителем устройства для этой категории.