使用 DirectShow 获取过滤器(com 设备)

get filters(com devices) using DirectShow

来自 code project 我得到了这段代码,但是 我不明白

此函数将在其类别之后获取所有过滤器(com 设备)并将其填充到 innerlist

谁能详细解释一下我搜索过的每个部分对我来说都是新的 我不明白什么是 ICreateDevEnumUCOMIEnumMonikerUCOMIMoniker 以及 我们如何使用它们获得过滤器

protected void getFilters(Guid category)
        {
            int                 hr;
            object              comObj = null;
            ICreateDevEnum      enumDev = null;
            UCOMIEnumMoniker    enumMon = null;
            UCOMIMoniker[]      mon = new UCOMIMoniker[1];

            try 
            {
                // Get the system device enumerator
                Type srvType = Type.GetTypeFromCLSID( Clsid.SystemDeviceEnum );
                if( srvType == null )
                    throw new NotImplementedException( "System Device Enumerator" );
                comObj = Activator.CreateInstance( srvType );
                enumDev = (ICreateDevEnum) comObj;

                // Create an enumerator to find filters in category
                hr = enumDev.CreateClassEnumerator( ref category, out enumMon, 0 );
                if( hr != 0 )
                    throw new NotSupportedException( "No devices of the category" );

                // Loop through the enumerator
                int f;
                do
                {
                    // Next filter
                    hr = enumMon.Next( 1, mon, out f );
                    if( (hr != 0) || (mon[0] == null) )
                        break;

                    // Add the filter
                    Filter filter = new Filter( mon[0] );
                    InnerList.Add( filter );

                    // Release resources
                    Marshal.ReleaseComObject( mon[0] );
                    mon[0] = null;
                }
                while(true);

                // Sort
                InnerList.Sort();
            }
            finally
            {
                enumDev = null;
                if( mon[0] != null )
                    Marshal.ReleaseComObject( mon[0] ); mon[0] = null;
                if( enumMon != null )
                    Marshal.ReleaseComObject( enumMon ); enumMon = null;
                if( comObj != null )
                    Marshal.ReleaseComObject( comObj ); comObj = null;
            }
        }

您在本机 API 上使用 [未记录] 托管包装器,但是 API 本身在 MSDN 上有详细记录,并且接口名称具有直接映射。

参见 Using the System Device Enumerator,其中描述了相关标识符。

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. 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. [...]