Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / MFC
Article

CTabCtrlSSL - An easy to use, flexible extended tab control

Rate me:
Please Sign up or sign in to vote.
4.90/5 (85 votes)
2 Oct 2003CPOL10 min read 1.1M   18K   156   469
An extended tab control that allows tab pages to be added from dialog resources

Sample Image - CTabCtrlSSL.gif

Introduction

This article has been updated and the details are available in the Updates section.

It's amazing what a bit of illness can do for your productivity at home! I've been ill for the last couple of days and here it is, yet another extended control. This time my target is the tab control. It seems to me that the tab control is a bit out of fashion these days with people preferring property sheets and pages instead. Well, I tried to use them and couldn't get the result I wanted. I needed some controls above the tabbed area (a bit like the demo, but a few more controls) and I just couldn't get that with property sheets and pages.

The problem with the standard tab control is that involves loads of effort to get pages in to the tab control. A quick in the MSDN located an example by Jeff Prosise that implemented a tabbed view, CTabView, allowing the tabs to be specified as dialog resources. Well, when it comes to code I'm a bit like I was as a ten year old with watches: I've got to fiddle about with it and see how it works and wonder how it could be better.

The first problem was that Jeff's solution was for a view class and I needed a control. The transition here is fairly easy as the view just wraps up the control. The second issue I had was that it didn't give much flexibility over what you could do with the tab pages. "How do I handle events within the page?" I asked myself. The answer was to allow the client to inherit from the tab page class and allow tab page objects to be added to the control and not just dialog resources.

Why is that solutions always present a new problem? By allowing this approach I then introduced a tricky situation with releasing the tab pages. Internally the tab control was creating the tab pages on the heap and maintaining a list of the pages that had been added. When the control was destroyed delete was called on each page in turn. This obviously causes problems if the pages are created outside of the tab control and passed in to it. In this case the tab control would destroy the pages created externally and then the parent dialog would try and do the same!!

After a lengthy discussion in the Visual C++ forum with Tomasz Sowinski we came up with the answer. The tab control has a protected function for adding pages to the control and the public functions call this one. What is actually passed in to the protected function is a structure containing a pointer to a tab page and a flag indicating if the tab control should destroy it. This way if the tab page is passed in then the flag is set to false, but if the tab control creates the tab page the flag is set to true. At destruction time only the pages with the flag set are destroyed by the tab control. All others are someone else's problem.

How to use it

  1. Create a dialog resource and class for the dialog that you want a tab control on.
  2. Add a tab control from the toolbox to the dialog resource.
  3. Create a member variable for the tab control and change it's type to CTabCtrlSSL.
  4. In the OnInitDialog handler for your dialog class create and add any pages you want on the tab control.
BOOL CCTabCtrlSSL_demoDlg::OnInitDialog () {
	CDialog::OnInitDialog ();
   
   // Setup the tab control
   int nPageID = 0;
   m_tabDemo.AddSSLPage (_T("Basic Tab"), nPageID++, IDD_TAB_BASIC);
   m_advancedTab.Create (IDD_TAB_ADVANCED, this);
   m_tabDemo.AddSSLPage (_T("Advanced Page"), nPageID++, &m_advancedTab);
   m_aboutTab.Create (IDD_TAB_ABOUT, this);
   m_tabDemo.AddSSLPage (_T("About"), nPageID++, &m_aboutTab);
   
   return TRUE; // return TRUE unless you set the focus to a control
}

As you can see from the above code sample (taken from the demo), to add a basic tab call AddSSLPage and just pass it the resource ID of the dialog resource. For an advanced tab, create the dialog resource setting the window style to Child and the border style to none, then call AddSSLPage and pass in a pointer to your CTabPageSSL-derived object.

To continue the style I started with CButtonSSL, here is the documentation for the classes:

Overview | Class members | Known problems

CTabCtrlSSL

A "tab control" is analogous to the dividers in a notebook or the labels in a file cabinet. By using a tab control, an application can define multiple pages for the same area of a window or dialog box. Each page consists of a set of information or a group of controls that the application displays when the user selects the corresponding tab. CTabCtrlSSL extends the standard tab control by providing an interface for adding tabs to the control that are defined as dialog resources. These tabs are defined internally as CTabPageSSL objects. There is also an interface for adding objects of this type to the tab control allowing custom objects to be defined by inheriting from CTabPageSSL.

