FIX: MFC Controls in Overlapped IFRAMEs Receive Unnecessary WM_PAINT Messages (307978)
The information in this article applies to:
- Microsoft Internet Explorer (Programming) 5.5
- Microsoft Internet Explorer (Programming) 6.0
This article was previously published under Q307978 SYMPTOMS When a Microsoft Foundation Classes (MFC) ActiveX control
appears in an IFRAME that is partially covered by another IFRAME in the same
Hypertext Markup Language (HTML) page, the ActiveX control receives unnecessary
WM_PAINT messages. The unnecessary WM_PAINT messages occur when other parts of the HTML page are updated.
CAUSE MFC ActiveX controls include dual windows: a child window
and a parent window. The parent window is used for notification. If the IFRAME
that contains an MFC ActiveX control is completely covered in one dimension,
the parent window is resized to the size of the control (including the clipped
portion that is outside the boundaries of the IFRAME). The parent window
returns to the clip area size whenever the page is updated. The resizing
generates the extra WM_PAINT messages. RESOLUTIONTo resolve this problem, obtain the latest
service pack for Internet Explorer 6. For additional information, click the
following article number to view the article in the Microsoft Knowledge Base: 328548 How to Obtain the Latest Internet Explorer 6 Service Pack
To work around this problem, modify the OnSetObjectRects function to ignore the resizing. For example:
// Code in the header file:
virtual BOOL OnSetObjectRects(LPCRECT lpRectPos, LPCRECT lpRectClip);
// Code in the implementation file:
#include <afxpriv2.h>
#include <..\src\afximpl.h>
#include <..\src\ctlimpl.h>
void MyGetClippingCoordinates(LPCRECT pPosRect, LPCRECT pClipRect,
LPRECT pIntersectRect, LPPOINT pOffsetPoint)
{
int clipLeft = 0;
int clipTop = 0;
if ((pClipRect == NULL) || IsRectEmpty(pClipRect))
{
CopyRect(pIntersectRect, pPosRect);
}
else
{
IntersectRect(pIntersectRect, pPosRect, pClipRect);
clipLeft = pClipRect->left;
clipTop = pClipRect->top;
}
pOffsetPoint->x = min(0, pPosRect->left - clipLeft);
pOffsetPoint->y = min(0, pPosRect->top - clipTop);
}
BOOL CTmpCtrl::OnSetObjectRects(LPCRECT lprcPosRect, LPCRECT lprcClipRect)
{
// return COleControl::OnSetObjectRects(lprcPosRect, lprcClipRect);
ASSERT(lprcPosRect != NULL);
// Remember the position rectangle.
m_rcPos = *lprcPosRect;
// Calculate complete rectangle, include the tracker if it is present.
CRect rectPos = m_rcPos;
if (m_bUIActive && m_pRectTracker != NULL)
{
// Save new clipping rectangle (for DestroyTracker).
if (lprcClipRect != NULL)
m_pRectTracker->m_rectClip = *lprcClipRect;
// Adjust tracker rectangle to new dimensions.
CRect rectTmp = rectPos;
rectTmp.OffsetRect(-rectTmp.left, -rectTmp.top);
m_pRectTracker->m_rect = rectTmp;
// Adjust the "true" rectangle to include handles/hatching.
UINT nHandleSize = m_pRectTracker->m_nHandleSize - 1;
rectPos.InflateRect(nHandleSize, nHandleSize);
}
// Now clip the rectangle as appropriate.
CRect rectClip;
MyGetClippingCoordinates(rectPos, lprcClipRect, rectClip, &m_ptOffset);
// Move the outer window first, and then move the inner window.
if (!m_bInPlaceSiteWndless)
{
CWnd* pWndOuter = GetOuterWindow();
//BEGIN CHANGE.
if (pWndOuter != NULL)
{
static CRect oldClipRect(0, 0, 0, 0);
if (oldClipRect != rectClip)
::MoveWindow(pWndOuter->m_hWnd,
rectClip.left, rectClip.top,
rectClip.Width(), rectClip.Height(),
TRUE);
oldClipRect = rectClip;
}
//END CHANGE.
if (pWndOuter != this)
MoveWindow(m_ptOffset.x, m_ptOffset.y,
rectPos.Width(), rectPos.Height());
}
return TRUE;
}
STATUSMicrosoft has confirmed that this is a bug in the Microsoft
products that are listed at the beginning of this article.
This problem was first corrected in Internet Explorer 6
Service Pack 1.REFERENCESFor more
information about developing Web-based solutions for Microsoft Internet
Explorer, visit the following Microsoft Web sites:
Modification Type: | Major | Last Reviewed: | 5/11/2006 |
---|
Keywords: | kbBug kbCtrlCreate kbfix kbIE600sp1fix KB307978 |
---|
|