Carregando um grafo de um processo externo

[O recurso associado a esta página, DirectShow, é um recurso herdado. Ele foi substituído por MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo na Media Foundation. Esses recursos foram otimizados para Windows 10 e Windows 11. A Microsoft recomenda fortemente que o novo código use MediaPlayer, IMFMediaEngine e Captura de Áudio/Vídeo no Media Foundation em vez de DirectShow, quando possível. A Microsoft sugere que o código existente que usa as APIs herdadas seja reescrito para usar as novas APIs, se possível.]

GraphEdit pode carregar um grafo de filtro criado por um processo externo. Com esse recurso, você pode ver exatamente qual grafo de filtro seu aplicativo cria, com apenas uma quantidade mínima de código adicional em seu aplicativo.

Observação

Esse recurso requer Windows 2000, Windows XP ou posterior.

 

Observação

A partir do Windows Vista, você deve registrar proppage.dll para habilitar esse recurso. Proppage.dll está incluído no SDK do Windows.

 

O aplicativo deve registrar a instância do grafo de filtro na ROT (Tabela de Objetos em Execução). O ROT é uma tabela de pesquisa globalmente acessível que controla a execução de objetos. Os objetos são registrados no ROT por moniker. Para se conectar ao grafo, o GraphEdit pesquisa a ROT em busca de monikers cujo nome de exibição corresponde a um formato específico:

!FilterGraph X pid Y

em que X é o endereço hexadecimal do Gerenciador de Grafo de Filtro e Y é a ID do processo, também em hexadecimal.

Quando o aplicativo cria o grafo de filtro pela primeira vez, chame a seguinte função:

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;
}

Essa função cria um moniker e uma nova entrada ROT para o grafo de filtro. O primeiro parâmetro é um ponteiro para o grafo de filtro. O segundo parâmetro recebe um valor que identifica a nova entrada ROT. Antes que o aplicativo libere o grafo de filtro, chame a função a seguir para remover a entrada ROT. O parâmetro pdwRegister é o identificador retornado pela função AddToRot.

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

O exemplo de código a seguir mostra como chamar essas funções. Neste exemplo, o código que adiciona e remove entradas ROT é compilado condicionalmente, de modo que ele seja incluído somente em builds de depuração.

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();

Para exibir o grafo de filtro no GraphEdit, execute o aplicativo e o GraphEdit ao mesmo tempo. No menu Arquivo GraphEdit, clique em Conectar-se ao Grafo Remoto... Na caixa de diálogo Conectar-se ao Graph , selecione a ID do processo (pid) do aplicativo e clique em OK. GraphEdit carrega o grafo de filtro e o exibe. Não use outros recursos do GraphEdit neste grafo, isso pode causar resultados inesperados. Por exemplo, não adicione nem remova filtros ou pare e inicie o grafo. Feche o GraphEdit antes de sair do aplicativo.

Observação

Seu aplicativo pode atingir várias declarações quando ele for encerrado. Você pode ignorá-los.

 

A ilustração a seguir mostra a caixa de diálogo Conectar ao Graph .

conectar-se ao grafo

Quando GraphEdit carrega o grafo, ele é executado no contexto do aplicativo de destino. Portanto, o GraphEdit pode bloquear porque está aguardando o thread. Por exemplo, isso pode ocorrer se você estiver percorrendo seu código no depurador.

Esse recurso deve ser usado apenas em builds de depuração do aplicativo, não em builds de varejo, pois permite que outros aplicativos exibam ou controlem o grafo de filtro.

Conectando-se a um grafo remoto da linha de comando

O GraphEdit dá suporte a uma opção de linha de comando para carregar um grafo remoto automaticamente na inicialização. A sintaxe do é:

GraphEdt -a moniker

em que moniker é um moniker criado usando a função AddToRot, descrita anteriormente.

Simulando a criação de grafo com GraphEdit