Click here to Skip to main content
Click here to Skip to main content

A WTL Tab Control for Managing Tab Views

By , 21 Jun 2002
 

TabViewCtrl Demo Image

Introduction

If you are looking for general information about tab controls, you are in the wrong place. You can find general information about tab controls elsewhere (MSDN). If you are just looking for an easier way to use tab controls in WTL, read on.

About

Tab controls are powerful tools, but sometimes it can be a hassle to re-implement tab management every time you need a tab control. This class encapsulates the functionality for managing tabs.

Some similar controls are available for MFC, but I could not find any tab management controls for WTL. This class was originally a port of an MFC class CSizingTabCtrlBar (author unknown), but as work progressed, the implementation changed significantly.

The management of the "View" windows for each tab is loosely based on the pane management for WTL::CSplitterImpl. Child "View" windows are created by the application for each tab and submitted to the CWTLTabViewCtrl for management.

Usage

To use this class in an SDI WTL application, derive a class from CWTLTabViewCtrl. (You need to have WTL in your include path to compile.)

class CDemoTabViewCtrl : public CWTLTabViewCtrl
{
public:
    DECLARE_WND_SUPERCLASS(NULL, 
                        CWTLTabViewCtrl::GetWndClassName())

    BOOL PreTranslateMessage(MSG* pMsg)
    {
        pMsg;
        return FALSE;
    }

    BEGIN_MSG_MAP_EX(CDemoTabViewCtrl)
        CHAIN_MSG_MAP(CWTLTabViewCtrl)
    END_MSG_MAP()
};

And declare it as a member variable on the main frame.

...
CDemoTabViewCtrl    m_TabViewDemo;
...

Creation

In a WTL SDI application, create the tab view window as a child of the main frame and assign the window handle to the m_hWndClient member variable.

m_hWndClient = m_TabViewDemo.Create( 
                      m_hWnd, rcDefault, NULL, 
                      WS_CHILD | WS_VISIBLE, WS_EX_STATICEDGE );
...

Adding a tab

To add a tab to the tab control, simply call CWTLTabViewCtrl::AddTab, passing the tab label, the window to manage and optionally the activation state, the image index, and the param to associate with the tab.

CTabDemoHelp    m_DemoTabHwnd;

// Create the tab as a child of the tab control
m_DemoTabHwnd.Create( m_hWndClient );

// Add the tab to the tab control
m_TabViewDemo.AddTab( "Tab Name", m_DemoTabHwnd );
...

Removing a tab

To remove a tab from the tab control, call CWTLTabViewCtrl::RemoveTab with the zero based index of the tab to remove..

// Remove the tab by specifying the zero based index of the 
// tab to remove
m_TabViewDemo.RemoveTab( theIndexOfTheTabToRemove );
    ...

CWTLTabViewCtrl::RemoveTab( ) does not destroy the window handle passed to CWTLTabViewCtrl::AddTab. This should be done when CWTLTabViewCtrl::RemoveTab() is called or when the window is no longer needed.

You can also override the CWTLTabViewCtrl::OnTabRemoved virtual method in the derived tab control class to destroy the window or any memory allocated for the window.

Usage in other scenarios

Using this class in a WTL MDI or WTL dialog application should be straightforward. Let me know how it goes ;-)

Modifying the tab control styles

To modify the styles of the tab control, call the CWTLTabViewCtrl::ModifyTabStyle( ) method. Using this method to set or remove the tab styles, TCS_BOTTOM, TCS_RIGHT and TCS_VERTICAL will set the font to the appropriate orientation.

Evidently, a tab control can handle tabs of different orientations, though it fails to modify the text used to draw the tab label to the proper orientation. The WM_SETFONT message is used to set the appropriate font.

Image Lists

Image lists can be associated with any tab control. These image lists are used to determine the image that appears on each tab. An optional parameter of the CWTLTabViewCtrl::AddTab() method specifies the zero based index of the image in the image list that should appear next to the tab label.

API Reference

All WTL::CTabCtrl methods are available on CWTLTabViewCtrl since the latter is derived from the former. The Windows Help file included with the source download contains a complete API reference, compliments of DOxygen (www.doxygen.org).

Limitations

In order for the tab view control to receive the TCN_SELCHANGE message that notifies the control that a new tab has been selected, parent windows must have the REFLECT_NOTIFICATIONS() macro in their message maps.

BEGIN_MSG_MAP(CMainFrame)
    ...
    REFLECT_NOTIFICATIONS()
    ...
END_MSG_MAP()

If the tab view window is a child of another window, such as CSplitterWindow, you can use the FORWARD_NOTIFICATIONS() macro to forward the WM_NOTIFY messages.

BEGIN_MSG_MAP(thisClass)
    ...
    FORWARD_NOTIFICATIONS()
    ...
END_MSG_MAP()

Demo Application

The demo application is a simple WTL SDI application that houses the tab view control. It allows you to add and remove tabs and dynamically change the style of the tab control.

