CCustomTabCtrl – MFC Tab Control

What’s New

  • “First” and “Last” buttons

  • Build-in tooltips for items and buttons

  • Multihighlited 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

Introduction

CCustomTabCtrl is 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 (see pictures above). The CCustomTabCtrl control also works properly if the state of XP Themes enabling is changed during the running of the application.

Using the Code

Using the CCustomTabCtrl class is very simple. To add it to your project, please follow the steps below:

  1. Add ThemeUtil.h, ThemeUtil.cpp, CustomTabCtrl.h, CustomTabCtrl.cpp, Tmschema.h, and Schemadef.h to your project.
  2. Include CustomTabCtrl.h to the appropriate header file, usually the dialog class header where the CCustomTabCtrl class is used.
  3. //  CustomTabCtrlDemoDlg.h : header file
        #include "CustomTabCtrl.h"
    
  4. Declare a m_ctrlTab object of type CCustomTabCtrl in your dialog header.
  5. //  CustomTabCtrlDemoDlg.h : header file
        class CCustomTabCtrlDemoDlg : CDialog
        {
            ......
        private:
            CCustomTabCtrl m_ctrlTab;
        };
    
  6. Create the control.
    1. Dynamically by calling Create

      In your dialog’s OnInitDialog, add the following code:

      //  CustomTabCtrlDemoDlg.cpp : definition file
          m_ctrlTab.Create(WS_VISIBLE|WS_CHILD,
                           CRect(0,0,100,20), this, 1);
      
    2. Via a dialog template.

      Create a custom control on 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:

      //  CustomTabCtrlDemoDlg.cpp : definition file
          void CCustomTabCtrlDemoDlg::
               DoDataExchange(CDataExchange* pDX)
      {
          CDialog::DoDataExchange(pDX);
          //{{AFX_DATA_MAP(CCustomTabCtrlDemoDlg)
          DDX_Control(pDX, IDC_TAB, m_ctrlTab);
          //}}AFX_DATA_MAP
      }
      
  7. After creating the tab control, add as many tabs as you need.
  8. To add tab items call InsertItem in your dialog’s OnInitDialog:

    //  CustomTabCtrlDemoDlg.cpp : definition file
        m_ctrlTab.InsertItem(0,"SS_BLACKRECT");
        m_ctrlTab.InsertItem(1,"SS_GRAY");
        m_ctrlTab.InsertItem(2,"SS_WHITERECT");
        m_ctrlTab.SetCurSel(0);
    
  9. Process WM_NOTIFY messages from the tab control in your dialog class.
  10. As users click tabs, the tab control (CCustomTabCtrl) sends notification messages (TCN_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).

    //  CustomTabCtrlDemoDlg.cpp : definition file
        BEGIN_MESSAGE_MAP(CCustomTabCtrlDemoDlg, CDialog)
        //{{AFX_MSG_MAP(CCustomTabCtrlDemoDlg)
        ON_NOTIFY(TCN_SELCHANGE, IDC_TAB, OnSelchangeTab)
        //}}AFX_MSG_MAP
        END_MESSAGE_MAP()
        ....
        void CCustomTabCtrlDemoDlg::OnSelchangeTab(NMHDR* pNMHDR,
                                                   LRESULT* pResult)
        {
       switch(m_ctrlTab.GetCurSel())
       {
       case 0:    // Black rectangle
            m_ctrlColor.ModifyStyle(SS_BLACKRECT|SS_GRAYRECT|
                                    SS_WHITERECT,SS_BLACKRECT);
            break;
        case 1: // Gray rectangle
            m_ctrlColor.ModifyStyle(SS_BLACKRECT|SS_GRAYRECT|
                                    SS_WHITERECT,SS_GRAYRECT);
            break;
        default: // White rectangle
            m_ctrlColor.ModifyStyle(SS_BLACKRECT|SS_GRAYRECT|
                                    SS_WHITERECT,SS_WHITERECT);
            break;
        }
        m_ctrlColor.Invalidate();
        *pResult = 0;
        }
    
  11. Finally, move the tab control in right place on the dialog.
  12. //  CustomTabCtrlDemoDlg.cpp : definition file
    
        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());
        }
        }
    

CCustomTabCtrl Class Members

Construction
Attributes
Operations
Notification Messages
Error Codes

Construction

