在网页上,我有一个带有 JavaScript 发布消息的按钮。在我的 BHO IE 插件中,我需要一个事件监听器来监听这个消息事件。任何线索如何做到这一点?我OnDocumentComplete
的如下。您能否提供更多指示,我们可以在其中编写处理此事件的代码。我想从此消息处理程序进行 REST API 调用。
测试脚本.h:
// TestScript.h : Declaration of the CTestScript
#pragma once
#include "resource.h" // main symbols
#include "TestBHO_i.h"
#include <mshtml.h> // DOM interfaces
#if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA)
#error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms."
#endif
// CTestScript
class ATL_NO_VTABLE CTestScript :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CTestScript, &CLSID_TestScript>,
public IObjectWithSiteImpl<CTestScript>,
public IDispatchImpl<ITestScript, &IID_ITestScript, &LIBID_TestBHOLib, /*wMajor =*/ 1, /*wMinor =*/ 0>,
public IDispEventImpl<1, CTestScript, &DIID_DWebBrowserEvents2, &LIBID_SHDocVw, 1, 1>,
//public IPersistPropertyBagImpl<CTestScript>,
public IObjectSafetyImpl<CTestScript, INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA>
{
public:
CTestScript()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_TESTSCRIPT)
DECLARE_NOT_AGGREGATABLE(CTestScript)
BEGIN_COM_MAP(CTestScript)
COM_INTERFACE_ENTRY(ITestScript)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP()
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
public:
BEGIN_SINK_MAP(CTestScript)
SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_DOCUMENTCOMPLETE, OnDocumentComplete)
//SINK_ENTRY_EX(1, DIID_DWebBrowserEvents2, DISPID_NAVIGATECOMPLETE2, OnNavigationComplete)
END_SINK_MAP()
void STDMETHODCALLTYPE OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL);
//void STDMETHODCALLTYPE OnNavigationComplete(IDispatch *pDisp, VARIANT *pvarURL);
STDMETHOD(SetSite)(IUnknown *pUnkSite);
HRESULT STDMETHODCALLTYPE DoSomething(){
::MessageBox(NULL, L"Hello", L"World", MB_OK);
return S_OK;
}
public:
//private:
// InstallBHOMethod();
private:
void EnableOpenOnDesktopButton(IHTMLDocument2 *pDocument);
private:
void AddPostMessage(IHTMLDocument2 *pDocument);
private:
CComPtr<IWebBrowser2> m_spWebBrowser;
BOOL m_fAdvised;
};
OBJECT_ENTRY_AUTO(__uuidof(TestScript), CTestScript)
测试脚本.cpp:
// TestScript.cpp : Implementation of CTestScript
#include "stdafx.h"
#include "TestScript.h"
// CTestScript
void debug(LPWSTR msg)
{
::MessageBox(NULL,msg,L"Debug",MB_OK);;
}
STDMETHODIMP CTestScript::SetSite(IUnknown* pUnkSite)
{
if (pUnkSite != NULL)
{
// Cache the pointer to IWebBrowser2.
HRESULT hr = pUnkSite->QueryInterface(IID_IWebBrowser2, (void **)&m_spWebBrowser);
if (SUCCEEDED(hr))
{
// Register to sink events from DWebBrowserEvents2.
hr = DispEventAdvise(m_spWebBrowser);
if (SUCCEEDED(hr))
{
m_fAdvised = TRUE;
}
}
}
else
{
// Unregister event sink.
if (m_fAdvised)
{
DispEventUnadvise(m_spWebBrowser);
m_fAdvised = FALSE;
}
// Release cached pointers and other resources here.
m_spWebBrowser.Release();
}
// Call base class implementation.
return IObjectWithSiteImpl<CTestScript>::SetSite(pUnkSite);
}
void STDMETHODCALLTYPE CTestScript::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
HRESULT hr = S_OK;
// Query for the IWebBrowser2 interface.
CComQIPtr<IWebBrowser2> spTempWebBrowser = pDisp;
//CComPtr<IEventTarget> spIEventTarget;
// Is this event associated with the top-level browser?
if (spTempWebBrowser && m_spWebBrowser &&
m_spWebBrowser.IsEqualObject(spTempWebBrowser))
{
// Get the current document object from browser...
CComPtr<IDispatch> spDispDoc;
hr = m_spWebBrowser->get_Document(&spDispDoc);
if (SUCCEEDED(hr))
{
// ...and query for an HTML document.
CComQIPtr<IHTMLDocument2> spHTMLDoc = spDispDoc;
if (spHTMLDoc != NULL)
{
EnableOpenOnDesktopButton(spHTMLDoc);
AddPostMessage(spHTMLDoc) ;
}
}
}
}
void CTestScript::EnableOpenOnDesktopButton(IHTMLDocument2* pDocument)
{
CComPtr<IHTMLElement> bodypt;
CComPtr<IHTMLElement> html;
pDocument->get_body(&bodypt);
bodypt->get_parentElement(&html);
//TODO: concatinate old class and new class and apply toht
BSTR className = L" my-browser-extension";
html->put_className(className);
}
void CTestScript::AddPostMessage(IHTMLDocument2* pDocument)
{
HRESULT hr = S_OK;
CComPtr<IHTMLWindow2> _spWindow;
hr = pDocument->get_parentWindow(reinterpret_cast<IHTMLWindow2 **>(&_spWindow));
if (SUCCEEDED(hr) && _spWindow)
{
CComPtr<IEventTarget> spIEventTarget;
hr = _spWindow->QueryInterface(IID_IEventTarget, reinterpret_cast<void **>(&spIEventTarget));
if (SUCCEEDED(hr) && spIEventTarget)
{
_pIEUIEventListener = new CIEUIEventListener(); // This class derives from IDispatch
hr = spIEventTarget->addEventListener(_bstr_t("message"), _pIEUIEventListener, VARIANT_TRUE);
if (SUCCEEDED(hr))
{
debug(L"HEREE");
}
}
}
}
IEUIEventListener.h:
#pragma once
class CIEUIEventListener : public IDispatchEx
{
public:
CIEUIEventListener(void);
~CIEUIEventListener(void);
HRESULT STDMETHODCALLTYPE Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr);
};
IEUIEventListener.cpp:
#include "StdAfx.h"
#include "IEUIEventListener.h"
CIEUIEventListener::CIEUIEventListener(void)
{
}
CIEUIEventListener::~CIEUIEventListener(void)
{
}
HRESULT STDMETHODCALLTYPE CIEUIEventListener::Invoke(
DISPID dispIdMember,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pDispParams,
VARIANT *pVarResult,
EXCEPINFO *pExcepInfo,
UINT *puArgErr)
{
::MessageBox(NULL,L"FYYYYYYYY",L"Debug",MB_OK);;
return S_OK;
}