zoukankan      html  css  js  c++  java
  • 如何使用系统设备枚举器 分类: DirectX 2013-11-15 16:03 707人阅读 评论(0) 收藏

    系统设备枚举器为我们按类型枚举已注册在系统中的Fitler提供了统一的方法。而且它能够区分不同的硬件设备,即便是同一个Filter支持它们。这对那些使用Windows驱动模型和KSProxy Filter的设备来说是非常有用的。系统设备枚举器对它们按不同的设备实例进行对待(译注:虽然它们支持相同Filter)。
      当我们利用系统设备枚举器查询设备的时候,系统设备枚举器为特定类型的设备(如,音频捕获和视频压缩)生成了一张枚举表(Enumerator)。类型枚举器(Category enumerator)为每个这种类型的设备返回一个Moniker,类型枚举器自动把每一种即插即用的设备包含在内。
      按如下的步骤使用系统设备枚举器:
      1. 调用方法CoCreateInstance生成系统设备枚举器。类标识(CLSID)为CLSID_SystemDeviceEnum。
      2. 调用ICreateDevEnum::CreateClassEnumerator方法生成类型枚举器,参数为你想要得到的类型的CLSID,该方法返回一个IEnumMoniker接口指针,如果指定的类型(是空的)或不存在,函数ICreateDevEnum::CreateClassEnumerator将返回S_FALSE而不是错误代码,同时IEnumMoniker指针(译注:通过参数返回)也是空的,这就要求我们在调用CreateClassEnumerator的时候明确用S_OK进行比较而不是使用宏SUCCEEDED。
      3. 使用IEnumMoniker::Next方法依次得到IEnumMoniker指针中的每个moniker。该方法返回一个IMoniker接口指针。当Next到达枚举的底部,它的返回值仍然是S_FALSE,这里我们仍需要用S_OK来进行检验。
      4. 想要得到该设备较为友好的名称(例如想要在用户界面中进行显示),调用IMoniker::BindToStorage方法。
      5. 如果想要生成并初始化管理该设备的Filter调用3返回指针的IMonitor::BindToObject方法,接下来调用IFilterGraph::AddFilter把该Filter添加到视图中。
      下图说明了上述步骤:
      下面的代码示例了如何枚举用户系统中的视频压缩器,为了简化,只给出了很少的错误检查。
      
      //生成系统设备枚举器.
      HRESULT hr;
      ICreateDevEnum *pSysDevEnum = NULL;
      hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
       IID_ICreateDevEnum, (void **)&pSysDevEnum);
      if (FAILED(hr))
      {
       return hr;
      }
      // 获得视频压缩的类枚举器(Class enumerator).
      IEnumMoniker *pEnumCat = NULL;
      hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnumCat, 0);
      if (hr == S_OK)
      {
       // 枚举其中的 moniker.
       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的友好名称:
       VARIANT varName;
       VariantInit(&varName);
       hr = pPropBag->Read(L"FriendlyName", &varName, 0);
       if (SUCCEEDED(hr))
       {
       //在你的用户界面上面显示.
       }
       VariantClear(&varName);
       // 如下,生成该filter的实例:
       IBaseFilter *pFilter;
       hr = pMoniker->BindToObject(NULL, NULL, IID_IBaseFilter,
       (void**)&pFilter);
       //将Filter加入到Graph.
       //后面必须记得释放pFilter.
       pPropBag->Release();
       }
       pMoniker->Release();
       }
       pEnumCat->Release();
      }
      pSysDevEnum->Release();
      
      设备Moniker
      IMoniker::GetDisplayName方法返回moniker的名字。你可以把这个名字传递给IFilterGraph2::AddSourceFilterForMoniker,这样可以生成该设备的捕获Filter。
      
      LPOLESTR strName = NULL;
      IBaseFilter pSrc = NULL;
      hr = pMoniker->GetDisplayName(NULL, NULL, &strName);
      if (SUCCEEDED(hr))
      {
       // 得到IFilterGraph2的Filter Graph Manager.
       IFilterGraph2 *pFG2 = NULL;
       hr = pGraph->QueryInterface(IID_IFilterGraph2, (void**)&pFG2);
       if (SUCCEEDED(hr))
       {
       hr = pFG2->AddSourceFilterForMoniker(pMoniker, 0, L"Source", &pSrc);
       pFG2->Release();
       }
       CoTaskMemFree(strName);
      }
      // 如果成功,记得释放pSrc.
      
      虽然,用上述方法得到的名字也有较好的可读性,但是我们一般不把它显示给用户,如前面所示,我们一般用从IPropertyBag得到的名字。
      方法IMoniker::ParseDisplayName和MkParseDisplayName可以用来生成指定filter类型的设备的moniker。名字以“@device:*:{category-clsid}”,代表了类型的GUID,默认的moniker是设备枚举器中的第一个moniker。
      
      //视频捕获类型
      WCHAR szMon[] = L"@device:*:{860BB310-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))
      {
       // 得到名字或绑定至DirectShow Filter.
       pMoniker->Release();
      }

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    CodeForces 7B
    CodeForces 4D
    离散化
    线段树入门
    洛谷 P3951 小凯的疑惑(赛瓦维斯特定理)
    Codeforces 1295D Same GCDs (欧拉函数)
    Codeforces 1295C Obtain The String (二分)
    Codeforces 1295B Infinite Prefixes
    Codeforces 1295A Display The Number(思维)
    Codeforces 1294F Three Paths on a Tree(树的直径,思维)
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706718.html
Copyright © 2011-2022 走看看