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:
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:
RECT rect;
GetClientRect (&rect);
int newHeight = rect.bottom;
int newWidth = rect.right;
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);
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:
void CFlsView::OnChangedTab(NMHDR* nmtab, LRESULT* pRes)
{
NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab;
giCurrentLayer = nmft.iItem;
Invalidate ();
}
void CFlsView::OnEditSheets(NMHDR* nmtab, LRESULT* pRes)
{
}
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);
}
void CFlsView::OnAddSheet(NMHDR* nmtab, LRESULT* pRes)
{
NMFOLDERTAB& nmft = *(NMFOLDERTAB*)nmtab;
int sheet = nmft.iItem;
FolderTabs.AddItem (LayerInfo [newSheet].Name);
giCurrentLayer = newSheet;
FolderTabs.SelectItem (giCurrentLayer);
Invalidate ();
}
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);
FolderTabs.RemoveItem (sheet);
if (sheet == giCurrentLayer)
giCurrentLayer = 0;
Invalidate ();
}
}