您的位置:首页 > 其它

[DirectShow] 036 - Using the System Device Enumerator

2009-08-18 20:53 253 查看
The System Device Enumerator provides a uniform way to enumerate, by
category, the filters registered on a user's system. Moreover, it
differentiates between individual hardware devices, even if the same filter
supports them. This is particularly useful for devices that use the Windows
Driver Model (WDM) and the KSProxy filter. For example, the user might have
several WDM video capture devices, all supported by the same filter. The System
Device Enumerator treats them as separate device instances.

系统设备枚举器提供统一的方法通过注册在用户系统中的类别来枚举,而且能区别单个硬件设备,即使同一个
filter
支持他们。对于使用
WDM

KSProxy filter
的设备来说这一点特别有用。例如,用户可以有多个被同一个
filter
的支持的
WDM
视频采集设备。设备枚举器把他们当作单独的设备实例看待。

The System Device Enumerator works by creating an enumerator for a
specific category, such as audio capture or video compression. The category
enumerator returns a unique moniker for each device in the category. The
category enumerator automatically includes any relevant Plug and Play devices
in the category. For a list of categories, see
Filter Categories

.

设备枚举器为指定的类别创建一个枚举器,例如音频采集或者视频压缩。类别枚举器为每一个设备返回一个唯一的名字。枚举器自动包含类别中的一些即插即用设备。

To use the System Device Enumerator, do the following:

要使用系统设备枚举器,按一下步骤:

1.

Create the system device enumerator by calling CoCreateInstance
.
The class identifier (CLSID) is CLSID_SystemDeviceEnum.

2.

调用
CoCreateInstance
创建系统设备枚举器。
CLSID

CLSID_SystemDeviceEnum


3.

Obtain a category enumerator by calling
ICreateDevEnum::CreateClassEnumerator


with the CLSID of the desired category. This method returns an IEnumMoniker
interface pointer. If the category is empty (or does not exist), the method
returns S_FALSE rather than an error code. If so, the returned IEnumMoniker
pointer
is NULL and dereferencing it will cause an exception. Therefore, explicitly
test for S_OK when you call CreateClassEnumerator
, instead of calling
the usual SUCCEEDED
macro.

4.

调用
ICreateDevEnum::CreateClassEnumerator
获得一个类别枚举器。这个方法返回一个
IEnumMoniker
接口指针。如果类别是空的或者不存在,这个方法就返回
S_FALSE
而不是错误码。假如返回的
IEnumMoniker
指针是空的话,废除它将产生一个异常。因此,当调用
CreateClassEnumerator
的时候明确的测试
S_OK
,通常使用
SUCCEEDED

宏。


5.

Use the IEnumMoniker::Next
method to enumerate each moniker. This
method returns an IMoniker
interface pointer. When the Next
method reaches the end of the enumeration, it also returns S_FALSE, so again
check for S_OK.

6.

使用
IEnumMoniker::Next
方法来枚举每一个名字。这个方法返回一个
IMoniker
接口指针。当
Next
到达末尾,就会返回
S_FALSE
,所以也要检查
S_OK.

7.

To retrieve the friendly name of the device (for example, to display in
the user interface), call the IMoniker::BindToStorage
method.

8.

要获得设备的友名,调用
IMoniker::BindToStorage
方法。

9.

To create and initialize the DirectShow filter that manages the device,
call IMoniker::BindToObject
on the moniker. Call
IFilterGraph::AddFilter


to add the filter to the graph.

10.

创建并初始化一个
DirectShow filter
,用来管理设备,在别名上上调用
IMoniker::BindToObject
。调用
IFilterGraph::AddFilter
把这个
filter
添加到
graph
中。

The following diagram illustrates this process.

下面的插图演示这个过程:



The following example shows how to enumerate the video compressors
installed on the user's system. For brevity, the example performs minimal error
checking.

接下来的例子显示如何枚举一个安装在用户系统中的视频压缩器。例子只进行了最少的错误检查。

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


Device Monikers


For device monikers, you can pass the moniker to the IFilterGraph2::AddSourceFilterForMoniker

method to create a capture filter for the device. For example code, see the
documentation for that method.

你可以传递别名给
IFilterGraph2::AddSourceFilterForMoniker
函数来为设备创建一个采集
filter


The IMoniker::GetDisplayName
method returns the display
name of the moniker. Although the display name is readable, you would not
typically display it to an end-user. Get the friendly name from the property bag
instead, as described previously.

IMoniker::GetDisplayName
方法返回别名的显示名称。尽管显示名称是易读的,你也不愿把他显示到终端。

从属性包中获得友名来代替显示名称。

The IMoniker::ParseDisplayName
method or the MkParseDisplayName
function can be used to create a default device moniker for a given filter
category. Use a display name with the form
@device:*:{category-clsid}

, where
category-clsid

is the string
representation of the category GUID. The default moniker is the first moniker
returned by the device enumerator for that category.

IMoniker::ParseDisplayName
方法或者
MKParseDisplayName
方法可以被用来为给定
filter
类别创建默认的设备别名。使用
@device:*:{category-clsid}结构作为显示名。
category-clsid代表类别
GUID
。默认别名是设备枚举器返回的第一个别名。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