用户可以采用枚举的方式列举系统中安装的设备。
以列举系统中的视频捕捉设备为例,
(1) 首先定义一个设备列举接口 ICreateDevEnum的一个指针;
(2) 调用CoCreateInstance方法创建ICreateDevEnum实例。
(3) 然后定义一个列举监视器 IEnumMoniker的一个指针;
(4) 调用ICreateDevEnum实例的CreateClassEnumerator方法创建 IEnumMoniker实例。
(5) 最后以循环的方式调用IEnumMoniker实例的Next方法遍历系统设备;
(6) 调用IEnumMoniker实例的 BindToObject方法将系统设备绑定到过滤器上。
在上面的描述中,ICreateDevEnum实例的CreateClassEnumerator方法的第一个参数确定枚举的系统设备。例如,第一个参数为CLSID_VideoInputDeviceCategory,表示将要枚举系统中的视频捕捉卡,为 CLSID_VideoCompressorCategory,表示枚举系统中的视频压缩器。
下面的代码演示了如何枚举系统中的视频捕捉卡。
//枚举视频设备;值= CLSID_VideoInputDeviceCategory
// 音频设备的值= CLSID_ AudioInputDeviceCategory;
ICreateDevEnum *pDevEnum = NULL;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
IEnumMoniker *pClassEnum = NULL;
pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pClassEnum, 0);
ULONG cFetched;
while (pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK)
{
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pSrc);
pMoniker->Release();
break;
}
pClassEnum->Release();
而下面的代码则用于判断系统中是否安装了指定的视频压缩器。
ICreateDevEnum *pDevEnum = NULL;
CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
IID_ICreateDevEnum, (void **)&pDevEnum);
IEnumMoniker *pClassEnum = NULL;
//列举视频压缩设备;值=CLSID_VideoCompressorCategory
pDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pClassEnum, 0);
while (pClassEnum->Next(1, &pMoniker, &cFetched) == S_OK)
{
IPropertyBag* pProp= NULL;
pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pProp);
VARIANT varName;
varName.vt = VT_BSTR;
pProp->Read(L"FriendlyName", &varName,0);
CString str = varName.bstrVal;
if (str.Find("Microsoft Video 1",0)!= -1)
{
pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pCompress);
pMoniker->Release();
break;
}
VariantClear(&varName);
}
pClassEnum->Release();
4) 查找Filter Pin过滤器引脚
每一个过滤器(Filter)至少应有一个引脚(Pin),或者是输入引脚或者是输出引脚。有些过滤器还拥有多个引脚,即又输入引脚又有输出引脚。但是过滤器的输入、输出引脚并不是对应的,有些过滤器可以有多个输入引脚,而只有一个输出引脚或者没有输出引脚。在程序中为了连接过滤器间的引脚,通常需要获得过滤器的各个引脚。
用户可以使用IEnumPins接口来枚举某一个过滤器的输入、输出引脚。过滤器 IBaseFilter提供了一个EnumPins方法用于生成一个IEnumPins接口实例,这样,通过调用IEnumPins的Next方法便可以访问各个引脚了。
下面的代码定义了一个FindPin函数,用于获得某个过滤器的输入或输出引脚。
//查找引脚
IPin* CKinescopeDlg::FindPin(IBaseFilter *pFilter, PIN_DIRECTION dir)
{
IEnumPins* pEnumPins;
IPin* pOutpin;
PIN_DIRECTION pDir;
pFilter->EnumPins(&pEnumPins);
while (pEnumPins->Next(1,&pOutpin,NULL)==S_OK)
{
pOutpin->QueryDirection(&pDir);
if (pDir==dir) {return pOutpin;}
}
return 0;
}
用户可以按下面的方式获得某个过滤器的输入、输出引脚。
IPin * pComOut,*pComIn ;
pComIn = FindPin(pCompress,PINDIR_INPUT);
pComOut = FindPin(pCompress,PINDIR_OUTPUT);
5) 连接Filter Pin过滤器引脚
使用Graph Edit工具,用户可以利用鼠标非常方便地连接两个过滤器间的引脚。但是在程序中却没这么简单了。首先需要按照上面介绍的方法获得两个过滤器的输入、输出引脚,然后将第一个过滤器的输出引脚连接到第二个过滤器的输入引脚,其中,连接两个引脚需要调用IGraphBuilder接口的 ConnectDirect方法。
下面的代码演示了如何连接两个过滤器的引脚。
IPin * pComOut,*pComIn ;
pComIn = FindPin(pCompress,PINDIR_INPUT);
pComOut = FindPin(pCompress,PINDIR_OUTPUT);
IPin* pOutpin = FindPin(pSrc,PINDIR_OUTPUT); //pSrc的输出引脚
HRESULT result ;
result = pGraph->ConnectDirect(pOutpin,pComIn,NULL);