Introduction
CCustomTabCtrl
is an MFC control derived from the CWnd
class. You can find a similar control in Microsoft Management Console Services used to switch between extended and standard views. CCustomTabCtrl
can be created in one orientation only - bottom. XP Themes scroll buttons are supported if the operating system is WinXP and XP Themes are enabled. CCustomTabCtrl
control also works properly if the state of XP Themes enabling is changed during the running of the application.
Using the code in dialog applications
Using the CCustomTabCtrl
class is very simple. To add it to your project, please follow the steps given below:
- Add ThemeUtil.h, ThemeUtil.cpp, CustomTabCtrl.h, CustomTabCtrl.cpp, Tmschema.h and Schemadef.h to your project.
- Include CustomTabCtrl.h in the appropriate header file - usually dialog class header where the class
CCustomTabCtrl
is used:
#include "CustomTabCtrl.h"
- Declare
m_ctrlTab
object of type CCustomTabCtrl
in your dialog header:
class CCustomTabCtrlDemoDlg : CDialog
{
......
private:
CCustomTabCtrl m_ctrlTab;
};
- Create the control:
- Dynamically by calling
Create
.
In your dialog's OnInitDialog
, add the following code:
m_ctrlTab.Create(WS_VISIBLE|WS_CHILD,
CRect(0,0,100,20), this, 1);
- Via a dialog template.
Create a custom control in the dialog resource and then in the control's properties, specify the class name as "CCustomTabCtrl
":
To link up m_ctrlTab
with the control, add the following in your dialog's DoDataExchange
:
void CCustomTabCtrlDemoDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TAB, m_ctrlTab);
}
- After creating the tab control, add as many tabs as you need.
To add tab items, call InsertItem
in your dialog's OnInitDialog
:
m_ctrlTab.InsertItem(0,"SS_BLACKRECT");
m_ctrlTab.InsertItem(1,"SS_GRAY");
m_ctrlTab.InsertItem(2,"SS_WHITERECT");
m_ctrlTab.SetCurSel(0);
- Process
WM_NOTIFY
messages from the tab control in your dialog class.
As the user clicks tab, the tab control (CCustomTabCtrl
) sends notification messages (CTCN_SELCHANGE
) to its parent window. Handle these messages if you want to do something in response. In the example shown below, I modify the style of the m_ctrlColor
control (CStatic
):
BEGIN_MESSAGE_MAP(CCustomTabCtrlDemoDlg, CDialog)
ON_NOTIFY(CTCN_SELCHANGE, IDC_TAB, OnSelchangeTab)
END_MESSAGE_MAP()
....
void CCustomTabCtrlDemoDlg::OnSelchangeTab(
NMHDR* pNMHDR, LRESULT* pResult)
{
switch(m_ctrlTab.GetCurSel())
{
case 0:
m_ctrlColor.ModifyStyle(
SS_BLACKRECT|SS_GRAYRECT|SS_WHITERECT,SS_BLACKRECT);
break;
case 1:
m_ctrlColor.ModifyStyle(
SS_BLACKRECT|SS_GRAYRECT|SS_WHITERECT,SS_GRAYRECT);
break;
default:
m_ctrlColor.ModifyStyle(
SS_BLACKRECT|SS_GRAYRECT|SS_WHITERECT,SS_WHITERECT);
break;
}
m_ctrlColor.Invalidate();
*pResult = 0;
}
- Finally, move the tab control in the right place on the dialog:
void CCustomTabCtrlDemoDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);
if(m_ctrlTab.m_hWnd && cx && cy)
{
CRect r;
m_ctrlTab.GetWindowRect(r);
ScreenToClient(r);
m_ctrlTab.MoveWindow(r.left,cy-r.Height()-
r.left,cx-2*r.left,r.Height());
}
}
Using the code in SDI/MDI applications
Create a SDI/MDI project and follow the steps below:
- Add TabMDIFrameWnd.h and TabMDIFrameWnd.cpp to your MDI project, TabSDIFrameWnd.h and TabSDIFrameWnd.cpp to the SDI project.
- Replace
CFrameWnd
with CTabSDIFrameWnd
and CMDIFrameWnd
with CTabMDIFrameWnd
in MainFrm.h and MainFrm.cpp files.
- Modify
CMainFrame::OnCreate()
like this: int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
...
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1;
}
if(!m_wndTab.Create(
WS_CHILD|WS_VISIBLE|CTCS_FOURBUTTONS|CTCS_DRAGMOVE|
CTCS_TOOLTIPS,CRect(0,0,0,m_nHeight),this,IDC_TABCTRL))
{
TRACE0("Failed to create tab control\n");
return -1;
}
m_wndTab.SetDragCursors(AfxGetApp()->LoadCursor(
IDC_CURSORMOVE),NULL);
m_wndTab.SetItemTooltipText(CTCID_FIRSTBUTTON,"First");
m_wndTab.SetItemTooltipText(CTCID_PREVBUTTON,"Prev");
m_wndTab.SetItemTooltipText(CTCID_NEXTBUTTON,"Next");
m_wndTab.SetItemTooltipText(CTCID_LASTBUTTON,"Last");
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
...
}
- In the MDI project, add
pMainFrame->AddView(sLabel,this,sTooltip)
in CView::OnInitialUpdate()
, pMainFrame->DeleteView(this)
in CView::OnDestroy()
and pMainFrame->OnActivateView(pActivateView)
in CView::OnActivateView()
. To edit a view, double click on the tab control item.
- In the SDI application, insert
pMainFrame->AddView(sLabel,this,sTooltip)
in CView::OnInitialUpdate()
and pMainFrame->DeleteContents()
in CDocument::DeleteContents()
. To add, delete and edit a view, right click on the tab control and use a popup menu.
CCustomTabCtrl class members
CCustomTabCtrl |
Constructs a CCustomTabCtrl object. |
Create |
Creates a tab control and attaches it to an instance of CCustomTabCtrl object. |
InsertItem |
Inserts a new tab in a tab control. |
DeleteItem |
Removes an item from a tab control. |
DeleteAllItems |
Removes all items from a tab control. |
MoveItem |
Moves a tab item within the current tab control. |
CopyItem |
Copies a tab item within the current tab control. |
HitTest |
Determines which tab or button, if any, is at a specified screen position. |
EditLabel |
Begins in-place editing of an item's text. |
CCustomTabCtrl( );
Remarks
Call this function to construct a CCustomTabCtrl
object.
BOOL Create( DWORD dwStyle, const RECT& rect,
CWnd* pParentWnd, UINT nID );
Return value
TRUE
, if initialization of the object was successful; otherwise FALSE
.
Parameters
dwStyle
: Specifies the tab control's style. Apply any combination of tab control styles to the control.
rect
: Specifies the tab control's size and position. It can be either a CRect
object or a RECT
structure.
pParentWnd
: Specifies the tab control's parent window, usually a CDialog
.
nID
: Specifies the tab control's ID.
Remarks
In addition to the window styles like WS_CHILD
, WS_VISIBLE
, the following styles can be applied to a tab control:
CTCS_FIXEDWIDTH
: Makes all tabs the same width.
CTCS_FOURBUTTONS
: Creates a control with four buttons (First, Prev, Next, Last).
CTCS_AUTOHIDEBUTTONS
: Auto hides the buttons. If not specified the buttons remain always on top.
CTCS_TOOLTIPS
: The tab control has a ToolTip control associated with it.
CTCS_MULTIHIGHLIGHT
: Multiple tabs can be selected by holding down the CTRL key when clicking.
CTCS_EDITLABELS
: Allows the item text to be edited in place.
CTCS_DRAGMOVE
: Item can be moved by holding the left mouse button down and dragging the cursor over the tab control.
CTCS_DRAGCOPY
: Item can be copied by holding down the left mouse button and CTRL key, and dragging the cursor over the tab control.
int GetItemCount( ) const;
Return value
Number of items in the tab control.
Remarks
Call this function to retrieve the number of tabs in the tab control.
int GetCurSel( ) const;
Return value
Zero-based index of the selected tab if successful or � 1 if no tab is selected.
Remarks
Call this function to retrieve the currently selected tab in a tab control.
int SetCurSel( int nItem );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: The zero-based index of the item to be selected.
Remarks
Selects a tab in a tab control. A tab control does not send a CTCN_SELCHANGE
notification message when a tab is selected using this function. These notifications are sent, using WM_NOTIFY
, when the user clicks to change tabs.
int IsItemHighlighted( int nItem );
Return value
1
if highlighted, 0
if not, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose highlight state is to be retrieved.
Remarks
Retrieves the highlighted state of a tab item.
int HighlightItem( int nItem, BOOL fHighlight );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose highlight state is to be set.
fHighlight
: A highlight state to be set to the item.
Remarks
This function sets the highlight state to the item. A tab control does not send a CTCN_HIGHLIGHTCHANGE
notification message when a tab is highlighted using this function. These notifications are sent, using WM_NOTIFY
, when the user clicks to highlight tabs.
int GetItemData( int nItem, DWORD& dwData ) const;
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose data is to be retrieved.
dwData
: Reference to a DWORD
variable that receives the 32-bit application-specific value associated with the specified item.
Remarks
This function retrieves the 32-bit application-specific value associated with the item specified by nItem
.
int SetItemData( int nItem, DWORD dwData );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose data is to be set.
dwData
: A 32-bit value to be associated with the item.
Remarks
This function sets the 32-bit application-specific value associated with the item specified by nItem
.
int GetItemText( int nItem, CString& sText );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose text is to be retrieved.
sText
: Reference to a CString
object that receives the item's text.
Remarks
This function retrieves the text of a tab item.
int SetItemText( int nItem, CString sText );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose text is to be set.
sText
: Pointer to a string object that contains the new item text.
Remarks
This function changes the text of a tab item.
int GetItemRect( int nItem, CRect& rect );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item whose rectangle is to be retrieved.
rect
: Reference to a CRect
object that receives the item's rectangle.
Remarks
This function retrieves the rectangle of a tab item.
int SetItemTooltipText( int nItem, CString sText );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
- Zero-based index of the tab item whose tooltip text is to be set to one of these values:
CTCID_FIRSTBUTTON
: ID of the first button.
CTCID_PREVBUTTON
: ID of the previous button.
CTCID_NEXTBUTTON
: ID of the next button.
CTCID_LASTBUTTON
: ID of the last button.
sText
: Pointer to a string object that contains the new item tooltip text.
Remarks
This function changes the tooltip text of a tab item.
void SetDragCursors( HCURSOR hCursorMove,
HCURSOR hCursorCopy );
Parameters
hCursorMove
: Handle to the move cursor.
hCursorCopy
: Handle to the copy cursor.
Remarks
Call this function to set the tab control's drag cursors.
BOOL ModifyStyle( DWORD dwRemove, DWORD dwAdd,
UINT nFlags );
Return value
TRUE
if successful, otherwise FALSE
.
Remarks
For help, see CWnd::ModifyStyle()
. Call this function to set the tab control's styles. (Don't use SetWindowLong()
to modify CCustomTabCtrl
styles.)
void SetControlFont( LOGFONTt& lf, BOOL fRedraw = FALSE );
Parameters
lf
: Specifies the new font.
fRedraw
: If TRUE
, redraw the CCustomTabCtrl
object.
Remarks
Sets the tab control's current font to the specified font.
static const LOGFONT& GetDafaultFont();
Return value
Reference to the default font's LOGFONT
structure.
Remarks
Retrieves the reference to the default font's LOGFONT
structure..
int InsertItem( int nItem, CString sText,
LPARAM lParam = 0 );
Return value
Zero-based index of the new tab if successful; otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Zero-based index of the new tab.
sText
: Pointer to a string object that contains the new item text.
lParam
: Application-defined data associated with the tab.
Remarks
Call this function to insert a new tab in an existing tab control.
int DeleteItem( int nItem );
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
- Zero-based value of the item to be deleted.
Remarks
Call this function to remove the specified item from a tab control.
void DeleteAllItems( );
Remarks
Call this function to remove all items from a tab control.
int MoveItem(int nItemSrc, int nItemDst);
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItemSrc
: Zero-based index of the source item.
nItemDst
: Zero-based index of the destination item.
Remarks
Moves a tab item within the current tab control. A tab control does not send a CTCN_ITEMMOVE
notification message when a tab is moved using this function. These notifications are sent, using WM_NOTIFY
, when the user uses a mouse to move items.
int CopyItem(int nItemSrc, int nItemDst);
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItemSrc
: Zero-based index of the source item.
nItemDst
: Zero-based index of the destination item.
Remarks
Copies a tab item within the current tab control. A tab control does not send a CTCN_ITEMCOPY
notification message when a tab is copied using this function. These notifications are sent, using WM_NOTIFY
, when the user uses a mouse to copy items.
int HitTest( CPoint pt);
Return value
The zero based index of the matching item or one of these values:
CTCHT_ONFIRSTBUTTON
: The position is over the first button.
CTCHT_ONPREVBUTTON
: The position is over the previous button.
CTCHT_ONNEXTBUTTON
: The position is over the next button.
CTCHT_ONLASTBUTTON
: The position is over the last button.
CTCHT_NOWHERE
: The position is inside the tab control's client window, but it is not over either a tab item or a button.
Parameters
pt
: Point to be tested in client coordinates.
Remarks
Determines which tab or button, if any, is at a specified screen position.
int EditLabel( int nItem);
Return value
CTCERR_NOERROR
if successful, otherwise CTCERR_ERRORCODE
.
Parameters
nItem
: Index of the tab item that is to be edited.
Remarks
Begins in-place editing of an item's text.
The following notification codes are supported by the tab control:
CTCN_CLICK
: User clicked the left mouse button in the control.
CTCN_RCLICK
: User clicked the right mouse button in the control.
CTCN_SELCHANGE
: User changed the current selection.
CTCN_HIGHLIGHTCHANGE
: User changed the highlight state of the item.
CTCN_ITEMMOVE
: User moved the item.
CTCN_ITEMCOPY
: User copied the item.
CTCN_LABELUPDATE
: User changed the item text.
CTCN_OUTOFMEMORY
: Control could not complete an operation because there was not enough memory available.
The notifications shown above pass a pointer to the CTC_NMHDR
structure that contains an NMHDR
structure as its first member which is defined as shown below:
typedef struct _CTC_NMHDR
{
NMHDR hdr;
int nItem;
TCHAR pszText[MAX_LABEL_TEXT];
LPARAM lParam;
RECT rItem;
POINT ptHitTest;
BOOL fSelected;
BOOL fHighlighted;
} CTC_NMHDR;
The following errors can be returned by the tab control functions:
CTCERR_NOERROR
: Operation successful.
CTCERR_OUTOFMEMORY
: Function call failed because there was not enough memory available.
CTCERR_INDEXOUTOFRANGE
: Function call failed because a tab item index was out of range.
CTCERR_NOEDITLABELSTYLE
: Function call failed because CTCS_EDITLABELS
style was not specified.
CTCERR_NOMULTIHIGHLIGHTSTYLE
: Function call failed because CTCS_MULTIHIGHLIGHT
style was not specified.
CTCERR_ITEMNOTSELECTED
: Function call failed because an item was not selected.
CTCERR_ALREADYINEDITMODE
: Function failed because the tab control was already in edit mode.
CTCERR_TEXTTOOLONG
: Function failed because an item text was too long.
CTCERR_NOTOOLTIPSSTYLE
: Function call failed because CTCS_TOOLTIPS
style was not specified.
CTCERR_CREATETOOLTIPFAILED
: Function call failed because the creation of tooltip control failed.
What's new
16th May, 2006
- Vertical styles (left and right) added:
- Remarks:
- Label editing is not supported for vertical styles.
- I use
PlgBlt()
for rotating bitmaps. This function is specific to NT and higher, and will not work on Windows95.
16th April, 2006
- Buttons for specifying style added:
- Bug fixes:
- Fix for RTL.
- Fix for incorrect handling of '
OnSize
' in the dialog demo application.
25th March, 2006
- A close button and a top style added:
- Bug fixes:
- Fix for incorrect recalculation of the tooltip rectangles when the tab item is deleted.
- Fix for 'Alt-F4 click' when in edit mode.
- Fix for incorrect handling of '
OnMouseMove
' in the drag and drop mode.
10th Oct, 2005
- SDI and MDI demo projects:
30th Jul, 2004
- "First" and "Last" buttons:
- Built-in tooltips for items and buttons:
- Multi-highlighted items:
- In-place editing:
- Drag and drop for moving and coping items.
- Auto-repeat buttons when held down.
- Auto hide or always on top buttons.