CCustomTabCtrl Constructs a CCustomTabCtrl object.
Create Creates a tab control and attaches it to an instance of a CCustomTabCtrl object.

Attributes

GetItemCount Retrieves the number of tabs in the tab control.
GetCurSel Determines the currently selected tab in a tab control.
SetCurSel Selects a tab in a tab control.
IsItemHighlighted Retrieves the highlight state of a tab item.
HighlightItem Sets the item’s highlight state.
GetItemData Retrieves the application-specific value associated with an item.
SetItemData Sets the item’s application-specific value.
GetItemText Retrieves the text of a tab item.
SetItemText Changes the text of a tab item.
GetItemRect Retrieves the rectangle of a tab item.
SetItemTooltipText Changes the tooltip text of a tab item.
SetDragCursors Sets the tab control’s drag cursors.
SetDragCursors Sets the tab control’s drag cursors.
ModifyStyle Modifies the tab control’s styles.
SetControlFont Sets the tab control’s current font.
GetDefaultFont Retrieves the reference to the default font’s LOGFONT structure.

Operations

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::CCustomTabCtrl

CCustomTabCtrl( );

Remarks

Call this function to construct a CCustomTabCtrl object.

CCustomTabCtrl::Create

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 the window styles like WS_CHILD, WS_VISIBLE, the following style 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 hide buttons. If not spcified, the buttons are 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 CTRL key when clicking.

  • CTCS_EDITLABELS—Allows item text to be edited in place.

  • CTCS_DRAGMOVE—Item can be moved by holding down left mouse button and dragging the cursor over the tab control.

  • CTCS_DRAGCOPY—Item can be copied by holding down left mouse button and CTRL key, and dragging the cursor over the tab control.

CCustomTabCtrl::GetItemCount

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.

CCustomTabCtrl::GetCurSel

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.

CCustomTabCtrl::SetCurSel

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.

CCustomTabCtrl::IsItemHighlighted

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 highlight state of a tab item.

CCustomTabCtrl::HighlightItem

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.

CCustomTabCtrl::GetItemData

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.

CCustomTabCtrl::SetItemData

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.

CCustomTabCtrl::GetItemText

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.

CCustomTabCtrl::SetItemText

int SetItemText( int nItem, CString sText );

Return Value

CTCERR_NOERROR if successful; otherwise, CTCERR_ERRORCODE.

Parameters

nItem—Index of the 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.

CCustomTabCtrl::GetItemRect

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.

CCustomTabCtrl::SetItemTooltipText

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 or 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.

CCustomTabCtrl::SetDragCursors

void SetDragCursors( HCURSOR hCursorMove, HCURSOR hCursorCopy );

Parameters

hCursorMove—Handle to the move cursor.

hCursorCopy—Handle to the copy cursor.

Remarks

This function sets the tab control’s drag cursors.

CCustomTabCtrl::ModifyStyle

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 tab control’s styles (Don’t use SetWindowLong() to modify CCustomTabCtrl styles).

CCustomTabCtrl::SetControlFont

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.

CCustomTabCtrl::GetDefaultFont

static const LOGFONT& GetDefaultFont();

Return Value

Reference to the default font’s LOGFONT structure.

Remarks

Retrieves the reference to the default font’s LOGFONT structure.

CCustomTabCtrl::InsertItem

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.

CCustomTabCtrl::DeleteItem

int DeleteItem( int nItem );

Return Value

CTCERR_NOERROR if successful; otherwise, CTCERR_ERRORCODE.

Parameters

nItem—Zero-based value of the item to delete.

Remarks

Call this function to remove the specified item from a tab control.

CCustomTabCtrl::DeleteAllItems

void DeleteAllItems( );

Remarks

Call this function to remove all items from a tab control.

CCustomTabCtrl::MoveItem

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.

CCustomTabCtrl::CopyItem

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.

CCustomTabCtrl::HitTest

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 neither a tab item nor 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.

CCustomTabCtrl::EditLabel

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.

Notification Messages

The following notification codes are supported by the tab control:


  • CTCN_CLICK—User clicked left mouse button in the control.
  • CTCN_RCLICK—User clicked 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;
Error Codes

The following errors can be returned by the tab control functions:


  • CTCERR_NOERROR—Operation succesful.

  • 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 creation of tooltip control failed.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read