传统地,Tab控件在切换Tab页时,需要切换页相对应的子窗体的隐藏与显示。单独对子窗体控制,略显繁杂。
本文采取如下思路: 将诸子窗体放到某个承载窗体(比如CWnd类型或者CDialog类型对象)上,在Tab切换时,操控承载窗体的显隐即可达到目的。
又传统地,程序需要维护一个对象数组,每个对象用于维护Tab和承载窗体或子窗体之间的关系;而本文采取如下方法:利用TCITEM结构体的lParam字段存储对应承载窗体的句柄。这样即可构建对应关系。
本例所需类:
1、CMainFrame
2、CChildView : public CWnd
3、CTabCtrl,此处亦作TabCtrl,因大部分属性对于Win32对象亦适用。
4、CDialog 作为承载窗体若干,用CDialog的好处在于,可以直接利用resource template,便于在工程rc中设计控件位置等。
步骤:
一、以VC的Application Wizard创建一个MFC exe-〉SDI-〉no Document/View,那么即具备以上1、2两对象,、
二、在2中定义一成员变量,类型为3、
三、在资源rc中画好对话框,并制定相应resource ID
四、重载2 (CChildView)的LRESULT CChildView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam),处理消息
WM_CREATE,创建TabCtrl、承载窗体,后者在此挂上资源;
WM_NOTIFY,遍历所有与TabCtrl相关的承载窗体,显示当前选中Tab对应的个体,其他个体隐藏;
WM_SIZE,调整TabCtrl的大小以适应CChildView,调整承载窗体的大小适应TabCtrl的Display Area

















FormView1.Create (IDD_FORMVIEW1,&m_Tab);//MUST like this, if do like above, will occur some problem described in comment1






































PointC:





































那么在模拟单击某个Tab页的动作,代码为:
m_wndView.m_Tab.SetCurSel(1);
NMHDR nh;
nh.hwndFrom=m_wndView.m_Tab.m_hWnd;
nh.idFrom=IDC_TABCTRL;
nh.code=TCN_SELCHANGE;
m_wndView.SendMessage(WM_NOTIFY,IDC_TABCTRL,(LPARAM)&nh);
假设动态地创建了多个Tab,其中一些可能对应某个Dialog派生类,那么如果需要查找某个特定的Dialog就必须仰赖MFC的RTTI和Dialog某甄别字段。如下例展示查找一个Dialog并将其杀掉,将界面切换至第1个(zero based index)Tab。
void CMainFrame::KillDialingPad(CString StrContactName)
{
CWnd* pWnd;
HWND hWnd;
TCITEM ItemTemp;
int i=0;
for (i=1;i<m_wndView.m_Tab.GetItemCount();i++)//start from 1, avoid searching from the CONTACT LIST
{
m_wndView.m_Tab.GetItem(i,&ItemTemp);
hWnd=(HWND)ItemTemp.lParam;
pWnd=CWnd::FromHandle(hWnd);//avoid to bring a new CWnd object;
if (pWnd->IsKindOf(RUNTIME_CLASS(CDialingBoxDlg)))
{
if(((CDialingBoxDlg *)pWnd)->m_StrContactName==StrContactName)
break;
}
}
if(i<m_wndView.m_Tab.GetItemCount())//found
{
pWnd->DestroyWindow();
delete pWnd;
pWnd=NULL;
m_wndView.m_Tab.DeleteItem(i);
}
m_wndView.m_Tab.SetCurSel(1);
NMHDR nh;
nh.hwndFrom=m_wndView.m_Tab.m_hWnd;
nh.idFrom=IDC_TABCTRL;
nh.code=TCN_SELCHANGE;
m_wndView.SendMessage(WM_NOTIFY,IDC_TABCTRL,(LPARAM)&nh);
}