VC2008特性包中CFormView中使用Group box空间刷新Bug的解决
如果不用特性包,使用经典的风格就不会有这种问题。不然的话就会出现Group box不正常刷新的问题。这个问题在VC2010中解决了。
2008中的解决方案如下:
新建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.
/////////////////////////////////////////////////////////////////////////////////////////////////////
// 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);
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);
}
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);
}
这样就正常了:
![](https://images.cnblogs.com/cnblogs_com/ccbb/%E7%95%8C%E9%9D%A21.png)