Folder Tab Control for Windows MFC (like MS Excel)





5.00/5 (10 votes)
Oct 6, 2003
1 min read

220182

4944
Folder Tab control for Windows MFC (like MS Excel).
Introduction
This is a folder tab window control for MFC. It looks and acts very much like the folder tab control for MS Excel, except it does not allow re-ordering of the folder tabs. It has a first button for the first tab, a next button for the next tab, a last button for the last tab and a previous button for the previous tab. You can also rename the folder tabs and delete/add new tabs interactively.
Paul DiLascia at MSDN magazine originally wrote this code in 3 separate issues of MSDN ( the last article was in the October 2002 issue). I just added the first and last buttons and the tab renaming capability.
Using the code
Paul wrote a FolderFrame.cpp class for handling the view of this class automatically. However, my view is a diagramming toolkit with zoom and pan that requires a lot of view specific code, so I do not use his FolderFrame
class.
To include this control in my app, I just added it to my View
class:
#include "ftab.h"
CFolderTabCtrl FolderTabs;
Then I created it in my OnCreate
method:
// create the folder tabs window CFolderTabCtrl& ftc = FolderTabs; VERIFY (ftc.Create (WS_CHILD|WS_VISIBLE, rc, this, 1, FTS_BUTTONS));
Then I draw it in my OnDraw
method along with my horizontal scrollbar:
// get the sizes of the client area and redraw the folder // tabs and the scrollbars - must do this as we might be // redrawing because of a change in number of folder tabs RECT rect; GetClientRect (&rect); int newHeight = rect.bottom; int newWidth = rect.right; // reposition the folder tabs window (calc size and limit first) int folderTabWidth = FolderTabs.GetDesiredWidth (); int folderTabLimit = (newWidth * 4) / 5; if (folderTabWidth > folderTabLimit) folderTabWidth = folderTabLimit; FolderTabs.MoveWindow (0, newHeight - GetSystemMetrics (SM_CYHSCROLL), folderTabWidth, GetSystemMetrics (SM_CYHSCROLL), TRUE); // reposition and redraw the horizontal scroll bar HorzScrollBar.MoveWindow (folderTabWidth, newHeight - GetSystemMetrics (SM_CYHSCROLL), newWidth - folderTabWidth - GetSystemMetrics (SM_CXVSCROLL), GetSystemMetrics (SM_CYHSCROLL), TRUE); SCROLLINFO si; ZeroMemory (&si, sizeof (SCROLLINFO)); si.cbSize = sizeof (SCROLLINFO); si.fMask = SIF_RANGE | SIF_POS | SIF_PAGE; si.nMin = 0; si.nMax = giPaperWdDP; si.nPos = gisFlsHorzOffset; si.nPage = gisFlsHorzInc; HorzScrollBar.SetScrollInfo (&si, TRUE);
I added several message map items in my View
class for handling the folder messages:
ON_NOTIFY(FTN_TABCHANGED, 1, OnChangedTab) ON_NOTIFY(FTN_EDITSHEETS, 1, OnEditSheets) ON_NOTIFY(FTN_TABNAMECHANGED, 1, OnChangedTabName) ON_NOTIFY(FTN_ADDSHEET, 1, OnAddSheet) ON_NOTIFY(FTN_DELETESHEET, 1, OnDeleteSheet)
My View
class also has the methods for handling messages from the folder tab control:
////////////////// // Changed tab // void CFlsView::OnChangedTab(NMHDR* nmtab, LRESULT* pRes) { NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab; giCurrentLayer = nmft.iItem; // your new tab number in the view Invalidate (); } ////////////////// // right mouse click on sheet tabs and select properties // void CFlsView::OnEditSheets(NMHDR* nmtab, LRESULT* pRes) { // put up your properties dialog now } ////////////////// // Changed tab name // void CFlsView::OnChangedTabName(NMHDR* nmtab, LRESULT* pRes) { NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab; int sheet = nmft.iItem; giCurrentLayer = sheet; strncpy (LayerInfo [sheet].Name, nmft.lpText, LYR_NAMELEN); } ////////////////// // add page // void CFlsView::OnAddSheet(NMHDR* nmtab, LRESULT* pRes) { NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab; int sheet = nmft.iItem; // add new sheet to the view FolderTabs.AddItem (LayerInfo [newSheet].Name); giCurrentLayer = newSheet; FolderTabs.SelectItem (giCurrentLayer); Invalidate (); } ////////////////// // Delete page // void CFlsView::OnDeleteSheet(NMHDR* nmtab, LRESULT* pRes) { NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab; int sheet = nmft.iItem; if (0 == sheet) { CString text = "You cannot delete "; text += LayerInfo [sheet].Name; text += "."; int result = MessageBox (text, "Your App name", MB_OK); } else { DeleteLayer (sheet); // fix the view FolderTabs.RemoveItem (sheet); // if deleting the current sheet then reset the current sheet to 0 if (sheet == giCurrentLayer) giCurrentLayer = 0; Invalidate (); } }