VC2008特性包中CFormView中使用Group box空间刷新Bug的解决

如果不用特性包,使用经典的风格就不会有这种问题。不然的话就会出现Group box不正常刷新的问题。这个问题在VC2010中解决了。

2008中的解决方案如下:

参考:http://connect.microsoft.com/VisualStudio/feedback/details/404296/cformview-with-group-box-display-issues-for-both-transparent-and-non-transparent-group-boxes

新建ClipStyleReset.h文件,并且写入一下类代码:

/////////////////////////////////////////////////////////////////////////////////////////////////////
// This code exists to work around an MFC bug.
//
// see Microsoft Connect issue 404296 -- CFormView with Group Box display issues for both transparent and non-transparent Group Boxes
//                                     Microsoft claims that the problem will be fixed in VS 2010.
//
// The problem is that CMDIChildWndEx::AdjustClientArea sets the WS_CLIPCHILDREN and sometimes WS_CLIPSIBLINGS windows
// styles and leave them set. This causes group boxes to disappear (see "PRB: BS_GROUPBOX-Style Child Window Background Painting Wrong"
// at http://support.microsoft.com/kb/79982). Unfortunately AdjustClientArea is not a virtual function, so we can't easily overload it.
// To work around the problem code has been added to save the window style and then restore it after calls to AdjustDockingLayout
// and RecalcLayout both of which are virtual and which call AdjustClientArea.

#include 
<afxDockablePane.h>

// This helper class is used to save the window style and then restore the WS_CLIPCHILDREN and WS_CLIPSIBLINGS flags.
class ClipStyleReset
{
public:

    ClipStyleReset(CMDIChildWndEx 
* p_pMDIChildWndEx)
        : m_pChildWnd(NULL)
        , m_dwChildStyle(
0)
    {
        
// Get a pointer to the window that CMDIChildWndEx::AdjustClientArea will change the windows style on.
        
// This logic is copied directly from CMDIChildWndEx::AdjustClientArea.
        CDockablePane * pTabbedControlBar = p_pMDIChildWndEx->GetTabbedPane();

        m_pChildWnd 
= (pTabbedControlBar != NULL && pTabbedControlBar->IsMDITabbed() &&
            pTabbedControlBar
->GetParent() == p_pMDIChildWndEx) ? pTabbedControlBar : p_pMDIChildWndEx->GetDlgItem(AFX_IDW_PANE_FIRST);

        
// If there is a child window, save its style.
        if (m_pChildWnd != NULL)
        {
            m_dwChildStyle 
= m_pChildWnd->GetStyle();
        }
    }

    
~ClipStyleReset()
    {
        
if (m_pChildWnd != NULL)
        {
            
// If there is a child window, restore the flags that may have changed.
            m_pChildWnd->ModifyStyle(
                WS_CLIPCHILDREN 
| WS_CLIPSIBLINGS,
                (WS_CLIPCHILDREN 
| WS_CLIPSIBLINGS) & m_dwChildStyle
                );
        }
    }

private:

    CWnd 
*    m_pChildWnd;
    DWORD    m_dwChildStyle;
};

// End MFC bug work around.
/////////////////////////////////////////////////////////////////////////////////////////////////////

在stdafx.h中加入:#include "ClipStyleReset.h"

然后在ChildFrm.h中加入两个方法声明:

void AdjustDockingLayout(HDWP hdwp);
void RecalcLayout(BOOL bNotify);

然后在ChildFrm.cpp中加入如下的代码:

// Overloaded to fix a MFC bug.
void CChildFrame::AdjustDockingLayout(HDWP hdwp)
{
    ClipStyleReset reset(
this);
    CMDIChildWndEx::AdjustDockingLayout(hdwp);
}

// Overloaded to fix a MFC bug.
void CChildFrame::RecalcLayout(BOOL bNotify)
{
    ClipStyleReset reset(
this);
    CMDIChildWndEx::RecalcLayout(bNotify);
}

这样就正常了:

 

posted @ 2010-04-23 10:39  InfantSorrow  阅读(1909)  评论(0编辑  收藏  举报