Artigo: 246247 - Última revisão: quinta-feira, 11 de Maio de 2006 - Revisão: 4.0

Como receber eventos de documento HTML para WebBrowser anfitrião

Dica do SistemaEste artigo aplica-se a um sistema operativo diferente do que está a utilizar. Foi desactivado o conteúdo do artigo, que pode não ser relevante para si.

Nesta página

Expandir tudo | Reduzir tudo

Sumário

Os programadores que hospedem o controlo WebBrowser no Microsoft Visual C++ ou Visual Basic frequentemente pretende receber eventos para o documento actualmente carregado. Isto é muito útil para fornecer comportamento global que os autores de browser pretendem implementar todas as páginas dentro a experiência de utilizador, tais como agarrando informações externas sobre uma hiperligação seleccionada ou uma parte de texto seleccionado.

A estratégia de Visual C++ e Visual Basic geral é:
  1. Receber eventos do controlo WebBrowser (a interface DWebBrowserEvents2) e capturar o evento DocumentComplete. Uma vez que o documento não é garantido que ser totalmente carregado até que este evento é accionado, todos os documentos sinking deve ser feita a partir daqui.
  2. No DocumentComplete, obter o objecto de documento o WebBrowser e Lavatório interface HtmlDocumentEvents. No Visual Basic, fazê-lo utilizando a palavra-chave WithEvents num objecto do tipo HTMLDocument.
  3. Processar o evento e devolver um valor boleano que indica se pretende o Internet Explorer executar o respectivo processamento de eventos ou cancelar o evento.
  4. Desmarque o receptor de BeforeNavigate2 e de OnDestroy desde a última receptor não ser limpo quando estão a matar a aplicação.

Mais Informação

Visual C++ (ATL)

O primeiro de negócio da encomenda no Visual C++ é criar o evento de pias. Dois "event sinks" tem de ser criado: um para DWebBrowserEvents2 para o controlo WebBrowser e outra para HtmlDocumentEvents (definido no MSHTML.H) para o documento de biblioteca de modelo de Active Directory (ATL) real.

