从外部进程加载图形

[与此页面关联的功能 DirectShow 是旧版功能。 它已被 MediaPlayerIMFMediaEngineMedia Foundation 中的音频/视频捕获所取代。 这些功能已针对Windows 10和Windows 11进行了优化。 Microsoft 强烈建议新代码尽可能在 Media Foundation 中使用 MediaPlayerIMFMediaEngine音频/视频捕获 ,而不是 DirectShow。 如果可能,Microsoft 建议重写使用旧 API 的现有代码以使用新 API。]

GraphEdit 可以加载由外部进程创建的筛选器图。 使用此功能,可以确切地查看应用程序生成的筛选器图,只需应用程序中少量的其他代码。

注意

此功能需要 Windows 2000、Windows XP 或更高版本。

 

注意

从 Windows Vista 开始,必须注册proppage.dll才能启用此功能。 Proppage.dll包含在 Windows SDK 中。

 

应用程序必须在 Running Object Table (ROT) 中注册筛选器图实例。 ROT 是一个全局可访问的查找表,用于跟踪正在运行的对象。 对象通过名字对象在 ROT 中注册。 若要连接到图形,GraphEdit 在 ROT 中搜索显示名称与特定格式匹配的名称:

!FilterGraph X pid Y

其中 X 是 Filter Graph Manager 的十六进制地址, Y 是进程 ID,也以十六进制表示。

应用程序首次创建筛选器图时,请调用以下函数:

HRESULT AddToRot(IUnknown *pUnkGraph, DWORD *pdwRegister) 
{
    IMoniker * pMoniker = NULL;
    IRunningObjectTable *pROT = NULL;

    if (FAILED(GetRunningObjectTable(0, &pROT))) 
    {
        return E_FAIL;
    }
    
    const size_t STRING_LENGTH = 256;

    WCHAR wsz[STRING_LENGTH];
 
   StringCchPrintfW(
        wsz, STRING_LENGTH, 
        L"FilterGraph %08x pid %08x", 
        (DWORD_PTR)pUnkGraph, 
        GetCurrentProcessId()
        );
    
    HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
    if (SUCCEEDED(hr)) 
    {
        hr = pROT->Register(ROTFLAGS_REGISTRATIONKEEPSALIVE, pUnkGraph,
            pMoniker, pdwRegister);
        pMoniker->Release();
    }
    pROT->Release();
    
    return hr;
}

此函数为筛选器图创建名字对象和新的 ROT 条目。 第一个参数是指向筛选器图的指针。 第二个参数接收一个值,该值标识新的 ROT 条目。 在应用程序释放筛选器图之前,请调用以下函数以删除 ROT 条目。 pdwRegister 参数是由 AddToRot 函数返回的标识符。

void RemoveFromRot(DWORD pdwRegister)
{
    IRunningObjectTable *pROT;
    if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) {
        pROT->Revoke(pdwRegister);
        pROT->Release();
    }
}

下面的代码示例演示如何调用这些函数。 在此示例中,添加和删除 ROT 条目的代码是有条件编译的,因此它仅包含在调试版本中。

IGraphBuilder *pGraph;
DWORD dwRegister;
    
// Create the filter graph manager.
CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
                        IID_IGraphBuilder, (void **)&pGraph);
#ifdef _DEBUG
hr = AddToRot(pGraph, &dwRegister);
#endif

// Rest of the application (not shown).

#ifdef _DEBUG
RemoveFromRot(dwRegister);
#endif
pGraph->Release();

若要在 GraphEdit 中查看筛选器图,请同时运行应用程序和 GraphEdit。 在“GraphEdit 文件 ”菜单中,单击“ 连接到远程图形...” 在“ 连接到图形 ”对话框中,选择应用程序的进程 ID (pid) ,然后单击“ 确定”。 GraphEdit 加载筛选器图并显示它。 请勿在此图上使用任何其他 GraphEdit 功能,这可能会导致意外结果。 例如,不要添加或删除筛选器,或者停止并启动图形。 在退出应用程序之前关闭 GraphEdit。

注意

应用程序退出时可能会遇到各种断言。 可以忽略这些错误。

 

下图显示了“ 连接到图形 ”对话框。

连接到图形

当 GraphEdit 加载图形时,它会在目标应用程序的上下文中执行。 因此,GraphEdit 可能会阻止,因为它正在等待线程。 例如,如果在调试器中单步执行代码,则可能会发生这种情况。

此功能应仅用于应用程序的调试版本,而不是零售版本,因为它允许其他应用程序查看或控制筛选器图。

从命令行连接到远程图形

GraphEdit 支持命令行选项,用于在启动时自动加载远程图形。 语法为:

GraphEdt -a moniker

其中 ,名字对象 是使用 AddToRot 函数创建的名字对象,如前所述。

使用 GraphEdit 模拟图形生成