[DirectShow] 枚举设备到Combo Box列表中 [大三TJB_708]

 

1 古人的话

古人说:知其然亦要知其所以然。其实到了自己来实践这一句话的时候是会感觉此话甚有几分道理的。首先知其然排在前面,是叫我们先学会应用;知其所以然是在知其然的前提下继续往对应模块(如果没有知其然,哪里知道的模块呢)的祖坟上刨,对每个模块的原理进行了解,便对对应模块的灵活应用可扩展。

像我这种人来读这句话的时候就会认为首先就要知其所以然。故而有的时候我把我自己也往往死胡同里面扔,还好从来都没有进过胡同里的垃圾桶,要不然早就被回收了,经过加工之后,我再也找不到曾经的朴实和憨厚,除非重新变成垃圾我才可能来领悟知其然和知其所以然的关系。而且对于下一步来讲,上一步有可能都是知其然。

 

所以,对于DirectShow视频预览这一块来说,我知道了具体是怎么回事么?我不知道。但是我知道怎么编排代码就能实现视频预览的功能么?是的,我知道,而且我大概已经对这整个流程划分了模块。所以能往每个模块上面刨刨,就刨泡吧。这样就算是第一个层次上面的真正懂了。

 

2 DirectShow系统设备枚举

2. 1 DirectShow枚举设备步骤

DirectShow视频预览中有一步是枚举系统设备,它的步骤为:

  • 用CoCreateInstance函数创建系统硬件设备列表,返回一个指向ICreateDevEnum接口的指针。
  • 通过ICreateDevEnum::CreateClassEnumerator方法创建特殊类型的系统设备列表,并返回一个指向IEnumMoniker接口的指针。
  • 用循环(while)通过IEnumMoniker::Next方法检索一个由上一步创建的设备,直到将所有的设备枚举完毕时,循环就结束,程序就将枚举到的设备拿来进行下一步操作(如将Filter绑定到此设备,然后进行视频预览)。

 

2. 2 DirectShow枚举设备函数

平台:VS2010

while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
	//如果枚举到了设备之后
	//就对此进行操作,比如将枚举到设备添加到Combo Box 里面呀等等
}


其中pEnumCat是IEnumMoniker类的指针对象。

IEnumMoniker::Next函数原型如下:

HRESULT Next(
  [in]       ULONG celt,
  [out]      IMoniker **rgelt,
  [in, out]  ULONG *pceltFetched
);

 

函数功能

此函数用来在指定列表中检索指定数目的设备。

参数

  • celt: 表示每次检测的系统设备的个数,一般将上面的代码中将其设置为1,表示每次从列表中检索一个视频设备。
  • rgelt:  IMoniker型的指针,含枚举到的设备信息,通过此指针调用IMoniker接口内的方法。
  • precltFetched: 表示检测到的目标设备的个数。

 

返回值

如果此函数检测到规定的设备的个数即celt个,则返回S_OK;否则返回S_FALSE

 

 

2.3 将枚举到的系统设备名称添加到Combo Box中

这个过程主要包含获取检索到的设备的设备名、然后通过Combo Box的成员函数将设备名添加到对应列表中。

对应代码

while(pEnumCat->Next(1, &pMoniker, &cFetched) == S_OK)
{
	IPropertyBag *pBag=0;
	hr	= pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
			
	if(FAILED(hr))
	{
		continue;
	}
			
	if(SUCCEEDED(hr))
	{
		VARIANT var;
		VariantInit(&var);
				
		if(FAILED(hr))
		{
			hr = pBag->Read(L"FriendlyName", &var, NULL); 
		}
		if(hr == NOERROR)
		{
			m_veideoSelect.AddString(var.bstrVal);
		}
	}
}


 

获取设备名

IEnumMoniker::Next获得一个设备名时就将此设备的信息(设备名捕捉到)。

其中pEnumCat是IMoniker类的指针对象。此处用IMoniker::BindToStorage方法的主要目的是返回一个IPropertyBag类的指针,通过此指针访问Read函数可以获得设备的名字。经过VARIANT var和VariantInit(&var)(具体含义可以查看MSDN的,我翻译的效果不会太好)语句后,然后通过pBag->Read(L"FriendlyName", &var, NULL);语句就能将设备名存到var.bstrVal中。

 

将设备名添加到Combo Box中

要达到此效果只需要一句:m_veideoSelect.AddString(var.bstrVal);

 

此次笔记记录完毕。

 

你可能感兴趣的:([DirectShow] 枚举设备到Combo Box列表中 [大三TJB_708])