zoukankan      html  css  js  c++  java
  • About SetClientSite in ActiveX

    PRB: ActiveX Control Window Is Not Created Until Visible in Internet Explorer

    Article ID: 195188 - View products that this article applies to.

    This article was previously published under Q195188

    Expand all | Collapse all

    On This Page

    SYMPTOMS

    An ActiveX control's WM_CREATE handler is not called in Internet Explorer 4.01 until the control is scrolled into view (in MFC, OnCreate() is the WM_CREATE handler). The same problem occurs if the control has a size of 0,0. If you are creating child windows in your WM_CREATE handler, they won't exist. If you have an automation method that is called from script (in Window_Onload for example) that manipulates the control's HWND or its child windows, you will get an ASSERT in debug mode on a line in MFC that reads the following:

    ASSERT(::IsWindow(m_hWnd));
    

    or in ATL:

    ATLASSERT(::IsWindow(m_hWnd));
    

    Back to the top | Give Feedback

    CAUSE

    Internet Explorer 4.01 does not in-place activate controls until they are visible. This is an optimization to reduce memory consumption and speed up load times for Web pages with ActiveX controls. Most ActiveX control frameworks like MFC and ATL create their control window during in-place activation. So unless a control is visible, it won't be in-place activated. If it's not in-place activate, it won't be created. If it's not created, the WM_CREATE handler is not called.

    Back to the top | Give Feedback

    RESOLUTION

    You can workaround this by creating the control window in IOleObject::SetClientSite(), which is always called regardless if the control is in-place activated.

    MFC
    MFC provides a function called COleControl::CreateControlWindow() to create the control's window. MFC's implementation of IOleObject::SetClientSite() calls COleControl::OnSetClientSite(). Add the following to your COleControl-derived class:

    // CMyControl is derived from COleControl.
    
       void CMyControl::OnSetClientSite()
    
       {
    
          if (m_pClientSite)
    
             // It doesn't matter who the parent window is or what the size of
    
             // the window is because the control's window will be reparented
    
             // and resized correctly later when it's in-place activated.
    
             VERIFY (CreateControlWindow (::GetDesktopWindow(), CRect(0,0,0,0),
    
                                          CRect(0,0,0,0)));
    
          COleControl::OnSetClientSite();
    
       }
    

    ATL
    ATL also provides a function called CComControl::CreateControlWindow(). But it won't re-parent the window later so the control needs to manually do this during in-place activation (CComControlBase::InPlaceActivate). Add the following to the declaration of your CComControl-derived class (typically in the class header file):

    // CMyControl is derived from CComControl
    
       STDMETHOD(SetClientSite)(IOleClientSite *pClientSite)
    
       {
    
          if (pClientSite)
    
          {
    
             RECT rc = {0,0,0,0};
    
             // Don't have access to the container's window so just use the
    
             // desktop.  Window will be resized correctly during in-place
    
             // activation.
    
             HWND hWnd = CreateControlWindow(::GetDesktopWindow(), rc);
    
             _ASSERT (hWnd);
    
          }
    
          return IOleObjectImpl<CMyControl>::SetClientSite (pClientSite);
    
       }
    
       HRESULT InPlaceActivate(LONG iVerb, const RECT* prcPosRect)
    
       {
    
          // Get the container's window.
    
          _ASSERT (m_spClientSite);
    
          LPOLEINPLACESITE pInPlaceSite = NULL;
    
          HRESULT hr = m_spClientSite->QueryInterface(IID_IOleInPlaceSite,
    
                                                      (void       **)&pInPlaceSite);
    
          _ASSERT (SUCCEEDED (hr) && pInPlaceSite);
    
          HWND hParent = NULL;
    
          hr = pInPlaceSite->GetWindow (&hParent);
    
          _ASSERT (SUCCEEDED (hr) && hParent);
    
          pInPlaceSite->Release ();
    
          // Set container window as our parent window
    
          SetParent (hParent);
    
          return CComControlBase::InPlaceActivate(iVerb, prcPosRect);
    
       }
    

    Back to the top | Give Feedback

    STATUS

    This behavior is by design. Beginning with Internet Explorer 5, Internet Explorer should always in-place activate controls, whether or not they are visible.

    Back to the top | Give Feedback

    MORE INFORMATION

    An ActiveX control can be redesigned to not require a window at all times. Initialization code can be moved out of OnCreate to COleControl::OnSetClientSite (MFC) or CComControl::SetClientSite (ATL). Automation methods can be rewritten either to not use a window for storage and functionality, to fail silently until the control is visible, or to queue up requests for processing when the window is available.
    Windowless controls, a form of control supported in Internet Explorer 4.x and Visual C++ 4.2 or higher, take the first approach. Windowless controls have speed and memory benefits over ordinary windowed ActiveX controls, in addition to allowing transparency effects when hosted in Internet Explorer 4.x.
    However, it may be extremely difficult or impossible to redesign existing controls to work in these conditions. Some controls would require too much extra code to work effectively without a window. For such controls, you can use the workaround in the RESOLUTION section.
    If the ActiveX control is positioned on a visible part of the HTML page, but the control's window is still not being created, that is a different issue from the one discussed in this article. The control may be a windowless control by default.

    Back to the top | Give Feedback

    REFERENCES

    For more information about developing Web-based solutions for Microsoft Internet Explorer, visit the following Microsoft Web sites:

    http://msdn.microsoft.com/ie/
    http://support.microsoft.com/iep

    Back to the top | Give Feedback

    Properties

    Article ID: 195188 - Last Review: May 11, 2006 - Revision: 2.0

    APPLIES TO
    • Microsoft Internet Explorer 4.01 Service Pack 2
    • Microsoft Internet Explorer 4.01 Service Pack 1
    • Microsoft Internet Explorer 4.01 Service Pack 2
    • Microsoft ActiveX Template Library 3.0, when used with:
      • Microsoft Visual C++ 5.0 Enterprise Edition
      • Microsoft Visual C++ 6.0 Enterprise Edition
      • Microsoft Visual C++ 5.0 Professional Edition
      • Microsoft Visual C++ 6.0 Professional Edition
      • Microsoft Visual C++, 32-bit Learning Edition 6.0
    • Microsoft Foundation Class Library 4.2, when used with:
      • Microsoft Visual C++ 5.0 Enterprise Edition
      • Microsoft Visual C++ 6.0 Enterprise Edition
      • Microsoft Visual C++ 5.0 Professional Edition
      • Microsoft Visual C++ 6.0 Professional Edition
      • Microsoft Visual C++, 32-bit Learning Edition 6.0
  • 相关阅读:
    matlab学习笔记第十章——曲线拟合
    matlab学习笔记第九章——变换
    matlab学习笔记第八章——积分
    matlab学习笔记第七章——常微分方程(ODE)的数值解
    matlab学习笔记第六章——基本符号演算和微分方程
    matlab学习笔记第五章——代数方程求解和其他符号工具
    javaScript中奇葩的假值
    对于javaScript闭包,立即执行函数的用法的一些理解
    Jquery——简单的视差滚动效果,兼容PC移动端
    网站前端开发与动画相关常见问题解答
  • 原文地址:https://www.cnblogs.com/crunchyou/p/2620097.html
Copyright © 2011-2022 走看看