Any tab pages that are created by CTabCtrlSSL (those where the tab is added by passing in a dialog resource id) are destroyed by CTabCtrlSSL. It is the clients responsibility to destroy any CTabPageSSL-derived objects that are passed in to CTabCtrlSSL.

#include "TabCtrlSSL.h"

Overview | Class members | Known problems

Class members

Construction

CTabCtrlSSLConstructs a CTabCtrlSSL object.

Page functions

AddSSLPageAdds a tab to the control.
RemoveSSLPageRemoves a tab from the control.
GetSSLPageCountReturns the number of tabs that have been added to the control.
GetSSLPageTitleReturns the label for a particular tab page.
SetSSLPageTitleSets the label for a particular tab page.
GetSSLPageIDReturns the page ID for the specified tab page.
SetSSLPageIDSets the page ID for the specified tab page.
ActivateSSLPageMakes the specified tab page the active one.
GetSSLActivePageGets the currently active tab page.
GetSSLPageIndexReturns the page index of the specified tab page.

Overridables

OnInitPageOverride in derived class to initialize pages.
OnActivatePageOverride in derived class to respond to page activations.
OnDeactivatePageOverride in derived class to respond to page deactivations.
OnDestroyPageOverride in derived class to free resources.

Overview | Class members | Known problems

CTabCtrlSSL::CTabCtrlSSL

CTabCtrlSSL ();

Remarks

Constructs a CTabCtrlSSL object.

Overview | Class members | Known problems

CTabCtrlSSL::AddSSLPage

int AddSSLPage (LPCTSTR pszTitle, int nPageID, int nTemplateID);

int AddSSLPage (LPCTSTR pszTitle, int nPageID, LPCTSTR pszTemplateName);

int AddSSLPage (LPCTSTR pszTitle, int nPageID, CTabPageSSL* pTabPage);

Return Value

Zero-based index of the new tab if successful; otherwise –1.

Parameters

pszTitle

Address of a null-terminated string that contains the tab text.

nPageID

The zero-based numeric ID for referring to the page to be added.

nTemplateID

Specifies the tab page’s resource ID.

pszTemplateName

Points to a null-terminated string that contains the name of the dialog resource to load.

pTabPage

Points to the CTabPageSSL object to be added.

Remarks

Call this function to insert a new tab in an existing tab control.

Overview | Class members | Known problems

See Also CTabCtrlSSL::RemoveSSLPage, CTabCtrlSSL::GetSSLPage

CTabCtrlSSL::RemoveSSLPage

BOOL RemoveSSLPage (int nIndex);

Return Value

Nonzero if successful; otherwise 0.

Parameters

nIndex

Zero-based value of the item to delete.

Remarks

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

Overview | Class members | Known problems

See Also CTabCtrlSSL::AddSSLPage, CTabCtrlSSL::GetSSLPage

CTabCtrlSSL::GetSSLPageCount

int GetSSLPageCount ();

Return Value

Number of items in the tab control.

Remarks

Call this function to retrieve the number of tabs in the tab control.

Overview | Class members | Known problems

CTabCtrlSSL::GetSSLPageTitle

BOOL GetSSLPageTitle (int nIndex, CString& strTitle);

Return Value

Nonzero if successful; otherwise 0.

Parameters

nIndex

Zero-based value of the relevant tab page.

strTitle

A CString reference to receive the title of the tab page.

Remarks

Call this function to retrieve the title of the specified item in a tab control.

Overview | Class members | Known problems

See Also CTabCtrlSSL::SetSSLPageTitle

CTabCtrlSSL::SetSSLPageTitle

BOOL SetSSLPageTitle (int nIndex, LPCTSTR pszTitle);

Return Value

Nonzero if successful; otherwise 0.

Parameters

nIndex
Zero-based value of the relevant tab page.

pszTitle

Points to a null-terminated string that contains the title to set for the specified tab page.

Remarks

Call this function to set the title of the specified item in a tab control.

Overview | Class members | Known problems

See Also CTabCtrlSSL::GetSSLPageTitle

CTabCtrlSSL::GetSSLPageID

