none
IE中对ActiveX的处理和生命周期,请ActiveX高手进。 RRS feed

  • 问题

  • 我们想知道IE中是怎么处理ActiveX控件的加载,卸载,在整个IE网页的切换中,调用那些接口,调用的顺序怎么样?有哪些需要遵循的规则?

    具体说,现在我们在切换带我们自己的ActiveX控件页面时,存在一些问题。
    先介绍一下我们的设计思路:
    我们在CDialogDlg : public CDialog中定义了两个空间CWebBrowser2:
     CWebBrowser2 m_ie1;
     CWebBrowser2 m_ie2;

    CDialogDlg::Navigate成员函数中交替调用
    m_ie1->Navigate(...);
    m_ie2->Navigate(...);
    以实现双页面缓冲,其中我们要显示的页面都有我们自己的ActiveX控件。

    现在的问题是:
    1. 在有些情况下,我们会出现页面切换的死锁现象,就是页面再也不能切换了。
    2. 在有些情况下,我们很出现CDialogDlg进程CPU占用接近100%,页面刷新很慢,页面都是一点一点跳着刷出来。
        一般在启动时就会出现,但有时候却正常。

    请高手指点迷津。

    2009年3月9日 4:36

答案

  • 1 不要在相应COM事件时等待
    2 需要提供重现问题的步骤。

    MSMVP VC++
    2009年3月9日 17:40
    版主
  • 试一下
    1 把整个CDialogDlg放到一个线程中,并初始化为STA模型。
    2 保证在CWebBrowser2 的Navigate调用结束后再进行第二次调用。

    2009年3月10日 2:43
    版主

全部回复

  • 1 不要在相应COM事件时等待
    2 需要提供重现问题的步骤。

    MSMVP VC++
    2009年3月9日 17:40
    版主
  • 试一下
    1 把整个CDialogDlg放到一个线程中,并初始化为STA模型。
    2 保证在CWebBrowser2 的Navigate调用结束后再进行第二次调用。

    2009年3月10日 2:43
    版主
  •  我碰到的是我在一个IE控件中连续加载不同的页面,页面加载的时候像滚窗帘那样慢慢出来的。在CSDN见识过您的水平,请您指点。
    2009年3月10日 8:10
  • Sheng Jiang 蒋晟 说:

    1 不要在相应COM事件时等待

    2 需要提供重现问题的步骤。

    MSMVP VC++



     我碰到的是我在一个IE控件中连续加载不同的页面,页面加载的时候像滚窗帘那样慢慢出来的。在CSDN见识过您的水平,请您指点。
    2009年3月10日 8:11
  • 谢谢两位专家!如果问题解决一定会在此回复。

    具体的实际问题确实很难用一两句话说清楚,我想先问几个比较通用的基础问题:

    1. 在页面加载的时候,CWebBrowser2何时加载和卸载ActiveX控件?此过程是否一定会调用OnSetClientSite函数?如果加载卸载时发生异常会如何?

    2. 为了在ActiveX中接收CWebBrowser2事件,在OnSetClientSite中使用AfxConnectionAdvise,AfxConnectionUnadvise连接DWebBrowserEvents2来交互是否为最合理方案?如何知道页面加载完成?

    3. 在ActiveX控件中,如何获取IID_IWebBrowser2?在OnSetClientSite中用以下方式有什么问题?

    void CMyActiveXCtrl::OnSetClientSite()
    {
     // m_pClientSite is a pointer to IOleClientSite.
     // This is the client site for your control.
     //

     ::Sleep(10);

     if (m_pClientSite == NULL)
     {// 卸载操作中

      if(m_pWebBrowser != NULL)
      {// 已经取得了浏览器的指针
       AfxConnectionUnadvise(m_pWebBrowser, __uuidof(SHDocVw::DWebBrowserEvents2),
       m_IESink.GetIDispatch(FALSE), FALSE, m_dwCookie);

       COMRELEASE(m_pWebBrowser);
      }
      __super::OnSetClientSite();

      return ;
     }

     HRESULT hr = S_OK;
     IServiceProvider *isp, *isp2 = NULL;
     
     hr = m_pClientSite->QueryInterface(IID_IServiceProvider, reinterpret_cast<void **>(&isp));
     if (FAILED(hr))
     {
      hr = S_OK;
      goto cleanup;
     }
     hr = isp->QueryService(SID_STopLevelBrowser, IID_IServiceProvider, reinterpret_cast<void **>(&isp2));
     if (FAILED(hr))
     {
      hr = S_OK;
      goto cleanup;
     }
     hr = isp2->QueryService(SID_SWebBrowserApp, IID_IWebBrowser2, reinterpret_cast<void **>(&m_pWebBrowser));
     if (FAILED(hr))
     {
      hr = S_OK;
      goto cleanup;
     }

     AfxConnectionAdvise(m_pWebBrowser,
      __uuidof(SHDocVw::DWebBrowserEvents2),
      m_IESink.GetIDispatch(FALSE), FALSE, &m_dwCookie);

     // COleControl::OnSetClientSite();
    cleanup:
     // Free resources.
     COMRELEASE(isp);
     COMRELEASE(isp2);
     __super::OnSetClientSite();

     return;
    }

    2009年3月10日 8:42
  • 页面加载的时候浏览器控件已经加载结束,所以没有涉及到浏览器控件的加载或者卸载。如果页面中有ActiveX控件,那么会随HTML文档加载和卸载。每次页面刷新都会重建HTML文档。
    如果你在IE控件内连续加载页面,记得在加载下一个Url之前调用IWebBrowser2::Stop。
    没有看出有必要在页面中的ActiveX控件中捕获浏览器控件事件的必要。页面中的ActiveX控件生命期太短。


    MSMVP VC++
    2009年3月10日 13:50
    版主
  •  To Sheng Jiang 蒋晟:
        感谢你的回答。我的页面上有一个ActiveX 控件,这个控件在页面加载起来后会创建一个线程。如果我调用了 IWebBrowser2::Stop ,    那么这个线程的状态会如何?是被挂起了,还是继续运行,还是不同版本的IE有不同的行为?
    2009年3月11日 1:26
  • CDialogDlg进程CPU占用接近100%,页面刷新很慢的发生情况:
    在一开始OnInitDialog的时候,我们调用Navigate(...)显示初始启动页面就会发生,以后就后续所有页面的也是这种情况了,很慢了。
    我们在OnInitDialog调用了其他一些m_ie1和m_ie2的Create函数。


    会不会我们也是在OnInitDialog做了什么操作,引起MS的BUG,导致页面刷新很占资源,很慢?

    我本来觉得是在我们Navigate(...)或刷新时候有另外的线程因为循环占用了资源导致。
    但现在看来,也有可能是某些消息(类似WM_PAINT)导致页面频繁刷新导致?

    请高手指点什么情况MS会有这种刷新占系统资源问题?特别是OnInitDialog里面做什么操作会引起这样的情况。
    2009年3月14日 6:50
  •   不要在相应COM事件时等待不是很理解,能不能再解释一下?

    CWebBrowser2和MyActiveX控件的COM事件吗?那些哪些事件不要等待?
    不要等待是不是指不要WaitForSingleObject等待?Sleep(x)是不是可以?
    2009年3月15日 13:31
  • 比如在一个STA套间内等待一个内核句柄或者一个对话框。
    MSMVP VC++
    2009年3月16日 1:47
    版主