Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

FIX: MFC Controls in Overlapped IFRAMEs Receive Unnecessary WM_PAINT Messages


View products that this article applies to.

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.

↑ Back to the top


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.

↑ Back to the top


Resolution

To 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;
} 
				

↑ Back to the top


Status

Microsoft 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.

↑ Back to the top


More information

Steps to Reproduce Behavior

  1. Create a default MFC ActiveX control.
  2. To modify the OnDraw function, use the following code to display the paint count:
    void CTmpCtrl::OnDraw(
    			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
    {
    	static int count = 0;
    	// TODO: Replace the following code with your own drawing code.
    	pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
    	pdc->Ellipse(rcBounds);
    	CString number;
    	number.Format("%d", count++);
    	pdc->TextOut(10, (rcBounds.bottom - rcBounds.top)/2, number);
    }
    					
  3. Build the MFC ActiveX control. The control automatically registers.
  4. Create a new HTML file named Simple.htm that contains the following code:
    <html>
    <body>
    <textarea style="width: 100%; height: 10%">You can type text in this text area</textarea>
    <iframe src="mfctest.htm" style="top: 300; left: 0; position:absolute"></iframe>
    <iframe src="about:blank" style="top: 300; left: 200; position: absolute"></iframe>
    </body>
    </html>
    					
  5. Create another new HTML file named Mfctest.htm that contains the following code:
    <html>
    <body style="margin:0px;">
    <object
    	classid="clsid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx"
    	height = "100%"
    	width = "100%">
    </object>
    </body>
    </html>
    					
    NOTE: Use the class ID (CLSID) from the .odl file of the ActiveX control. One of the IFRAMEs for Simple.htm is Mfctest.htm.
  6. Double-click Simple.htm, and then type text in the text area. Every time you type, the ActiveX control flickers. Additionally, every time the top frame window is resized, the ActiveX control flickers.
  7. To see how the layout affects the problem, modify the top attributes of one of the IFRAMEs to a value other than 300. Make sure that the IFRAME is not completely covered. Refresh or resize the page. Notice that the frame does not flicker.
NOTE: This problem occurs if one of the dimensions (the width or the height) of the IFRAME that contains the MFC ActiveX control is completely covered by the other IFRAME.

↑ Back to the top


References

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

↑ Back to the top


Properties

Retired KB Content Disclaimer
This article was written about products for which Microsoft no longer offers support. Therefore, this article is offered "as is" and will no longer be updated.

↑ Back to the top


Keywords: KB307978, kbie600sp1fix, kbfix, kbctrlcreate, kbbug

↑ Back to the top

Article Info
Article ID : 307978
Revision : 4
Created on : 5/11/2006
Published on : 5/11/2006
Exists online : False
Views : 295