Listing the codecs intalled on the machine

Often an application requires to list all the Audio/Video compressors installed on the machine. We can achieve this
easily with
the ICreateDevEnum interface available from DirectShow. ICreateDevEnum exposes
a method named CreateClassEnumerator that allows us to create enumerators
for different categories of devices, such as audio/video codecs, Directx Media
Objects (DMO) etc.

The typical usage is as shown below:

      CComPtr<ICreateDevEnum> pSysDevEnum;
    if(FAILED(hr = pSysDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum)))
    {
        return hr;
    }
    
    IEnumMoniker *pEnum = NULL;
    hr = pSysDevEnum->CreateClassEnumerator(CLSID_VideoCompressorCategory, &pEnum, 0);
    if (hr == S_OK) 
    {
        // Use the pEnum to enumerate the devices
        ...    
        // Do not forget to release it when done.
        pEnum->Release();
    }    

The below code enumerates the Audio compressors available on the
machine and adds their friendly names to an application defined combo box.

 HRESULT CAudioConvertDlg::AddCompressorsToComboList(CString *pStrErrMsg)
{
    HRESULT hr = E_FAIL;

    this->m_ctrlCompressorsCombo.ResetContent();

    CComPtr<ICreateDevEnum> pCreateDevEnum;
    if(FAILED(hr = pCreateDevEnum.CoCreateInstance(CLSID_SystemDeviceEnum)))
    {
        *pStrErrMsg += "Unable to Create System Device Enumerator";   return hr;
    }
    
    CComPtr<IEnumMoniker> pEnumMoniker;
    if(FAILED(hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioCompressorCategory,&pEnumMoniker,0)))
    {
        *pStrErrMsg += "Unable to Create AudioCompressor Enumerator";  return hr;
    }
    
    CComPtr<IMoniker> pMoniker;
    while(pEnumMoniker->Next(1,&pMoniker,NULL) == S_OK)
    {
        CComPtr<IPropertyBag> pBag;    // Use the Moniker's PropertyBag to get the Object's name
        if(SUCCEEDED(pMoniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&pBag)))
        {
            VARIANT var;
            var.vt = VT_BSTR;
            if(SUCCEEDED(pBag->Read(L"FriendlyName",&var,NULL)))
            {
                TCHAR szName[512];
                GetTcharFromWchar(var.bstrVal,szName,sizeof(szName));
                SysFreeString(var.bstrVal);
                this->m_ctrlCompressorsCombo.AddString(szName);
            }
        }
        pMoniker.Release();
    }

    this->m_ctrlCompressorsCombo.SetCurSel(0);

    return hr = S_OK;   // Everything went fine !!
}