DirectShow详解2-过滤器注册信息
有关过滤器注册信息的描述,在DirectShow帮助文档“DirectShow\使用DirectShow\编写DirectShow过滤器\DirectShow和COM\如何注册DirectShow过滤器\注册表项的布局”中。过滤器在两个位置注册:第1个位置HKEY_CLASSES_ROOT\CLSID\Filter CLSIDFilter CLSID是替代符号,实际应为过滤器GUID字符,如果过滤器是“Color Space Converter”过滤器,则为{1643E180-90F5-11CE-97D5-00AA0055595A},即CLSID_Colour的值。项具有1个子项“InprocServer32”,子项值数量为2,值名称分别为“”和“ThreadingModel”。序号值类型值名称值说明1REG_SZ空C:\Windows\SysWOW64\quartz.dll过滤器DLL文件路径2REG_SZThreadingModelBoth线程模式为Both过滤器的DLL文件被注册为过滤器的COM服务器。当应用程序调用CoCreateInstance创建过滤器时,Microsoft Windows COM库使用此注册表项来找到DLL的位置。可以使用读注册表项的方法获取这些注册信息。下面代码获取Color Space Converter过滤器DLL注册信息:CString text; HKEY hKey; LONG ret = RegOpenKeyEx(HKEY_CLASSES_ROOT, L"CLSID\\{1643E180-90F5-11CE-97D5-00AA0055595A}\\InprocServer32", 0, KEY_READ, hKey); //{1643E180-90F5-11CE-97D5-00AA0055595A}为CLSID_Colour(颜色空间转换过滤器GUID) if (ret != ERROR_SUCCESS) { MessageBox(L"打开注册表项失败"); return; } DWORD subkeys_count, max_subkey_len, values_count, max_value_name_len, max_value_len; ret = RegQueryInfoKey(hKey, NULL, NULL, NULL, subkeys_count, max_subkey_len, NULL, values_count, max_value_name_len, max_value_len, NULL, NULL); if (ret != ERROR_SUCCESS) { MessageBox(L"查询注册表项信息失败"); RegCloseKey(hKey); return; } for (DWORD i = 0; i values_count; i++)//根据值数量建立循环 { char* value_name = new char[max_value_name_len + 1]; DWORD value_name_len = max_value_name_len + 1; DWORD value_type, value_len; ret = RegEnumValueA(hKey, i, value_name, value_name_len, NULL, value_type, NULL, value_len);//第一次调用获取值的大小 BYTE* value = new BYTE[value_len]; value_name_len = max_value_name_len + 1; ret = RegEnumValueA(hKey, i, value_name, value_name_len, NULL, value_type, value, value_len);//第二次调用获取值 CString ValueStr, ss; switch (value_type) { case REG_SZ://以null结尾的Unicode字符串 ValueStr = (CString)value; break; } ss.Format(L"%s\t\t%u\t\t%s \r\n", (CString)value_name, value_type, ValueStr); text += ss; delete value_name; delete value; } jump: RegCloseKey(hKey); SetDlgItemText(IDC_EDIT1, text);结果:序号值名称值类型值说明1空1C:\Windows\SysWOW64\quartz.dll颜色空间转换过滤器执行文件的路径2ThreadingModel1Both线程模式第2个位置HKEY_CLASSES_ROOT\CLSID\Category\Instance\Filter CLSIDCategory是替代符号,实际应为过滤器类别GUID字符,如:{083863F1-70DE-11D0-BD40-00A0C911CE86}//CLSID_LegacyAmFilterCategory//DirectShow过滤器类别Filter CLSID是替代符号,实际应为过滤器GUID字符。如:{1643E180-90F5-11CE-97D5-00AA0055595A}//CLSID_Colour//颜色空间转换过滤器GUID项值数量为3;值名称分别为“CLSID”,“FilterData”和“FriendlyName”。如下表:序号值类型值名称值说明1REG_SZCLSID{1643E180-90F5-11CE-97D5-00AA0055595A}过滤器GUID字符串2REG_BINARYFilterData二进制数据过滤器信息(信息为二进制数据)3REG_SZFriendlyNameColor Space Converter过滤器名称字符串注册表项的值数据类型在Windows SDK文件winnt.h中定义:// Predefined Value Types.//预定义值类型#define REG_NONE ( 0 ) // No value type//没有值类型#define REG_SZ ( 1 ) // Unicode nul terminated string//以null结尾的Unicode字符串#define REG_EXPAND_SZ ( 2 ) // Unicode nul terminated string// (with environment variable references)//以null结尾的Unicode字符串(具有环境变量引用)#define REG_BINARY ( 3 ) // Free form binary//二进制数据#define REG_DWORD ( 4 ) // 32-bit number//32位数值#define REG_DWORD_LITTLE_ENDIAN ( 4 ) // 32-bit number (same as REG_DWORD)//32位数值(与REG_DWORD相同)#define REG_DWORD_BIG_ENDIAN ( 5 ) // 32-bit number//大端格式的32位数值#define REG_LINK ( 6 ) // Symbolic Link (unicode)//符号链接(unicode字符串)#define REG_MULTI_SZ ( 7 ) // Multiple Unicode strings//多个Unicode字符串#define REG_RESOURCE_LIST ( 8 ) // Resource list in the resource map//资源映射中的资源列表#define REG_FULL_RESOURCE_DESCRIPTOR ( 9 ) // Resource list in the hardware description//硬件描述中的资源列表#define REG_RESOURCE_REQUIREMENTS_LIST ( 10 )//资源要求列表#define REG_QWORD ( 11 ) // 64-bit number//64位的数值#define REG_QWORD_LITTLE_ENDIAN ( 11 ) // 64-bit number (same as REG_QWORD)//64位的数值(与REG_QWORD相同)这个位置是过滤器其他信息,在过滤器类别中注册。系统设备枚举器和过滤器映射器使用此信息。获取DirectShow过滤器类别下注册的过滤器列表CStringArray StringAry; HRESULT hr; ICreateDevEnum* pSysDevEnum = NULL; hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(pSysDevEnum));//创建系统设备枚举器 IEnumMoniker* pEnumCat; hr = pSysDevEnum-CreateClassEnumerator(CLSID_LegacyAmFilterCategory, pEnumCat, 0);//获取DirectShow过滤器类别的类枚举器 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 (hr == S_OK) { VARIANT var; VariantInit(var); pPropBag-Read(L"FriendlyName", var, 0);//读取过滤器名称 CString Name= var.bstrVal; VariantClear(var); VariantInit(var); pPropBag-Read(L"CLSID", var, 0);//读取过滤器GUID CString ClsidStr = var.bstrVal; ClsidStr.MakeUpper();//注册表中有些GUID字符没有使用大写,在这里转换为大写 VariantClear(var); /*VariantInit(var); pPropBag-Read(L"FilterData", var, 0);//读取过滤器二进制数据 VariantClear(var);*/