分类:
2008-10-13 16:08:36
在MDI程序中实现类似WPS2000的文件切换标签
作者:山西大同
用过WPS2000的朋友,肯定对其文件切换功能有很深的印象。当打开多个文件时,他可以使我们快速的切换到指定的文件。本文将详细地说明如何在自己的MDI程序中加入这样一个标签。
图一是本文例子程序运行画面。
图一 例子程序运行画面
开始之前,我们先对WPS2000中的文件切换标签做简单分析,这是一个Tab标签,该标签具有以下功能:
Style: Child Border: Thin 去掉标题条和系统菜单选项; 字体:宋体,字号:10在模板中加入一个Tab标签控件IDC_TAB,按如下设置:
选中按钮选项。//这使的Tab标签呈现按钮风格 选中Hot Track选项。//这使得鼠标移上时文字变蓝仔细调整对话框条及Tab控件的位置、尺寸。创建主框架时,将以该模板创建出Tab标签对话框条。
void CMyTab::OnSelchange(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int idx = GetCurSel(); TC_ITEM ti; ti.mask = TCIF_PARAM; GetItem(idx, &ti); CView * pView = (CView *) ti.lParam; ((CMDIFrameWnd *)AfxGetMainWnd())->MDIActivate((pView->GetParent())->GetParent()); *pResult = 0; *pResult = 0; }4、利用类向导为类CMyTab添加WM_LBUTTONDBLCLK消息映射函数,实现双击时最大化或恢复子窗口,编辑如下:
void CMyTab::OnLButtonDblClk(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default int idx = GetCurSel(); TC_ITEM ti; ti.mask = TCIF_PARAM; GetItem(idx, &ti); CView * pView = (CView *) ti.lParam; ((CMDIFrameWnd *)AfxGetMainWnd())->MDIActivate((pView->GetParent())->GetParent()); // maximize or restore MDIChild window based on its current state BOOL bMaximize=FALSE; CWnd* pActiveWnd=((CMDIFrameWnd *)AfxGetMainWnd())->MDIGetActive(&bMaximize); if(bMaximize) ((CMDIFrameWnd *)AfxGetMainWnd())->MDIRestore(pActiveWnd); else ((CMDIFrameWnd *)AfxGetMainWnd())->MDIMaximize(pActiveWnd); }5、在MainFrm.h中加入:#include "MyTab.h"
protected: CDialogBar m_wndTabBar; public: CMyTab m_MyTab;7、在菜单资源"查看"中加入菜单项"文件切换",ID值为ID_VIEW_TAB_BAR。在MainFrm.cpp中消息映射部分加入以下两行:
ON_COMMAND_EX(ID_VIEW_TAB_BAR, OnBarCheck) ON_UPDATE_COMMAND_UI(ID_VIEW_TAB_BAR, OnUpdateControlBarMenu)8、在CMainFrame::OnCreate()加入以下代码:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) { //向导生成代码略去 //创建TAB条 if (!m_wndTabBar.Create(this, IDD_TAB_DLG_BAR, CBRS_TOP | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_HIDE_INPLACE, ID_VIEW_TAB_BAR)) //ID_VIEW_TAB_BAR是菜单命令ID,用于显示或隐藏对话框条 { TRACE0("Failed to create dialog bar m_wndDialogbar\n"); return -1; // fail to create } //m_wndTabBar.EnableDocking(CBRS_ALIGN_LEFT | CBRS_ALIGN_RIGHT); //EnableDocking(CBRS_ALIGN_ANY); //DockControlBar(&m_wndTabBar); //将m_MyTab与控件IDC_TAB绑定 m_MyTab.SubclassDlgItem(IDC_TAB, &m_wndTabBar); return 0; }9、为类CMainFrame添加WM_SIZE消息映射函数,如下:
void CMainFrame::OnSize(UINT nType, int cx, int cy) { CMDIFrameWnd::OnSize(nType, cx, cy); // TODO: Add your message handler code here CRect rcClient; GetClientRect(&rcClient); int left,top,right,bottom; left=rcClient.left; top=rcClient.top; right=rcClient.right; bottom=rcClient.bottom; m_wndTabBar.MoveWindow(left,top+24,right-left,24,TRUE); CRect rcTab; m_wndTabBar.GetClientRect(&rcTab); CTabCtrl *pMyTab=(CTabCtrl *)(m_wndTabBar.GetDlgItem(IDC_TAB)); pMyTab->MoveWindow(rcTab,TRUE); }三、手工创建类CViewManager
public: CViewManager m_ViewManager;3、在视类TabMDIDemoView.cpp文件中加入:#include "MainFrm.h"
void CTabMDIDemoView::OnInitialUpdate() { CView::OnInitialUpdate(); //取得文档标题及视指针并加入到视管理器数组及tab控件中 CMDIDialogbarDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); CString cs=pDoc->GetTitle(); ((CMainFrame*)AfxGetMainWnd())->m_ViewManager.AddView(cs,this); }5、在视类的析构函数中加入以下代码:
CTabMDIDemoView::~CTabMDIDemoView() { ((CMainFrame*)AfxGetMainWnd())->m_ViewManager.RemoveView(this); }6、重载视类的OnActivateView()函数,编辑如下:
void CTabMDIDemoView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView) { // TODO: Add your specialized code here and/or call the base class ((CMainFrame*)AfxGetMainWnd())->m_ViewManager.OnActivateView(bActivate, this); CView::OnActivateView(bActivate, pActivateView, pDeactiveView); }五、编译