int GetSSLPageID (int nIndex);

Return Value

Zero-based page identifier if successful; otherwise -1.

Parameters

nIndex

Zero-based index of the relevant tab page.

Remarks

Call this function to retrieve the page identifier as specified when the tab was added of the specified item in a tab control. The page identifier may also be altered with the SetSSLPageID function.

Overview | Class members | Known problems

See Also CTabCtrlSSL::SetSSLPageID

CTabCtrlSSL::SetSSLPageID

int SetSSLPageID (int nIndex, int nPageID);

Return Value

The previous zero-based page identifier if successful; otherwise -1.

Parameters

nIndex

Zero-based index of the relevant tab page.

nPageID

The new zero-based page identifier to be set.

Remarks

Call this function to alter the page identifier for a specified tab page.

Overview | Class members | Known problems

See Also CTabCtrlSSL::GetSSLPageID

CTabCtrlSSL::ActivateSSLPage

BOOL ActivateSSLPage (int nIndex);

Return Value

Nonzero if successful; otherwise 0.

Parameters

nIndex

Zero-based index of the tab page to activate.

Remarks

Call this function to change the active tab.

Overview | Class members | Known problems

See Also CTabCtrlSSL::GetSSLActivePage

CTabCtrlSSL::GetSSLActivePage

int GetSSLACtivePage ();

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.

See Also CTabCtrlSSL::ActivateSSLPage

Overview | Class members | Known problems

CTabCtrlSSL::GetSSLPage

CWnd* GetSSLPage (int nIndex);

Return Value

A pointer to the requested tab page if successful; otherwise NULL.

Parameters

nIndex

Zero-based index of the tab page to get.

Remarks

Call this function to get a specific tab in the tab control.

Overview | Class members | Known problems

CTabCtrlSSL::GetSSLPageIndex

int GetSSLPageIndex (int nPageID);

Return Value

Zero-based index of the specified tab if successful; otherwise -1.

Parameters

nPageID

Zero-based page identifier of the relevant tab page.

Remarks

Call this function to retrieve the zero-based index of a tab page in the tab control.

Overview | Class members | Known problems

CTabCtrlSSL::OnInitPage

BOOL OnInitPage (int nIndex, int nPageID);

Return Value

Nonzero if successful; otherwise 0.

Parameters

nIndex

Zero-based index of the tab page being initialized.

nPageID

Zero-based page identifier of the page being initialized.

Remarks

Override in derived class to initialize pages.

Overview | Class members | Known problems

CTabCtrlSSL::OnActivatePage

void OnActivatePage (int nIndex, int nPageID);

Parameters

nIndex

Zero-based index of the tab page being activated.

nPageID

Zero-based page identifier of the page being activated.

Remarks

Override in derived class to respond to page activations.

Overview | Class members | Known problems

CTabCtrlSSL::OnDeactivatePage

void OnDeactivatePage (int nIndex, int nPageID);

Parameters

nIndex

Zero-based index of the tab page being activated.

nPageID

Zero-based page identifier of the page being activated.

Remarks

Override in derived class to respond to page deactivations.

Overview | Class members | Known problems

CTabCtrlSSL::OnDestroyPage

void OnDestroyPage (int nIndex, int nPageID);

Parameters

nIndex

Zero-based index of the tab page being activated.

nPageID

Zero-based page identifier of the page being activated.

Remarks

Override in derived class to free resources.

Overview | Class members | Known problems

Known problems

As far as I know there aren't any, but then the advanced tab part hasn't been tested much. If you find any let me know.

Updates

  • 01 Oct 2003

    The most common question I have had about CTabCtrlSSL is about x, y, or z control that someone can't receive messages for.

    I have explained the problem and the solution many times to many people and now, with thanks to John A Johnson, I have a solution that really works and can be applied to the source code for all.

    The problem was that WM_COMMAND, WM_NOTIFY and WM_CMDMSG were passed on to the parent of the tab page, the tab control, which then passed them on to its parent (usually a dialog) so that the parent dialog could handle notifications, etc. of the tab pages. Unfortunately, this meant that any derived tab page would never get a chance to handle its own control notifications, unless you removed the OnCommand, OnNotify and OnCmdMsg handlers in CTabPageSSL.

    The real solution is to turn off this command routing by default as most people want to handle control notifications in the class that owns them directly, but allow people to turn command routing back on, if they want the parent dialog to handle them instead. This resulted in a few extra methods in CTabPageSSL. But if you only want to handle commands/notifications in your derived tab page, you won't need to change your code at all, just drop in the new TabPageSSL.h and TabPageSSL.cpp.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionBreaks Accelerator table Pin
