c++ - 如何在未注册的过滤器上使用属性页?

标签 c++ winapi com directshow multimedia

我使用过滤器 DS LAME 来压缩音频。我从文件“lame.ax”加载它如下:

// pPath - path to LAME "lame.ax"
HRESULT CMyFilter::CreateObjectFromPath(wchar_t *pPath, REFCLSID clsid, IUnknown **ppUnk)
{
    // load the target DLL directly
    if (!m_hLibFilter) m_hLibFilter = LoadLibrary(pPath);
    if (!m_hLibFilter)
    {
        return HRESULT_FROM_WIN32(GetLastError());
    }

    // the entry point is an exported function
    FN_DLLGETCLASSOBJECT fn = (FN_DLLGETCLASSOBJECT)GetProcAddress(m_hLibFilter, "DllGetClassObject");
    if (fn == NULL)
    {
        return HRESULT_FROM_WIN32(GetLastError());
    }

    // create a class factory
    IUnknownPtr pUnk;
    HRESULT hr = fn(clsid, IID_IUnknown, (void**)(IUnknown**)&pUnk);
    if (SUCCEEDED(hr))
    {
        IClassFactoryPtr pCF = pUnk;
        if (pCF == NULL)
        {
            hr = E_NOINTERFACE;
        }
        else
        {
            // ask the class factory to create the object
            hr = pCF->CreateInstance(NULL, IID_IUnknown, (void**)ppUnk);
        }
    }
    return hr;
}

进一步

HRESULT hr = 0;
IUnknown *ppUnk = 0;
ULONG lRef = 0;    
hr = CreateObjectFromPath(L"lame.ax", CLSID_LAMEDShowFilter, (IUnknown **)&ppUnk);
hr = ppUnk->QueryInterface(&m_pFilter);
lRef = ppUnk->Release();

它工作得很好。 LAME 编码音频。

我想显示过滤器设置-属性页,但是这段代码失败了

bool ShowConfigWindow(HWND hParent)
{
    ISpecifyPropertyPages *pProp;
    HRESULT hr = m_pFilter->QueryInterface(IID_ISpecifyPropertyPages, (void **)&pProp);
    if (SUCCEEDED(hr))
    {
        // Get the filter's name and IUnknown pointer.
        FILTER_INFO FilterInfo;
        hr = m_pFilter->QueryFilterInfo(&FilterInfo);
        IUnknown *pFilterUnk;
        m_pFilter->QueryInterface(IID_IUnknown, (void **)&pFilterUnk);

        // Show the page. 
        CAUUID caGUID;
        pProp->GetPages(&caGUID);
        pProp->Release();
        HRESULT hr = OleCreatePropertyFrame(
            hParent,                   // Parent window
            0, 0,                   // Reserved
            FilterInfo.achName,     // Caption for the dialog box
            1,                      // Number of objects (just the filter)
            &pFilterUnk,            // Array of object pointers. 
            caGUID.cElems,          // Number of property pages
            caGUID.pElems,          // Array of property page CLSIDs
            0,                      // Locale identifier
            0, NULL                 // Reserved
        );

        // Clean up.
        pFilterUnk->Release();
        FilterInfo.pGraph->Release();
        CoTaskMemFree(caGUID.pElems);
    }
    return true;
}

我找到了 https://groups.google.com/forum/#!topic/microsoft.public.win32.programmer.directx.video/jknSbMenWeM

我应该为每个属性页调用 CoRegisterClassObject,但该怎么做呢? 或者什么是正确的方法?

最佳答案

OleCreatePropertyFrame 采用属性页类标识符 (CLSID),因此您需要找到一种方法让它们对 API“可见”。

CoRegisterClassObject 的使用是实现上述任务的方法之一(也许是最简单的方法,另一种方法是无注册 COM)。您需要像在第一个片段中那样检索属性页 CLSID 的 IClassFactory 指针。然后不调用 IClassFactory::CreateInstance,而是使用接口(interface)指针作为 CoRegisterClassObject API 的参数。确保您在与以下 OleCreatePropertyFrame 调用相同的线程上执行此操作。 CoRevokeClassObject 将在之后进行清理。

关于c++ - 如何在未注册的过滤器上使用属性页?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39467914/

相关文章:

c++ - 运行可执行文件 (libcurl) 时缺少 dll

c - 带有 TreeView 和面板内存对话框的首选项对话框

c++ - 尝试创建计划任务以在 win7 上使用 C++、Task Scheduler 1.0 运行一次

c# - 从 C# COM 方法返回对象和内存所有权

com - 运行时的 "Method ' ~' of object ' ~' failed"是什么意思?

c++ - Fortran 中 REAL(KIND=real_normal) 的 C 等效类型是什么?

c++ - 装饰器模式 - 我如何在初始化时不调用复制构造函数?

delphi - 将 WinAPI 回调封装在类中的最优雅的方法

c# - 在 VS 2015 扩展中,如何在解决方案资源管理器中获取选定的对象?

c++ - 获取和设置相机设置