ID do artigo: 246247 - Última revisão: quinta-feira, 11 de maio de 2006 - Revisão: 4.0

Como coletar eventos de documento HTML para host WebBrowser

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 | Recolher tudo

Sumário

Os desenvolvedores que hospedam o controle WebBrowser no Microsoft Visual C++ ou Visual Basic com freqüência desejam coletar eventos para o documento carregado no momento. Isso é muito útil para fornecer comportamento global que autores de navegador desejam implementar em todas as páginas dentro a experiência do usuário, como captura informações externas em um link clicado ou uma parte do texto selecionado.

A estratégia geral para Visual C++ e Visual Basic é:
  1. Coletor de eventos do controle WebBrowser (a interface DWebBrowserEvents2) e capturar o evento DocumentComplete. Porque o documento não é garantido para ser totalmente carregado até que este evento é acionado, todos os documento recepção deve ser feito a partir daqui.
  2. No DocumentComplete, recuperar o objeto de documento do WebBrowser e a interface HtmlDocumentEvents do coletor. No Visual Basic, fazer isso usando a palavra-chave WithEvents em um objeto do tipo HTMLDocument.
  3. Manipular o evento e retornar um valor Boolean que indica se deseja que o Internet Explorer para executar seu próprio processamento de eventos ou cancelar o evento.
  4. Desmarque o coletor no BeforeNavigate2 e em OnDestroy desde a última coletor não ser limpo quando são eliminar o aplicativo.

Mais Informações

O Visual C++ (ATL)

A primeira empresa de ordem no Visual C++ é criar o evento coletores. Dois receptores de evento devem ser criados: um para DWebBrowserEvents2 para o controle WebBrowser e um para HtmlDocumentEvents (definido no MSHTML.H) para o documento real do ATL (Active Template Library).

O coletor de DWebBrowserEvents2 pode ser implementado rapidamente usando IDispEventImpl do ATL, conforme descrito no seguinte artigo Base de dados de Conhecimento Microsoft:
194179  (http://support.microsoft.com/kb/194179/ ) AtlEvnt.exe exemplo mostra como cria ATL coletores usando as classes ATL IDispEventImpl e IDispEventSimpleImpl
Porque não haverá um novo documento toda vez que o usuário navega para uma nova página, você deve coletar os eventos de documento sempre que o controle WebBrowser lança o evento DocumentComplete. Dentro o manipulador de DocumentComplete, usar o seguinte código para coletar 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;
}
				
informações adicionais sobre recepção DocumentComplete, particularmente quando quadros estão envolvidos, podem ser encontradas no seguinte artigo da Base de dados de Conhecimento:
180366  (http://support.microsoft.com/kb/180366/ ) Como determinar quando uma página é feita carregando no controle WebBrowser
O coletor de eventos documento HTML deve incluir o arquivos <MSHTML.h> e <MSHTMDID.h> (que define todos os DISPIDs para HTMLDocumentEvents).

Manipuladores de eventos para eventos de documento cancelável devem retornar um valor booleano no parâmetro do método IDispatch::Invoke() pvarResult. Um valor de VARIANT_TRUE indica que o Internet Explorer deve executar seu próprio processamento de eventos; um valor de VARIANT_FALSE cancela o evento. Por esse motivo, você deve substituir Invoke() diretamente em vez de usar uma implementação de atalho como IDispEventImpl do ATL, que não permitirá a você alterar o pvarResult. Para substituir Invoke() com êxito em um coletor 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 recpetor de dispinterface, usando a ATL (Active Template Library) no Visual C++
O coletor de código a seguir mostra como Invoke() pode ser substituída para manipular o evento Click (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, verifique se unadvise seu coletor 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: coletor de eventos de documento no evento DocumentComplete do objecto WebBrowser. Felizmente, o processo de evento de recepção é reduzido usando palavra-chave WithEvents do Visual Basic em cooperação com uma declaração de variável.

Supondo que o WebBrowser é denominado WebBrowser1 e você adicionou o Microsoft HTML Object Library ao projeto, o código a seguir funciona exatamente o mesmo que o código 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 sites:
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 Edição de 128 Bits
  • 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 traduzido ou revisto por pessoas. A Microsoft possui artigos traduzidos por aplicações (MT) e artigos traduzidos por tradutores profissionais, com o objetivo de oferecer em português a totalidade dos artigos existentes na base de dados de suporte. No entanto, a tradução automática não é sempre perfeita, podendo conter erros de vocabulário, sintaxe ou gramática. A Microsoft não é responsável por incoerências, erros ou prejuízos ocorridos em decorrência da utilização dos artigos MT por parte dos nossos clientes. A Microsoft realiza atualizações freqüentes 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 ArticleAviso de Isenção de Responsabilidade sobre Conteúdo do KB Aposentado
Este artigo trata de produtos para os quais a Microsoft não mais oferece suporte. Por esta razão, este artigo é oferecido "como está" e não será mais atualizado.