O receptor DWebBrowserEvents2 pode ser implementado muito rapidamente utilizando IDispEventImpl do ATL, conforme descrito o seguinte artigo da base de dados de conhecimento da Microsoft:
194179  (http://support.microsoft.com/kb/194179/ ) AtlEvnt.exe exemplo mostra como cria ATL PIAs utilizando as classes ATL IDispEventImpl e IDispEventSimpleImpl
Porque haverá um novo documento sempre que o utilizador navega para uma nova página, tem de receber os eventos de documento sempre que o controlo WebBrowser lança o evento DocumentComplete. No seu processador DocumentComplete, utilize o seguinte código para receber eventos de documento:
// Declare these as members of your IWebBrowser2 sink.
CComObject<CDocumentSink> *pSink;
CComPtr<IUnknown> pSrcUnk;
DWORD dwDocCookie;

STDMETHODIMP CWebOCWindow::DocumentComplete(IDispatch *wbDisp, VARIANT* url) {
	HRESULT hr;
	CComPtr<IDispatch> pDocDisp;
	CComQIPtr<IHTMLDocument2> pDoc;
	CComPtr<IUnknown> wbDispUnk;

	// Sink only the topmost document. Slightly more complex logic will be needed
	// if you wish to sink multiple pages embedded in a frameset.
	hr = wbDisp->QueryInterface(IID_IUnknown, reinterpret_cast<void **>(&wbDispUnk));
	if (FAILED(hr)) {
		goto cleanup;
	}
	if (wbDispUnk == browserUnk) {
		hr = CComObject<CDocumentSink>::CreateInstance(&pSink);
		if (FAILED(hr)) {
			goto cleanup;
		}
		// Get the current document from the WebBrowser.
		// If you'll be surfing to sites with frames, and want to avoid sinking all but
		// the top-level document - i.e., the frameset - make sure to sink only when the
		// IUnknown obtained from wbDisp and the original IUnknown of the hosted 
		// WebBrowser control are equal.
		hr = webOC->get_Document(&pDocDisp);
		if (FAILED(hr)) {
			goto cleanup;
		}
		hr = pDocDisp->QueryInterface(&pSrcUnk);
		if (FAILED(hr)) {
			goto cleanup;
		}
		// If this is not an HTML document (e.g., it's a Word doc or a PDF), don't sink. 
		pDoc = pDocDisp;
		if (!pDoc) {
			goto cleanup;
		}

		hr = AtlAdvise(pSrcUnk, pSink, DIID_HTMLDocumentEvents, &dwDocCookie);
		if (FAILED(hr)) {
			goto cleanup;
		}
	}

cleanup:
	// Only smart pointers used - nothing to do here.
	return hr;
}
				
poderá encontrar informações adicionais sobre sinking DocumentComplete, particularmente quando estão envolvidas pacotes, no seguinte artigo da base de dados de conhecimento:
180366  (http://support.microsoft.com/kb/180366/ ) Como determinar quando é efectuada uma página carregado no controlo WebBrowser
O receptor de eventos de documento HTML tem de incluir os ficheiros <MSHTML.h> e <MSHTMDID.h> (que define todos os DISPID para HTMLDocumentEvents).

Processadores de eventos para eventos de documento cancelável devem devolver um valor boleano no parâmetro do método IDispatch::Invoke() pvarResult. Um valor de VARIANT_TRUE indica que Internet Explorer deverá efectuar o suas próprias processamento de eventos; um valor de VARIANT_FALSE cancela o evento. Por este motivo, deve substituir Invoke() directamente em vez de utilizar uma implementação de atalho como IDispEventImpl do ATL, que não lhe permitirá alterar o pvarResult. Para substituir Invoke() com êxito de um receptor de eventos ATL, consulte o seguinte artigo na base de dados de conhecimento da Microsoft:
181277  (http://support.microsoft.com/kb/181277/ ) O exemplo AtlSink.exe demonstra como implementar um receptor dispinterface utilizando o Active Directory modelo de biblioteca (ATL) no Visual C++
O código de receptor seguinte mostra como pode ser substituída Invoke() para processar o evento clicar (DISPID_CLICK):
void OnClick(VARIANT_BOOL *bProcessEvent) {
        AtlTrace("CDocumentSink:OnClick - Obtained a click on the document\n");
	*bProcessEvent = TRUE;
}

STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult,
			  EXCEPINFO *pexcepinfo, UINT *puArgErr) {
        HRESULT hr;

	if (dispidMember == DISPID_CLICK) {
	    VARIANT_BOOL bEventRet;
	    OnClick(&bEventRet);
	    pvarResult->vt = VT_BOOL;
	    pvarResult->boolVal = bEventRet;
            hr = S_OK;
	} else {
            hr = DISP_E_MEMBERNOTFOUND;
	}
	return hr;
}
				
por último, certifique-se de unadvise o receptor de BeforeNavigate2:
STDMETHODIMP CWebOCWindow::BeforeNavigate2(IDispatch *pDisp, VARIANT *url, VARIANT *Flags, VARIANT *TargetFrameName,
							 VARIANT *PostData, VARIANT *Headers, VARIANT_BOOL *Cancel) {
	if (pSrcUnk) {
		hr = AtlUnadvise(pSrcUnk, DIID_HTMLDocumentEvents, dwDocCookie);
		pSrcUnk.Detach();
	}
	return S_OK;
}
				

Visual Basic

O processo no Visual Basic é o mesmo: sink de eventos de documentos no evento DocumentComplete para o objecto WebBrowser. Felizmente, o processo de evento sinking é reduzido utilizando palavra-chave WithEvents do Visual Basic em cooperação com uma declaração de variável.

Partindo do princípio que o WebBrowser chama WebBrowser1 e adicionado Microsoft HTML Object Library ao projecto, o seguinte código funciona exactamente o mesmo que o código do C++:
Dim WithEvents doc As HTMLDocument

Private Sub Form_Load()
    WebBrowser1.Navigate "http://www.microsoft.com/"
End Sub

Private Sub WebBrowser1_DocumentComplete(ByVal pDisp As Object, URL As Variant)
    Dim htm As IHTMLDocument2
    
    On Error Resume Next
    Set htm = WebBrowser1.Document
    If Err.Number = 0 Then
        MsgBox "HREF is " & htm.location.href
    End If
    
    Set doc = htm
End Sub

Private Function doc_onclick() As Boolean
    MsgBox "Clicked the document!"
    ' Tell IE to continue processing the event.
    doc_onclick = True
End Function

Private Sub WebBrowser1_BeforeNavigate2(ByVal pDisp As Object, URL As Variant, Flags As Variant, _
						    TargetFrameName As Variant, PostData As Variant, Headers As Variant, _
						    Cancel As Boolean)
    set doc = Nothing
End Sub
				

Referências

Para obter mais informações sobre como desenvolver soluções baseadas na Web para o Microsoft Internet Explorer, visite os seguintes Web sites da Microsoft:
http://msdn.microsoft.com/ie/ (http://msdn.microsoft.com/ie/)

http://support.microsoft.com/iep (http://support.microsoft.com/iep)

A informação contida neste artigo aplica-se a:
  • Microsoft Internet Explorer 4.0 128-Bit Edition
  • Microsoft Internet Explorer 4.01 Service Pack 2
  • Microsoft Internet Explorer 4.01 Service Pack 1
  • Microsoft Internet Explorer 4.01 Service Pack 2
  • Microsoft Internet Explorer 5.0
  • Microsoft Internet Explorer 5.01
  • Microsoft Internet Explorer 5.5
Palavras-chave: 
kbmt kbactivexevents kbhowto kbwebbrowser KB246247 KbMtpt
Tradução automáticaTradução automática
IMPORTANTE: Este artigo foi traduzido por um sistema de tradução automática (também designado por Machine translation ou MT), não tendo sido portanto revisto ou traduzido por humanos. A Microsoft tem artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais. O objectivo é simples: oferecer em Português a totalidade dos artigos existentes na base de dados do suporte. Sabemos no entanto que a tradução automática não é sempre perfeita. Esta pode conter erros de vocabulário, sintaxe ou gramática? erros semelhantes aos que um estrangeiro realiza ao falar em Português. A Microsoft não é responsável por incoerências, erros ou estragos realizados na sequência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza actualizações frequentes ao software de tradução automática (MT). Obrigado.
Clique aqui para ver a versão em Inglês deste artigo: 246247  (http://support.microsoft.com/kb/246247/en-us/ )
Retired KB ArticleExclusão de Responsabilidade para Conteúdo sem Suporte na KB
Este artigo foi escrito sobre produtos para os quais a Microsoft já não fornece suporte. Por conseguinte, este artigo é oferecido "tal como está" e deixará de ser actualizado.