1.使用CoCreateInstance函数创建系统枚举器组件对象,并获得ICreateDevEnum接口; 2.使用接口方法ICreateDevEnum::CreateClassEnumerator为指定的Filter注册类型目录创建一个枚举器,并获得 IEnumMoniker接口; 3.使用IEnumMoniker接口方法枚举指定类型目录下所有设备标识 4.调用IMoniker::BindToStorage之后,可以访问设备标识的属性集,比如得到Display Name,Friendly Name等; 5.调用IMoniker::BindToOject可以将设备标识生成一个DirectShow Filter,随后调用IFilterGraph::AddFilter, 并将之加入到FilterGraph中就可以参与工作了. 下面是实现这个过程的代码: //创建一个系统枚举组件 HRESULT hr; ICreateDevEnum *pSysDevEnum=NULL; hr=CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC_SERVER,IID_ICreateDevEnum,(void**)&pSysDevEnum); if(FAILED(hr)) { retuen hr; } //指定枚举的类型录,获得IEnumMoniker接口 IEnumMoniker *pEnumCat=NULL; hr=pSysDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,&pEnumCat,0); if(hr==S_OK) { //使用IEnumMoniker接口枚举所有的设备标识 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)) { //获得Filter的Friendly Name VARIANT varName; VariantInit(&varName); hr=pPropBag->Read(L"FriendlyName",&varName,0); if(SUCCEEDED(hr)) { } VariantClear(&varName); //创建Filter实例 IBaseFilter *pFilater; hr=pMoniker->BindToObject(NULL,NULL,IID_IBaseFilter,(void**)&pFilter); pPropBag->Release(); } pMoniker->Release(); } pEnumCat->Release(); } pSysDevEnum->Release();
知道了一个硬件的设备标识,我们也可以直接通过IFilterGraph2::AddSourceFilterForMoniker接口方法来 创建Filter,代码如下: LPOLESTR strName=NULL; IBaseFilter pSrc=NULL; hr=pMoniker->GetDisplayName(NULL,NULL,&strName); if(SUCCEEDED(hr)) { //获得IFilterGraph2接口 IFilterGraph2 *pFG2=NULL; hr=pGraph->QueryInterface(IID_IFilterGraph2,(void**)&pFG2); if(SUCCEEDED(hr)) { //根据设备标识创建一个Source Filter hr=pFG2->AddSourceFilterForMoniker(pMoniker,0,L"Source",&pSrc); pFG2->Release(); } CoTaskMemFree(strName); } 或者给定一个Filter类型目录的Display Name描述,创建一个该类型目录下第一个返回的设备标识对象. //视频采集设备的类型目录 WCHAR szMon[]=L"@device:*:{86DBB310-5D01-11D0-BD3B-00A0C911CE86}"; IBindCtx *pBindCtx; hr=CreateBindCtx(0,&pBindCtx); ULONG chEaten=0; IMoniker *pMoniker=0; hr=MkParseDisplayName(pBindCtx,szMon,&chEaten,&pMoniker); pBindCtx->Release(); if(SUCCEEDED(hr)) { pMoniker->Release(); }
|