IHTMLDocument2 *pDocument = NULL;
pDocument = (IHTMLDocument2*)m_ie.GetDocument();
if(pDocument)
{
IHTMLWindow2 *pWindow = NULL;
if(SUCCEEDED(pDocument->get_parentWindow(&pWindow)) && pWindow)
{
try
{
pWindow->scrollBy(page.m_scrollH, page.m_scrollV);   //此处异常
}
catch (CMemoryException* e)
{
}
catch (CFileException* e)
{
}
catch (CException* e)
{
}
pWindow->Release();
}
pDocument->Release();
}异常为:中的 0x7e2ace29 处未处理的异常: 0xC0000005: 写入位置 0x0000001b 时发生访问冲突
求解决办法。
初步是想程序可以继续运行下去就行,不要异常退出,就用了个try{}catch{},但是好像不起作用,异常依旧。
另外不太明白,既然正确获得了pWindow,那又为何会scrollBy失败呢?

解决方案 »

  1.   

    中的 0x7e27d332 处未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
      

  2.   

    pWindow 估计不是正确地窗口,换其他方式获取看看
      

  3.   

    本帖最后由 skyxie 于 2010-03-11 12:16:22 编辑
      

  4.   

    增加了catch(...){},但是还是捕获不到。另外page.m_scrollH和page.m_scrollV的值可以确定是正常的
      

  5.   

    确实不在同一个线程中,就是说webbrowser控件和这段代码不在一个线程中。
    请问该怎样更改?
      

  6.   

    在webbrowser线程中 CoMarshalInterThreadInterfaceInStream ,把stream传到这段代码的线程,CoGetInterfaceAndReleaseStream  之后用
      

  7.   

    两种办法,一种PostMessage或SendMessage自定义消息到webbrowser中,在webbrowser中处理这些消息,把你上面的代码写在这些处理函数里,应该就可以了。但这个不合适使用ActiveX控件的程序,因为你没法改动控件的代码。另一种方法,我转篇文章给你吧不要在线程之间传递原始接口指针我咨询的首批COM项目之一就涉及到一个包含100,000行代码的分布式应用程序,该程序是由美国西海岸的一个大型软件公司编写的。该应用程序在多个机器上创建了数十个COM对象,并从客户端进程启动的背景线程中调用这些对象。开发小组遇到问题了,调用要么消失得无影无踪,要么在没有明显原因的情况下失败。他们给我演示的最惊人的症状是:当一个调用无法返回时,在同一台机器上启动其他支持COM的应用程序(包括MicrosoftPaint等)会频繁导致这些应用程序被锁定。检查他们的代码后发现,他们违反了COM并发的一个基本规则,就是说,如果一个线程要与另一个线程共享一个接口指针,它应首先封送该接口指针。如果有必要,封送接口指针可使COM创建一个新的代理(以及一个新的信道对象,将代理和存根结对),以允许从另一个单元向外调用。不通过封送而将原始接口指针(内存中的一个32位地址)传递给另一个线程,会绕过COM的并发机制,并且如果发送和接收的线程位于不同的单元中,将出现各种不良行为。(在Windows2000中,由于两个对象可以共享一个单元,但又位于不同的上下文中,因此如果线程位于同一个单元中,可能会使您陷入困境。)典型的症状包括调用失败和返回RPC_E_WRONG_THREAD_ERROR。WindowsNT4.0和更高版本可以使用一对名为CoMarshalInterThreadInte**ceInStream和CoGetInte**ceAndReleaseStream的API函数,在线程之间轻松地封送接口指针。假定您应用程序中的一个线程(线程A)创建了一个COM对象,继而接收了一个IFoo接口指针,并且同一进程中的另一个线程(线程B)想调用这个对象。在准备将接口指针传递给线程B时,线程A应该封送该接口指针,如下所示:CoMarshalInterThreadInte**ceInStream(IID_IFoo,pFoo,&pStream);在CoMarshalInterThreadInte**ceInStream返回后,线程B就可以安全地取消封送该接口指针:IFoo*pFoo;CoGetInte**ceAndReleaseStream(pStream,IID_IFoo,(void**)&pFoo);在这些示例中,pFoo是一个IFoo接口指针,pStream是一个IStream接口指针。COM在调用CoMarshalInterThreadInte**ceInStream时初始化IStream接口指针,然后在CoGetInte**ceAndReleaseStream内部使用和释放该接口指针。实际上,您通常要使用一个事件或其他同步化基元来协调这两个线程的行为—例如,让线程B知道接口指针已准备好,可以取消封送。请注意,以这种方式封送接口指针不会出现任何问题,因为COM有足够的智能,在不需要进行封送时不会去封送(或重新封送)指针。如果在线程之间传递接口指针时这样做,使用COM就轻松多了。如果调用CoMarshalInterThreadInte**ceInStream和CoGetInte**ceAndReleaseStream看起来太麻烦,您还可以通过将接口指针放在全局接口表(GIT)中,并让其他线程去那里检索它们,从而实现在线程之间传递接口指针。从GIT中检索到的接口指针在被检索时会自动封送。更多信息,请参阅IGlobalInte**ceTable中的文档。
      

  8.   

    用了PostMessage,到主线程中执行这些代码。但是现在错误又转到了delayhlp.cpp中的__delayLoadHelper2函数的pfnRet = ::GetProcAddress(hmod, dli.dlp.szProcName);这一行中
    调用堆栈里是这样显示的:
      kernel32.dll!7c812afb() 
    > mfc90d.dll!__delayLoadHelper2(const ImgDelayDescr * pidd=0x073dfba4, int (void)* * ppfnIATEntry=0x787de970)  行380 + 0xa 字节 C++  WebPageClick.exe!CWebBrowser2::Navigate2(tagVARIANT * URL=BSTR = 0x08a26fb4 "http://ajbone.taobao.com/", tagVARIANT * Flags=Empty, tagVARIANT * TargetFrameName=Empty, tagVARIANT * PostData=Empty, tagVARIANT * Headers=Empty)  行344 + 0x2d 字节 C++