#include <shlwapi.h>
#pragma comment(lib,"shlwapi.lib")
#include <tchar.h>
//定义相关数据
#define DS_CATEGORIE_IDX 3
#define SAFE_RELEASE(x) { if(x) x->Release(); x = NULL; }
typedef struct _category_info
{
const CLSID *pclsid;
TCHAR szName[128];
}CATEGORY_INFO_DS;
const CATEGORY_INFO_DS categories[] = {
&CLSID_AudioInputDeviceCategory, TEXT("Audio Capture Devices/0"),
&CLSID_AudioCompressorCategory, TEXT("Audio Compressors/0"),
&CLSID_AudioRendererCategory, TEXT("Audio Renderers/0"),
&CLSID_LegacyAmFilterCategory, TEXT("DirectShow Filters/0"),
&CLSID_MidiRendererCategory, TEXT("Midi Renderers/0"),
&CLSID_VideoInputDeviceCategory, TEXT("Video Capture Devices/0"),
&CLSID_VideoCompressorCategory, TEXT("Video Compressors/0"),
};
//定义相关成员函数及成员变量
public:
CListCtrl m_listSystemFilter;
public:
BOOL GetDllPathForClsid(LPCTSTR lpClsid,LPTSTR pFile,DWORD dwLen);
STDMETHOD(EnumFilter)(IEnumMoniker *pEnumCat);
STDMETHOD(EnumFilter)(int ncatalogIdx);
public:
ICreateDevEnum *m_pSysDevEnum;
virtual BOOL OnInitDialog();
//实现部分BOOL CtestsystemfilterDlg::OnInitDialog()
{
CDialog::OnInitDialog();
m_listSystemFilter.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);
m_listSystemFilter.InsertColumn(0,TEXT("Name"),LVCFMT_LEFT,200);
m_listSystemFilter.InsertColumn(1,TEXT("CLSID"),LVCFMT_LEFT,360);
m_listSystemFilter.InsertColumn(2,TEXT("Path"),LVCFMT_LEFT,360);
this->EnumFilter(DS_CATEGORIE_IDX);
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
BOOL CtestsystemfilterDlg::GetDllPathForClsid(LPCTSTR lpClsid,LPTSTR pFile,DWORD dwLen)
{
TCHAR szSubKey[MAX_PATH] = TEXT("");
DWORD dwType = REG_SZ;
_sntprintf(szSubKey,sizeof(szSubKey),TEXT("CLSID//%s//InprocServer32"),lpClsid);
if(ERROR_SUCCESS == SHGetValue(HKEY_CLASSES_ROOT,szSubKey,TEXT(""),&dwType,pFile,&dwLen))
return TRUE;
return FALSE;
}
STDMETHODIMP CtestsystemfilterDlg::EnumFilter(int ncatalogIdx)
{
m_pSysDevEnum = NULL;
if(FAILED(CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_INPROC,__uuidof(ICreateDevEnum),(void**)&m_pSysDevEnum)))
return E_FAIL;
IEnumMoniker *pEnumCat = NULL;
const CLSID *pClsid = categories[ncatalogIdx].pclsid;
if(FAILED(m_pSysDevEnum->CreateClassEnumerator(*pClsid,&pEnumCat,0)))
return E_FAIL;
return EnumFilter(pEnumCat);
}
STDMETHODIMP CtestsystemfilterDlg::EnumFilter(IEnumMoniker *pEnumCat)
{
if(NULL == pEnumCat)
return E_FAIL;
HRESULT hr = E_FAIL;
int nListRow = 0;
IMoniker *pMoniker = NULL;
ULONG cFetched;
while(SUCCEEDED(pEnumCat->Next(1,&pMoniker,&cFetched)) && NULL != pMoniker)
{
IPropertyBag *pPropBag = NULL;
hr = pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pPropBag);
if(FAILED(hr)) continue;
VARIANT varName;
varName.vt = VT_BSTR;
hr = pPropBag->Read(L"FriendlyName",&varName,0);
if(FAILED(hr)) continue;
m_listSystemFilter.InsertItem(nListRow,varName.bstrVal);
VARIANT varClsid;
varClsid.vt = VT_BSTR;
hr = pPropBag->Read(L"CLSID",&varClsid,0);
if(SUCCEEDED(hr))
{
m_listSystemFilter.SetItemText(nListRow,1,varClsid.bstrVal);
TCHAR szFilePath[MAX_PATH] = TEXT("");
if(GetDllPathForClsid((LPTSTR)varClsid.bstrVal,szFilePath,MAX_PATH))
m_listSystemFilter.SetItemText(nListRow,2,szFilePath);
}
SAFE_RELEASE(pPropBag);
SAFE_RELEASE(pMoniker);
nListRow++;
}
SAFE_RELEASE(pEnumCat);
SAFE_RELEASE(m_pSysDevEnum);
return hr;
}
运行结果图: