Skip to main content
Email Password   helpLost your password?

Introduction

I first saw the new Microsoft Visual Studio .NET after beta 2 was released. One of the things that stood out to me was how nice the tabs looked. It also finally included a tabbed MDI.

I soon after found Bjarke Viks�e's Cool Tab Controls. I was especially interested in the "DotNetTabCtrl". Bjarke soon linked to an updated version by Pascal Binggeli, that had support for the tabs to have images. There were several minor issues with both versions, but when I examined the code, it seemed an excellent foundation to build from.

Starting with the updates from Pascal, I began making my own updates. Initial updates included adding divider lines between the tabs, adjusting the layout to closer match VS.NET, adding implementations to use the tab control for a tabbed MDI, and adding other improvements. At first, I tried to make minimal changes to the base CCustomTabCtrl. I eventually began evolving even the base CCustomTabCtrl to accommodate my vision for what this could be.

Custom Tab Controls

CCustomTabCtrl is the base, templatized, ATL::CWindowImpl derived class to help implement a customized tab control window. The painting is double buffered for flicker free drawing. Clients never use this class directly, but instead use a class derived from it. Included out of the box are a handful of tab controls derived from CCustomTabCtrl:

CCustomTabCtrl derived tab controls are meant to work similar to other common controls such as the list view (SysListView32) and the tree view (SysTreeView32). There is already an existing tab control (SysTabControl32) that is a common control. So why do we need CCustomTabCtrl? Because there are several customizations that are hard to do with it. SysTabControl32 was originally created to implement the task bar in Windows 95 and later (just like SysListView32 and SysTreeView32 were originally created for Windows Explorer). There are several features that other common controls have that SysTabControl32 is missing, such as custom drawing, insert and delete notifications, position displacement and more.

Custom Tab Items

One of the differences between CCustomTabCtrl derived tab controls and common controls in Windows are how items are managed. Common controls are meant to work with any client that can handle structures and window programming - from x86 assembly to Visual Basic. The "item" in most common controls is a structure. To get and set items, you fill out a structure with a mask to identify the fields you are interested in. There are several side effects of this design decision. One is that there is often more "memory copying" than really needs to be happening, especially with getting and setting text. Another is that there is no good way to know if a particular field is actually in use. Another effect is that any user data is always put into an "LPARAM" into one of these structures, cast to and from the real type of data.

CCustomTabCtrl takes a different approach, and lets you use any C structure or C++ class for the item that provides the needed interface. There are two such classes available out of the box - CCustomTabItem and CTabViewTabItem. The type of structure or class is a template parameter on the tab control class. If you want to use the tab control, and have instances of your own class for the tab items, the easiest thing to do is inherit from CCustomTabItem or CTabViewTabItem, and extend it to provide the extra functionality you need, then specify this new class as a parameter. To see the interface needed, simply look at CCustomTabItem.

Using Custom Tab Controls

Tab controls based on CCustomTabCtrl are meant to be used either as a stand-alone window, or to subclass an existing control on a dialog such as a static control. The parent of the tab control is responsible for creating, destroying, sizing and positioning the tab control window appropriately along side other child windows.

Depending on which custom tab control you use, it will probably depend on some system metrics to figure out which colors and fonts to use. If the user changes these system metrics (for example, by changing items on the "appearance" tab of the display control panel), the tab control can pick up these changes - but only if you propagate WM_SETTINGCHANGE from the main frame to the tab control. This can be done by handling WM_SETTINGCHANGE in the main frame, then calling CWindow::SendMessageToDescendants or the equivalent code. See the included sample applications for an example.

The samples provided with this article demonstrate how to use these tab controls as stand-alone windows used to switch between child "view" windows, where only one child view is visible at a time.

For a simple example of how to use a custom tab control for a tabbed MDI, see the "SimpleTabbedMDIDemo" sample. In this sample, the WTL wizard was run to create a default MDI Application. Instead of having CMainFrame inherit from CMDIFrameWindowImpl, change it to inherit from CTabbedMDIFrameWindowImpl. Instead of CMDICommandBarCtrl, use CTabbedMDICommandBarCtrl. Then in each MDI child frame, inherit from CTabbedMDIChildWindowImpl instead of CMDIChildWindowImpl.

The "TabDemo" sample uses a tabbed MDI as well, but in addition has a "popup tool window frame" that uses CDotNetTabCtrl to switch between child views. It also uses CDotNetButtonTabCtrl for the child frame to switch between an HTML view and an edit view (of the source of the HTML).

The "DockingDemo" sample shows how you might integrate these custom tab controls with Sergey Klimov's WTL Docking Windows. I've included the source for his docking windows with permission. However - be sure to get the latest updates from him! In the file "TabbedDockingWindow.h", there is the class CTabbedDockingWindow that inherits from CTabbedFrameImpl and Sergey's CTitleDockingWindowImpl.

The "TabbedSDISplitter" sample shows the use of a splitter in an SDI application, with the right side window "tabbed" to show multiple views. For another sample showing a slightly different use of these tabs in an SDI application, see the "SDITabbedSample" from Sergey Klimov's WTL Docking Windows and the work by Igor Katrayev.

It should be possible to integrate the custom tab controls in with other docking frameworks, splitters, etc. as well. As time allows, I'll try to get some more sample applications up.

Tabbed Frame

TabbedFrame.h contains classes to make it simple to add the ability to turn a frame window with one "view" into a tabbed frame window with a custom tab control to switch between one or more views. Included are the classes:

Tabbed MDI

TabbedMDI.h contains classes to help implement a tabbed MDI using a custom tab control. There are multiple approaches to implementing a tabbed MDI. The approach that is used here is to subclass the out-of-the-box "MDIClient" from the OS, and require each MDI child frame to inherit from a special class CTabbedMDIChildWindowImpl (instead of the normal CMDIChildWindowImpl). Included are the classes:

Note to previous users

I originally posted my version of the "DotNetTabCtrl" code to the WTL mailing list's site on groups.yahoo.com, and to Bjarke Viks�e. If you have used a previous version downloaded from either of these places, there are only a couple of updates to your client code to accommodate updates that I've made:

Custom Tab Control Reference

Requirements

Styles

Notifications

These messages are sent to the parent of the tab control window in the form of a WM_NOTIFY message.

Structures

Constants

#define the following constants before you #include CustomTabCtrl.h to redefine them.

Methods

Note: This is one place where custom tab controls are dissimilar to common controls. Instead of sending messages to the window, you call public methods - much like working with the common control wrappers of WTL. If you want corresponding messages to these methods, then let me know.

Acknowledgements

I'd like to thank Bjarke Viks�e for his original "Cool Tab controls" and for all of the other cool things on his web site that he so generously shares with the world. I'd also like to thank all the many others who have given feedback, made suggestions, and helped this become what it is today.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionAbout TabControl Pin
Niharvyas
22:56 7 Aug '09  
QuestionDid dockingframe's arrange is settled by class ssection ? Pin
khaki6688
0:59 18 Jun '09  
AnswerRe: Did dockingframe's arrange is settled by class ssection ? Pin
khaki6688
21:53 18 Jun '09  
GeneralSomething wrong with CDotNetTabCtrl Pin
Love In Snowing
3:51 11 Apr '09  
GeneralPlease clarify licence Pin
peterchen
5:56 15 Jan '09  
AnswerRe: Please clarify licence Pin
Daniel Bowen
20:36 20 Jan '09  
Questionhi Pin
Member 3719516
6:09 21 Mar '08  
GeneralNotifications Pin
squeakyariwheel
9:06 21 Sep '07  
GeneralUsing this framework problem, tooltip not display Pin
free2000fly
21:08 8 May '07  
GeneralRe: Using this framework problem, tooltip not display Pin
free2000fly
6:22 1 Aug '07  
GeneralTabbedSDISplitter Pin
hahahua
12:41 24 Apr '07  
QuestionHow to Show and Hide Pages In sample project TabbedSDISplitter Pin
GuoliangLiu
23:05 2 Mar '07  
QuestionNM_RELEASEDCAPTURE message Pin
RaviPK
2:25 27 Feb '07  
GeneralThank you Pin
Douglas Troy
21:22 31 Jan '07  
Questioncannot go into "CMyCustomListView::OnItemPostPaint" method Pin
gaojinsong
1:30 27 Jan '07  
QuestionHow to let the "Task List" of panewindows first selected. Pin
gaojinsong
18:33 20 Jan '07  
AnswerRe: How to let the "Task List" of panewindows first selected. Pin
gaojinsong
22:09 21 Jan '07  
GeneralDockingDemo trouble && VS 2005 PE Pin
HeToC
23:34 16 Jan '07  
GeneralRe: DockingDemo trouble && VS 2005 PE Pin
HeToC
23:38 16 Jan '07  
GeneralUsing Tabbed Framework with STLPort5.0.2: bugs Pin
loyso_b
4:45 27 Dec '06  
QuestionUsing CTabbedFrameImpl for main frame? Pin
domehead
21:33 5 Dec '06  
AnswerRe: Using CTabbedFrameImpl for main frame? Pin
domehead
7:41 8 Dec '06  
GeneralWTL / MFC Pin
blackbondi
6:02 22 Nov '06  
GeneralRe: WTL / MFC Pin
sophia nguyen
15:46 12 Oct '07  
GeneralHow to use TabbedMDISave and build error Pin
kite
7:40 31 Aug '06  


Last Updated 13 Jul 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009