PRB: ActiveX Control Window is not Created Until Visible in IEID: Q195188
|
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));
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.
You can workaround this by creating the control window in IOleObject::SetClientSite(), which is always called regardless if the control is in-place activated.
// 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();
}
// 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);
}
This behavior is by design.
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.
For more information, please see the MSDN Web Workshop:
http://msdn.microsoft.com/workshop/default.asp(c) Microsoft Corporation 1998, All Rights Reserved. Contributions by Samson Tanrena, Microsoft Corporation.
Additional query words:
Keywords : kbActiveX kbCtrl kbIE400 kbIE401 kbInternet kbDSupport
Version : WINDOWS:3.0,4.01,4.01 SP1,5.0dp1; winnt:5.0,6.0
Platform : WINDOWS winnt
Issue type : kbprb
Last Reviewed: July 22, 1999