MFC ActiveX 控件在IE下闪烁的问题

这周打算发布公司新版本的OCX,忽然又收到客户报的一个很老的bug,公司的OCX在IE下使用的时候,拉动滚动条会重叠,而且还有很严重的闪烁的现象。上半年的时候已经查过相关资料,没有找到解决方法,而且老大也说这个是微软的一个bug,我们无法解决。有些戏剧性的是,林mm发了一个微软的网页,称那篇文章详细说明了那个bug的问题,让我看一下,,再和客户解释我们为什么不能解决。那个链接是:

认真看了一下,微软是声称那个bug在IE5下是有问题的,可是在IE6下,是已经有办法解决了。

解决第一步,依葫芦画瓢,根据微软说的方法重载了OnSetObjectRects,但是实现为空的,代码如下:

BOOL CmfcaxCtrl::OnSetObjectRects(LPCRECT lpRectPos, LPCRECT lpRectClip) {

return TRUE; }

兴致勃勃的rebuild all,再用IE测试。发现是不闪烁了,可是初始化时被隐藏的那部分照样没刷新,-_-失败告终。

冲击第二步,再认真看了那篇文章,发现有一个注意项:

注意 已更改解决以下 Microsoft 知识库 (KB) 文章中描述的问题: 在 Internet Explorer 中

307978 FIX: 重叠 IFRAME 中的 MFC 控件收到不必要的 WM _ PAINT 消息

点击进去,第二篇文章讲述了OnSetObjectRects的重载方法:

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

再rebuild下,发现外框是不会闪了,但是中间那些view窗口还是能感觉到闪烁,那个方法只是对IE下闪烁问题做了一些缓解,效果还不是很理想。继续再baidu和google,很难找到最有效的解决方法。继续做其他尝试,还是毫无结果。

冲击三,今天无意间又搜到一篇文章,内容和第一篇很像,也是说了OnSetObjectRects的重载方法,代码几乎一模一样,原先还以为微软弄了个冗余的网页,差点忽略过去。那个网页地址为:

本着死马当活马医的思想,又试了一下,原以为会和第二次的结果是一样的,令人惊奇的事情就在意外中发生了。用IE测试的时候,没有闪烁,最小化,很自然的平铺过去了。正当我要欢呼的时候,在StatusBar下面出现了令人恶心的重叠。。。。。继续baidu&&google,无果。。。

在msdn上发现了一个人说把

pOffsetPoint->x = min(0, pPosRect->left – clipLeft); pOffsetPoint->y = min(0, pPosRect->top – clipTop);改一下,改成(0,0)的效果更好些。尝试下,果然,效果非常好。闪烁+重叠的现象都没发现,顿时感到人生真是美好。

那个bug貌似解决了,等测试结果吧。心情一下子开朗了很多,就一个字,爽

不要气馁于那前方的阴影,那只是因为我背后光芒万丈

MFC ActiveX 控件在IE下闪烁的问题

相关文章:

你感兴趣的文章:

标签云: