将对象与 IDispatch 进行比较以仅获取主框架(BHO)
我不知道是否有人熟悉 BHO(浏览器帮助对象),但 c++ 专家也可以帮助我。
在我的 BHO 中,我只想在主框架(第一个容器)上运行 OnDocumentComplete() 函数,而不是在当前页面内的所有 Iframe 上运行。 (另一种方法是仅当这是主框架时才放置一些代码)。
我找不到如何跟踪何时填充主框架。
在谷歌搜索后,我发现每个帧都有“IDispatch* pDisp”,我必须将它与指向第一个帧的指针进行比较。
这是主要功能:
STDMETHODIMP Browsarity::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<Browsarity>::SetSite(pUnkSite);
}
这是我想知道它是否是主窗口(框架)的地方:
void STDMETHODCALLTYPE Browsarity::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
// as you can see, this function get the IDispatch *pDisp which is unique to every frame.
//some code
}
我在微软论坛上问了这个问题,我得到了答案,但没有解释如何实际实现:http://social.msdn.microsoft.com /Forums/zh-CN/ieextensiondevelopment/thread/7c433bfa-30d7-42db-980a-70e62640184c
I don't know if anyone familiar with BHO (Browser Helper Object), but an expert in c++ can help me too.
In my BHO I want to run the OnDocumentComplete() function only on the main frame - the first container and not all the Iframes inside the current page. (an alternative is to put some code only when this is the main frame).
I can't find how to track when is it the main frame that being populated.
After searching in google I found out that each frame has "IDispatch* pDisp", and I have to compare it with a pointer to the first one.
This is the main function:
STDMETHODIMP Browsarity::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<Browsarity>::SetSite(pUnkSite);
}
This is where I want to be aware whether its the main window(frame) or not:
void STDMETHODCALLTYPE Browsarity::OnDocumentComplete(IDispatch *pDisp, VARIANT *pvarURL)
{
// as you can see, this function get the IDispatch *pDisp which is unique to every frame.
//some code
}
I asked this question on Microsoft forum and I got an answer without explaining how to actually implement that: http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/7c433bfa-30d7-42db-980a-70e62640184c
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
jeffdav建议的是,通过
QueryInterface()
测试pDisp
是否支持IWebBrowser2
,如果支持,检查它是否是同一个对象作为您存储在SetSite()
中的那个。QueryInterface()
规则< /a> 仅要求IUnknown
的QI
始终产生相同的指针值,因此您必须将QI
附加到IUnknown
并比较结果指针。这会导致
OnDocumentComplete()
中出现类似的情况:...或者如果您使用 ATL(如
m_spWebBrowser
建议):What jeffdav suggested is, to test wether the
pDisp
supportsIWebBrowser2
viaQueryInterface()
, and if so, to check wether it is the same object as the one you stored inSetSite()
.The
QueryInterface()
rules only require that aQI
forIUnknown
always results in the same pointer value, so you have to additionallyQI
toIUnknown
and compare the resulting pointers.This would lead to something like this in
OnDocumentComplete()
:... or if you are using ATL (as
m_spWebBrowser
suggests):请注意,我没有对此进行测试,我只是重写了 msdn 上的人所说的内容。
在 ::SetSite 中你得到一个 IUnknown 指针。对其调用 IUnknown::QueryInterface(就像您已经在做的那样),但使用 IID_IDISPATCH。把这个指针保存在某个地方,这个指针就是顶层框架。
在 ::OnDocumentComplete 中,您将获得一个 IDispatch 指针,将其与之前保存的 ptr 进行比较,瞧,如果存在匹配项,则您位于顶层。
Notice that I did not test this, I'm only rewriting what the guy on msdn said.
In ::SetSite you get an IUnknown pointer. Call IUnknown::QueryInterface on it (just like you're already doing), but instead use IID_IDISPATCH. Save this pointer somewhere, this pointer is the top level frame.
In ::OnDocumentComplete you're getting a IDispatch pointer, compare this one to the previous saved ptr and voíla, if there is a match you're in the top level.