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;
m_DemoTabHwnd.Create( m_hWndClient );
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..
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.
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.