导航

如何於 MDI 應用程式中使用 MDI Tab 以及 Tab Group

Posted on 2009-06-12 16:49  Phil Wang  阅读(697)  评论(0编辑  收藏  举报

打從使用 VC++ .Net 2003開始, MDI Tab 以及 MDI Tab Group 這個功能, 我就覺得很好用, 他將 MDI 文件從原本的子視窗管理改為 Tab Window 方式呈現, 使得於同時瀏覽多份文件的狀況下, 變得很方便, 不過要 Implement這個功能就可沒那麼簡單了.

我曾經找過很多 resource, 不用錢的...沒找到, 要錢買的, 有 Codejock 的 Xtreme Pro, BCGSoft 的 BCGControlBar Pro, 而 Pro-UIS 雖然有支援 MDI Tabbed 功能, 但 MDI Tab Group 的功能就一直沒看到 (還是我不會用??), 不過拜 VC++2008 Feature Pack的恩典, 現在不用額外加錢就有了. 以下簡單說明其用法.

1. 先建立 MDI Tab的Popup menu以及Drag Tab 的 Popup menu.

MDI Tab上按加鍵所 Popup 的menu 定為 "IDR_POPUP_MDITABS_MENU"

裡面的Item 定義如下.

New Horizontal Tab Group -- ID_MDI_NEW_HORZ_TAB_GROUP

New &Vertical Tab Group -- ID_MDI_NEW_VERT_GROUP

Move to Ne&xt Tab Group -- ID_MDI_MOVE_TO_NEXT_GROUP

Move to P&revious Tab Group -- ID_MDI_MOVE_TO_PREV_GROUP

而拖放 MDI Tab 到另一個 Tab group 時所顯示的 Popup menu 定為 "IDR_POPUP_DROP_MDITABS_MENU"

其包含的項目為

New &Horizontal Tab Group -- ID_MDI_NEW_HORZ_TAB_GROUP

New &Vertical Tab Group -- ID_MDI_NEW_VERT_GROUP

Move to Ne&xt Tab Group -- ID_MDI_MOVE_TO_NEXT_GROUP

Move to P&revious Tab Group -- ID_MDI_MOVE_TO_PREV_GROUP

&Cancel -- ID_MDI_CANCEL

建好兩個 Popup menu 的 resource後, 於 MainFrm.cpp 建立其對應的 Event Handle.

首先是 "OnShowMDITabContextMenu" , 他是一個 Virtual function.

MainFrm.h 定義如下

protected :

    virtual BOOL OnShowMDITabContextMenu(CPoint point, DWORD dwAllowedItems, BOOL bDrop);

Implementation如下

BOOL CMainFrame::OnShowMDITabContextMenu(CPoint point, DWORD dwAllowedItems, BOOL bDrop)

{
 CMenu menu;
 VERIFY(menu.LoadMenu(bDrop ? IDR_POPUP_DROP_MDITABS : IDR_POPUP_MDITABS));

 CMenu* pPopup = menu.GetSubMenu(0);
 ASSERT(pPopup != NULL);

 if (pPopup)
 {
  if ((dwAllowedItems & AFX_MDI_CREATE_HORZ_GROUP) == 0)
  {
   pPopup->DeleteMenu(ID_MDI_NEW_HORZ_TAB_GROUP, MF_BYCOMMAND);
  }

  if ((dwAllowedItems & AFX_MDI_CREATE_VERT_GROUP) == 0)
  {
   pPopup->DeleteMenu(ID_MDI_NEW_VERT_GROUP, MF_BYCOMMAND);
  }

  if ((dwAllowedItems & AFX_MDI_CAN_MOVE_NEXT) == 0)
  {
   pPopup->DeleteMenu(ID_MDI_MOVE_TO_NEXT_GROUP, MF_BYCOMMAND);
  }

  if ((dwAllowedItems & AFX_MDI_CAN_MOVE_PREV) == 0)
  {
   pPopup->DeleteMenu(ID_MDI_MOVE_TO_PREV_GROUP, MF_BYCOMMAND);
  }

  if ((dwAllowedItems & AFX_MDI_CAN_BE_DOCKED) == 0)
  {
   pPopup->DeleteMenu(ID_MDI_TABBED_DOCUMENT, MF_BYCOMMAND);
  }

  CMFCPopupMenu* pPopupMenu = new CMFCPopupMenu;
  if (pPopupMenu)
  {
   pPopupMenu->SetAutoDestroy(FALSE);
   pPopupMenu->Create(this, point.x, point.y, pPopup->GetSafeHmenu());
  }
 }

 return TRUE;
}

這樣就建好 Popup menu. 接下來是 Implement 產生 MDI Tab Group 的 function. 將 Popup menu 的 resource open 出來, 按右鍵分別點選各item, 於 Popup menu 選擇 "Add Event Handle..", 幫每一個項目建立對應 Event Handle function. 如下圖所示.

Event function 建好後,

只要於OnMdiNewVertGroup() 加入 MDITabNewGroup(); 這個function call ,建立垂直的 Tab group 功能就完成,

而OnMdiNewHorzTabGroup() 加入MDITabNewGroup(FALSE); 則是建立水平 Tab group.

以上就是MDI Tab Group 的做法, 十分簡單, 只要安裝 VC++2008 Feature pack 就萬事 O.K.

詳細Sample code 可參考 VisualStudioDemo 這個 project.