- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在网页上,我有一个带有 JavaScript 发布消息的按钮。在我的 BHO IE 附加组件中,我需要一个用于此消息事件的事件监听器。有什么线索可以做到这一点吗?我的 OnDocumentComplete
如下。您能否提供更多指示,让我们可以编写处理此事件的代码。我想从此消息处理程序进行 REST API 调用。
TestScript.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;
}
最佳答案
如果你的意思是window.postMessage ,您需要从 BHO 的 DOM window
对象 (window.addEventListener("message")
) 上添加 message
事件的监听器。要获取 window
对象,请使用 IWebBrowser2::get_Document
、IHTMLDocument2::get_parentWindow
,然后查询 window
IEventTarget
并调用 addEventListener
。为其提供一个 IDispatch
实现作为 listener
参数。当消息发布时,它将被回调为 IDispatch::Invoke(DISPID_VALUE)
。
[已编辑] 此更新基于您发布的更新代码。我不知道为什么 IEventTarget
仍未为您定义(也许您的 Visual Studio 包含路径配置有问题)。因此,只需从这里获取定义:
MIDL_INTERFACE("305104b9-98b5-11cf-bb82-00aa00bdce0b")
IEventTarget : public IDispatch
{
public:
virtual /* [id] */ HRESULT STDMETHODCALLTYPE addEventListener(
/* [in] */ __RPC__in BSTR type,
/* [in] */ __RPC__in_opt IDispatch *listener,
/* [in] */ VARIANT_BOOL useCapture) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE removeEventListener(
/* [in] */ __RPC__in BSTR type,
/* [in] */ __RPC__in_opt IDispatch *listener,
/* [in] */ VARIANT_BOOL useCapture) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE dispatchEvent(
/* [in] */ __RPC__in_opt IDOMEvent *evt,
/* [out][retval] */ __RPC__out VARIANT_BOOL *pfResult) = 0;
};
MIDL_INTERFACE("305104ba-98b5-11cf-bb82-00aa00bdce0b")
IDOMEvent : public IDispatch
{
public:
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_bubbles(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_cancelable(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_currentTarget(
/* [out][retval] */ __RPC__deref_out_opt IEventTarget **p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_defaultPrevented(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_eventPhase(
/* [out][retval] */ __RPC__out USHORT *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_target(
/* [out][retval] */ __RPC__deref_out_opt IEventTarget **p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_timeStamp(
/* [out][retval] */ __RPC__out ULONGLONG *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_type(
/* [out][retval] */ __RPC__deref_out_opt BSTR *p) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE initEvent(
/* [in] */ __RPC__in BSTR eventType,
/* [in] */ VARIANT_BOOL canBubble,
/* [in] */ VARIANT_BOOL cancelable) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE preventDefault( void) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE stopPropagation( void) = 0;
virtual /* [id] */ HRESULT STDMETHODCALLTYPE stopImmediatePropagation( void) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_isTrusted(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propput] */ HRESULT STDMETHODCALLTYPE put_cancelBubble(
/* [in] */ VARIANT_BOOL v) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_cancelBubble(
/* [out][retval] */ __RPC__out VARIANT_BOOL *p) = 0;
virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_srcElement(
/* [out][retval] */ __RPC__deref_out_opt IHTMLElement **p) = 0;
};
接下来,您的 CIEUIEventListener
看起来不像 COM 对象实现。我没有看到任何 IUnknown
和 IDispatch
方法,也许您只是没有显示它。您也不必从 IDispatchEx
派生,IDispatch
就足够了。我建议您以以下 DOM 事件接收器的实现为基础,它是不言自明的:
// Usage:
//
// CComPtr<CEventSink> eventSink;
// CEventSink::Create(pTestScript, &eventSink); // pass eventSink where IDispatch* is expected
//
class CEventSink:
public CComObjectRoot,
public IDispatch
{
protected:
CTestScript* m_pParent;
CEventSink() { m_pParent = NULL; }
public:
BEGIN_COM_MAP(CEventSink)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// create and initialize
static HRESULT Create(CTestScript* pParent, CEventSink** pp)
{
CComObject<CEventSink>* pThis = NULL;
CComObject<CEventSink>::CreateInstance(&pThis);
if (!pThis)
return E_OUTOFMEMORY;
pThis->m_pParent = pParent;
(*pp = pThis)->AddRef();
return S_OK;
}
// IDispatch
STDMETHODIMP GetTypeInfoCount(UINT* pctinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
{
return DISP_E_UNKNOWNNAME;
}
STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
if ( dispidMember == DISPID_VALUE )
{
// handle the event
// for example, call some method on m_pParent
}
return DISP_E_MEMBERNOTFOUND;
}
};
关于events - ATL C++ BHO 中的 Javascript 发布消息事件处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18756704/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!