CMFCTabCtrl的几个刷新BUG解决办法

时间:2023-02-07 23:50:15

问题1:

懒的打字了。看图吧;


CMFCTabCtrl的几个刷新BUG解决办法


如果上图,把对话框创建到CMFCTabCtrl上后对话框上的控件显示位置不对(全部跑到了左上角),而在Debug模式下,则不会有此问题;

下图是Debug模式的控件显示位置:

CMFCTabCtrl的几个刷新BUG解决办法


捣鼓了半天终于试出了了解决方法;

贴代码了。

#define CreateChildConfigTab( Name, ClassName )do{\
CDialog *pChildDlg = new ClassName( /* 空参数,不传递父窗口句柄 */ );\
ASSERT( pChildDlg != NULL );\
/* 创建对话框时不要把父窗口指定为CMFCTabCtrl窗口,而是指定为桌面 */\
pChildDlg->Create( ClassName::IDD, CWnd::GetDesktopWindow() );\
ASSERT( IsValidWindow( pChildDlg ) );\
/* CMFCTabCtrl m_ctlPage */\
/* m_ctlPage是CCMFCTabCtrl类的对象 */\
m_ctlPage.Add( pChildDlg, (Name));\
/* 最后把pChildDlg的父窗口改回CMFCTabCtrl即可 */\
pChildDlg->SetParent( &m_ctlPage );\
}while(0)

问题2:

如果把CListCtrl或CTreeCtrl之类的控件直接放到CMFCTabCtrl则可能导致其子窗口无法收到部分WM_PAINT消息。

解决办法也很简单:

……

算了,还是贴代码方便;


namespace{
class CMFCTabCtrlEx : public CMFCTabCtrl
{
virtual LRESULT WindowProc( UINT message, WPARAM wParam, LPARAM lParam )
{
LRESULT l = __super::WindowProc( message, wParam, lParam );

switch( message )
{
case WM_PAINT:
{
if( !RedrawActiveWindow() ){
TRACE( "Warning: CMFCTabCtrlEx::WM_PAINT 消息没能正确刷新子窗口\n" );
}
}
break;
}

return l;
}

virtual BOOL SetActiveTab( int iTab )
{
BOOL bResult = __super::SetActiveTab( iTab );

if( !RedrawActiveWindow() ){
TRACE( "Warning: CMFCTabCtrl::SetActiveTab 没有正确刷新子窗口\n" );
}

return bResult;
}

_Check_return_ BOOL RedrawActiveWindow()
{
CWnd *pActiveWnd = GetActiveWnd();

if( pActiveWnd != NULL )
{
if( IsWindow( pActiveWnd->GetSafeHwnd() ) ){
return PSTMSG( pActiveWnd->GetSafeHwnd(),
WM_PAINT,
NULL,
NULL );
}
}

return FALSE;
}
};
}


另外不得不说,CSDN上流传的基本都是最傻B的方法,当然我也在用……

再废话一句,xhEditor真恶心。


.fuhao

.2015年1月14日17时15分

<mail> :503267714@qq.com