This application dynamically allocates a window class and stores it as the param associated with the tab. When the tab is removed, it destroys the window and deletes the window class in the overloaded CWTLTabViewCtrl::OnTabRemoved virtual method. It uses the image index to determine the type of window to be deleted.

History

For updates to this class, visit www.jones-net.com. Send me an email if you end up using this class.

  • 06/18/2002 - Creation.

Copyright

This article and all accompanying material is ©2002 Stephen Jones. All rights reserved. The compiled source code may be used at will.

THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. USE IT AT YOUR OWN RISK! THE AUTHOR ACCEPTS NO LIABILITY FOR ANY DAMAGE/LOSS OF BUSINESS THAT THIS PRODUCT MAY CAUSE.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Stephen Jones
Web Developer
United States United States
Stephen Jones is a Lead Software Engineer for Anark Corporation in Boulder, Colorado.
 

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
BugV607 Ownerless expression 'm_Views[inTab]'. wtltabviewctrl.h 226memberPPA_PPA4-Apr-13 20:38 
//==============================================================================
HWND GetTab( int inTab )
{
HWND theTabHwnd = NULL;

if ( inTab >= 0 && inTab < GetTabCount( ) )
{
m_Views[ inTab ];
}
 
return theTabHwnd;
}
GeneralMy vote of 5memberkevinhan408926-Mar-12 16:22 
so nice
Generalusing this control in WTL MDI projectmemberdeepdiverxx24-Oct-10 19:13 
thanks the author and very good control to help to use the tab control easily. but when using this control in MDI child frame, when close the mainframe window, an error happen because of the set view focus function in the "RemoveTab()" function. so I have to modify the "RemoveAllTabs()" to remove the active next tab function since there is not necessary to active any tabs while removing all tabs
GeneralCatch Tab key in TabViewsmembercact20-Nov-08 0:30 
The tab key don't perform the navigation in elements.
 
Anyone solve this?
GeneralRe: Catch Tab key in TabViewsmemberzhouyeheng22-Dec-08 3:18 
jkljkljkjljkjkljkjk
GeneralChild Windowsmemberanubis_ex30-Oct-07 5:55 
I have placed the control on docking windows implementation. but is still confuse where i use FORWARD_DECLARATION(), in child windows( but the docking control doesn´t handle MESSAGE_MAPS) or the class when CWTLTabViewCtrl was inherited??Sigh | :sigh:
 
Sigh | :sigh: Sigh | :sigh:
GeneralRe: Child Windowsmemberzhouyeheng22-Dec-08 3:19 
lklklkl
GeneralMDImemberpicazo4-Mar-06 16:32 
Hello Stephen,
 
I am having a lot of trouble using you ctrl in an MDI WTL application. Would it possible for you to explain how to do this?
 
Thank you very much,
 
-----------------
Genaro
GeneralA error found when use TCS_MULTILINE stylememberRocom.liu27-Jan-05 16:50 
Sigh | :sigh: There may be some bug at CalcViewRect().
I found that sometimes the code as below can't get the correct value.
LONG theRowCount = GetRowCount();
 
The value cause the UI looks very ugly! Please help me!!!
GeneralIncorrect link to demo app.memberblippblapp17-Nov-04 21:46 
Correct link seems to be:
 
http://www.codeproject.com/wtl/TabViewCtrl/CTabViewCtrl_demo.zip
 

GeneralA fix for problems when using in Dialogsussmparedes25-Nov-03 12:43 
When using it as a control in a a dialog the windows are always placed at the left topmost position (0,0) regardless of where the control is placed. This can be fixed by adding the following lines to the CalcViewRect function:
 
WINDOWPLACEMENT wndpl;
GetWindowPlacement(&wndpl);
(*pRect).OffsetRect(wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.top);

GeneralButtons in Tab Lock up AppmemberBillisWrong20-Nov-03 6:44 
My App is a SDI WTL application. My View inherits from CWTLTabViewCtrl and in each tab I add I am dynamically adding ActiveX composite controls.
 
I have two instances where the application locks up when I attempt to click on a button in a tab: the first is when I add a tab on my ActiveX control (a tab within a tab), the second is when I have a dialog with a inherited view added to it dynamically this tab also holds activeX controls.
 
In both cases I can click and use controls such as radio buttons and edit controls but the second I click a button it hangs the app. It doesn't get to my button click handler.
 
Any help would be appreciated.
 
Keith
GeneralWonderfulmemberShawnTassie7-May-03 16:41 
Wonderful control, thanks for sharing. I have found it very useful. By way of a bug though, think this function here:
 
HWND GetTab( int inTab )
{
HWND theTabHwnd = NULL;

if ( inTab >= 0 && inTab < GetTabCount( ) )
{
m_Views[ inTab ];
}
 
return theTabHwnd;
}
 
Specifically this line:
 
m_Views[ inTab ];
 
you probably meant to say:
 
theTabHwnd = m_Views[ inTab ];
 
small little thing and thanks again.

 
-Shawn

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130617.1 | Last Updated 22 Jun 2002
Article Copyright 2002 by Stephen Jones
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid