COleControlSite释放出错

patchclass 2008-02-19 05:46:22
编译环境VC8,使用微软的MTMDI建立了一个界面多线程浏览器框架,同时通过 重载 CreateControlSite 函数
*ppSite = new CCustomControlSite(pContainer); // CCustomControlSite 继承了 COleControlSite
实现了对于Chtmlview的控制,如果正常运行的时候,发现没有任何问题,但是如果使用 OnNewWindow2中 将
*ppDisp = pLastView->GetApplication()后在关闭的时候将出现严重问题,状况为 关闭 OnNewWindow2 打开的相关联的窗口,在关闭最后一个的时候出现访问冲突错误,错误跳转到 occsite.cpp 的析构函数~COleControlSite中的 m_pObject->SetClientSite(NULL);如果不重载 CreateControlSite 函数,或者不用界面多线程 则不会出现此种情况
个人分析为 COleControlSite 对象的释放错误,OnNewWindow2 打开的系列窗口之间可能存在某种联系,导致在自动释放 CCustomControlSite 对象的时候引起冲突
但是目前没有找到解决方法,请各位指教。
...全文
525 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
eduyu 2008-02-20
  • 打赏
  • 举报
回复
方法1:让目标线程调用CoMarshalInterThreadInterfaceInStream,保存得到的IStream的指针。当前进程获取此指针,调用CoGetInterfaceAndReleaseStream,得到列集后的接口指针,传入。
方法2:让目标线程调用IGlobalInterfaceTable::RegisterInterfaceInGlobal,本线程调用lobalInterfaceTable::GetInterfaceFromGlobal,也可获得列集后的接口指针。

另:(to james帅哥)js的window.open方法会返回一个window对象,也就是对NewWindow2中,你传给他的IWebbrowser2来query IHTMLWindow2的结果。js获得了目标window自然可以访问对方DOM也可以把自己window传给对方让对方访问自己DOM。这在js开发人员看来是很自然的。
jameshooo 2008-02-20
  • 打赏
  • 举报
回复
从未听说过一个网页中的js能访问另一个浏览器中的网页,技术上不是做不到,IE安全管理器自己也会拦截。
如果想网页间相互访问,在一个网页里使用frame,frame之间能互相访问。
patchclass 2008-02-20
  • 打赏
  • 举报
回复
我需要打开页面之间进行js的通讯,如果采用Cancel参数设置为true自己的浏览器窗口中Navigate,会导致这2个窗口没有关联,此方法不可行,请高手支招.
jameshooo 2008-02-20
  • 打赏
  • 举报
回复
直接把OnNewWindow2中的Cancel参数设置为true,然后在自己的浏览器窗口中Navigate需要的URL即可。
eduyu 2008-02-20
  • 打赏
  • 举报
回复
不管怎样,这些接口都是可以互queryinterface到的,猜想ms的CoGetInterfaceAndReleaseStream
代码会query吧。所以你才能得到。拿个query不到的接口,肯定报错。

返回S_OK就当它OK了,反正不是开源的东东。谁知道里面啥动作呢 ;)

patchclass 2008-02-20
  • 打赏
  • 举报
回复
多谢 eduyu 我这里实现了,方法是
pDispatch = (LPDISPATCH)this->GetApplication();
hr = CoMarshalInterThreadInterfaceInStream(
IID_IDispatch, // interface ID to marshal
pDispatch, // ptr to interface to marshal
&pStream) ; // output variable
然后调用的时候
hr = CoGetInterfaceAndReleaseStream(
pStream , // stream containing marshaling info
IID_IDispatch, // interface desired
(void **) &pDispatch) ; // output variable

if (hr != S_OK)
{
AfxMessageBox(_T("Couldn't get interface")) ;
} IID_IDispatch
*ppDisp = pDispatch;
效果是可以了,就是担心做的不对,因为其中的 IID_IDispatch 我不知道选的是否正确 用IID_IServiceProvider 或者 IID_IWebBrowser2 ,好像也可以,搞不清楚最后我选择用的是 IID_IWebBrowser2,不知道是否正确?
patchclass 2008-02-20
  • 打赏
  • 举报
回复
多谢 eduyu ,看上去方法一和方法二,貌似都很麻烦,我尝试的写下,另外一个弱弱的问一下 给这个 *ppDisp 这个传递一个 列集后的接口指针 就对了吗?
patchclass 2008-02-19
  • 打赏
  • 举报
回复
多谢eduyu,知道原因了,可是如何简易的解决此问题呢,就是不同线程间打开新窗口,我查了,很少有相关资料,请大家说详细一点,谢谢
eduyu 2008-02-19
  • 打赏
  • 举报
回复
这句话:
*ppDisp = pLastView-> GetApplication();
是把另一个套间线程的接口传给这个套间。
跨套间(此处为单线程套间)传接口要列集。
查CoMarshalInterface

3,055

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC HTML/XML
社区管理员
  • HTML/XML社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