CodeHead3-Sep-14 8:11
CodeHead3-Sep-14 8:11 
QuestionGetting BEGIN_MESSAGE_MAP messages from a CTabPageSSL Pin
Member 82426055-Nov-12 3:23
Member 82426055-Nov-12 3:23 
GeneralExcellent! Pin
jstanch19-Mar-12 7:33
jstanch19-Mar-12 7:33 
Questionerror C2440: 'static_cast' : cannot convert from 'LRESULT Pin
Hari Om Prakash Sharma3-Oct-11 20:32
Hari Om Prakash Sharma3-Oct-11 20:32 
AnswerRe: error C2440: 'static_cast' : cannot convert from 'LRESULT Pin
Derek Lakin3-Oct-11 21:08
Derek Lakin3-Oct-11 21:08 
GeneralRe: error C2440: 'static_cast' : cannot convert from 'LRESULT Pin
Hari Om Prakash Sharma4-Oct-11 0:50
Hari Om Prakash Sharma4-Oct-11 0:50 
GeneralRe: error C2440: 'static_cast' : cannot convert from 'LRESULT Pin
Coruscant5-Jul-12 10:58
Coruscant5-Jul-12 10:58 
GeneralMy vote of 5 Pin
webrobot99923-Jul-11 13:12
webrobot99923-Jul-11 13:12 
GeneralFlicker Issue Pin
_CBerber01052-Feb-11 11:54
_CBerber01052-Feb-11 11:54 
GeneralRe: Flicker Issue Pin
Derek Lakin2-Feb-11 23:00
Derek Lakin2-Feb-11 23:00 
GeneralCrash Problem Pin
Mohamed AlSaeed Rizk5-Nov-10 9:03
Mohamed AlSaeed Rizk5-Nov-10 9:03 
GeneralMake it look like a Wizard Pin
Sunny12706-Sep-10 22:56
Sunny12706-Sep-10 22:56 
GeneralDouble Click Pin
Nite20-Mar-10 8:05
Nite20-Mar-10 8:05 
GeneralSend a Message from a tab page to the Parent Dialog [modified] Pin
mimosa5-Mar-10 17:38
mimosa5-Mar-10 17:38 
GeneralVista / Windows 7 style property pages Pin
User 2694226-Nov-09 4:21
professionalUser 2694226-Nov-09 4:21 
GeneralRe: Vista / Windows 7 style property pages Pin
Derek Lakin26-Nov-09 4:49
Derek Lakin26-Nov-09 4:49 
GeneralRe: Vista / Windows 7 style property pages Pin
User 2694230-Nov-09 3:33
professionalUser 2694230-Nov-09 3:33 
GeneralRe: Vista / Windows 7 style property pages Pin
Derek Lakin30-Nov-09 3:40
Derek Lakin30-Nov-09 3:40 
GeneralDLGTEMPLATEEX defined in TabCtrlSSL.h [modified] Pin
User 2694217-Nov-09 22:07
professionalUser 2694217-Nov-09 22:07 
Questionhow about multiple page on one tab? Pin
mimosa10-Apr-09 14:20
mimosa10-Apr-09 14:20 
GeneralMy vote of 2 Pin
Like2Byte6-Feb-09 10:52
Like2Byte6-Feb-09 10:52 
GeneralRe: My vote of 2 Pin
Derek Lakin26-Nov-09 4:52
Derek Lakin26-Nov-09 4:52 
QuestionHow to reference parent dlg? [modified] Pin
kys07169-Jan-09 7:49
kys07169-Jan-09 7:49 
QuestionSSL, what's mean ? Pin
kys071628-Dec-08 14:09
kys071628-Dec-08 14:09 
AnswerRe: SSL, what's mean ? Pin
Derek Lakin4-Jan-09 21:16
Derek Lakin4-Jan-09 21:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.