PRB: ATL IOleInPlaceSite::OnPosRectChange Doesn't Resize Control (242994)
The information in this article applies to:
- The Microsoft Active Template Library (ATL) 3.0, when used with:
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
This article was previously published under Q242994 SYMPTOMS
ActiveX controls hosted in an ATL container are unable to resize themselves dynamically. The container could be a composite control or any window using ATL containment as described in the following Knowledge Base article:
192560 HOWTO: Adding ATL Control Containment Support to Any Window
CAUSE
When an ActiveX control calls IOleInPlaceSite::OnPosRectChange, the container must call the control's IOleInPlaceObject::SetObjectRects to specify the new position of the in-place window and the clip rectangle. Only then does the object resize its window.
The CAxHostWindow implementation of IOleInPlaceSite::OnPosRectChange currently returns E_NOTIMPL, which doesn't give the control the opportunity to resize.
RESOLUTION
This can be worked around by modifying ATLHOST.h and making changes to the OnPosRectChange() function. The function should be changed
such that it calls SetObjectRects() on it's containing control. A sample implementation is as below:
STDMETHOD(OnPosRectChange)(LPCRECT lprcPosRect)
{
ATLTRACE2(atlTraceHosting, 0, _T("IOleInPlaceSite::OnPosRectChange"));
// Use MoveWindow() to resize the CAxHostWindow.
// The CAxHostWindow handler for OnSize() will
// take care of calling IOleInPlaceObject::SetObjectRects().
// Convert to parent window coordinates for MoveWindow().
RECT rect = *lprcPosRect;
ClientToScreen( &rect );
HWND hWnd = GetParent();
// Check to make sure it's a non-top-level window.
if(hWnd != NULL)
{
CWindow wndParent(hWnd);
wndParent.ScreenToClient(&rect);
wndParent.Detach ();
}
// Do the actual move.
MoveWindow( &rect);
return S_OK;
}
Make these modifications to a copy of AtlHost.h, for instance, FixAtlHost.h. Then, in Stdafx.h, comment out AtlHost.h and use FixAtlHost.h instead:
// #include <atlhost.h>
#include "FixAtlHost.h"
This technique will only work in Debug or ReleaseMinDependency builds. It will not work in ReleaseMinSize builds as ATL.dll would be used, not the code in FixAtlHost.h.
REFERENCES
For more information look at the following Web sites:
| Modification Type: | Major | Last Reviewed: | 12/11/2003 |
|---|
| Keywords: | kbATLWC kbCtrlCreate kbprb KbUIDesign KB242994 |
|---|
|