Click here to Skip to main content
15,885,869 members
Articles / Desktop Programming / WTL

Custom Tab Controls, Tabbed Frame and Tabbed MDI

Rate me:
Please Sign up or sign in to vote.
4.90/5 (144 votes)
13 Jul 200522 min read 1.6M   35.5K   395  
An extensible framework for creating customized tabs in ATL/WTL, with a VS.NET-like tab control implementation, tabbed frames, tabbed MDI, and more.
// History of DotNetTabCtrl.h prior to codeproject article about it
//
// History (Date/Author/Description):
// ----------------------------------
//
// 2002/06/12: Daniel Bowen (DDB)
// - Notifications no longer need to be reflected
// - Draw close button in CDotNetTabCtrlImpl when
//   CTCS_CLOSEBUTTON style is set (draw in PostPaint)
// - Draw scroll buttons in CDotNetTabCtrlImpl when
//   CTCS_SCROLL style is set.
// - Improve drawing.  Override DoPrePaint, DoItemPaint, DoPostPaint
//   instead of being a "client" of custom drawing.  Use the
//   custom draw structure colors, so that you pick up
//   any changes that a client might be doing if they truly are
//   using the custom draw functionality.  Override
//   InitializeDrawStruct to specify the defaults.
// - Move updating of the tab item tool tip RECT updating to
//   "UpdateTabItemTooltipRects" in the base CCustomTabCtrl class.
// - On WM_SETTINGCHANGE, if CTCS_BOLDSELECTEDTAB is set,
//   the bold font wasn't being deleted if one had already been set
//
// 2002/05/13: Daniel Bowen (DDB)
// - Minor updates to avoid level 4 warnings
// - Take out a trace statement in UpdateLayout
//
// 2002/05/09: Daniel Bowen (DDB)
// - Move out of CoolTabCtrls.h into its own file
//   to match how Bjarke has reorganized it.
//   Relevant history also moved.
// - Have the original CDotNetTabCtrl turn into
//   an overrideable CDotNetTabCtrlImpl, and have
//   CDotNetTabCtrl inherit from CDotNetTabCtrlImpl.
// - Minor updates to accomodate changes I made
//   to CCustomTabCtrl (unsigned vs. signed types, etc.).
// - Incorporate suggestsion from Bjarke Viksoe
//   (don't use atlmisc.h types, AtlGetDefaultGuiFont()
//   instead of AtlGetStockFont(DEFAULT_GUI_FONT),
//   UpdateLayout in OnSettingChange, etc.)
//
// 2002/04/26: Daniel Bowen (DDB)
// - CDotNetTabCtrl and CDotNetButtonTabCtrl -
//   Owen Gunter [OwenG@d-graphic.co.uk] pointed out that
//   the tabs were "shifting" when the selection changed
//   (in tab controls that aren't bolding the selected tab).
//   This was due to using "SelMargin" in some recent updates.
//   Now, SelMargin is not used, just "Margin" - and the
//   tabs shouldn't shift like they did.
// - Owen Gunter [OwenG@d-graphic.co.uk] suggested some
//   slight modifications to CDotNetTabCtrl for drawing
//   the tab background on the right side when the tabs
//   are shown on top.  Those modifications are in here now.
//
// 2002/04/22: Daniel Bowen (DDB)
// - Move the Image List and "bold selected tab" stuff to the
//   base "CCustomTabCtrl" class.  In a future revision, I'll
//   probably update the base class to honor these, but for
//   now, its up to the deriving class whether or not to use
//   these things.  Having them there makes it easier to use
//   any CCustomTabCtrl derived class where there's a template
//   parameter for the tab class, and where it might want to
//   use the image list or bold the selected tab.
// - When the tabs are not a subclassed static control,
//   the "GetFont" and "SetFont" calls were going in the bit
//   bucket.  CCustomTabCtrl now has a member variable
//   "CFont m_font", and all the derived classes (with one
//   exception) now use the base class version instead of their own.
//   If a derived class has a bold font, they still declare
//   that themselves.  Because the base class "m_font" is
//   managing the lifetime of the font (i.e., it calls DeleteObject
//   in the destructor), the handler for WM_SETFONT makes
//   a copy of the font instead of "pointing" to it.
//   Typically, no one should be sending us WM_SETFONT.
//   CFlatTabCtrl is the one deriving class that has its
//   own version of m_font, because it wants to do a
//   SetFont(m_fontBold) - which with the new way of things
//   would cause CCustomTabCtrl::m_font and CFlatTabCtrl::m_fontBold
//   to be the same.
// - More updates for CDotNetTabCtrl and CDotNetButtonTabCtrl
//   to accomodate the current DPI and system metrics.
//   The updates were focused on getting the padding and margin
//   for the active and inactive tabs to be a better match
//   for what VS.Net does under various DPI and font settings.
//   It turned out to be quite difficult to get a pixel-for-pixel
//   match to VS.Net under various font sizes and DPI settings.
//   What's there now is not a perfect match, but its pretty good.
// - Change the logic for CDotNetTabCtrl and CDotNetButtonTabCtrl
//   when they don't get all the real estate their tabs want.
//   When the desired widths of the tabs would be too big for
//   the client area:
//    * First, the inactive tabs are proportionally reduced,
//      and the selected tab is given its desired width
//    * Once the smallest inactive tab would be too small,
//      the inactive tabs are no longer made proportional to
//      their desired size, but are all made the same size.
//      The selected tab is still given its desired width.
//    * Once there's not enough room to show the selected tab
//      at its desired width and all the inactive tabs at
//      the same minimum width, all of the tabs are made
//      the same width (both the selected and inactive tabs)
//   NOTE: This is not the approach VS.Net takes.  VS.Net
//    first gives away the real estate for the widest tabs
//    until all the tabs are the same width.  If you'd rather
//    have that approach, create a new class that inherits
//    from CDotNetTabCtrl/CDotNetButtonTabCtrl and override
//    UpdateLayout with your implementation.
//   
// 2002/04/17: Daniel Bowen (DDB)
// - Owen Gunter [OwenG@d-graphic.co.uk] pointed out that the
//   tab background and font height of CDotNetTabCtrl didn't match
//   what he saw in the tabs under his version of Visual Studio.
//   When I originally chose those, I was running Visual Studio
//   RC1 under Windows XP with the Windows XP theme and the
//   silver color scheme and large fonts.  It wasn't clear to me
//   at the time if the tab background color was dependant on a
//   system color (it didn't seem to be) or if the font was dependant
//   on a system metric (I had changed the caption font and saw
//   it didn't change).
//
//   I've now revisited the issue, and there's now a much better
//   approximation of what Visual Studio.Net is doing.
//   * The tab font is the "ICON" font, which can be retrieved
//     by calling SystemParametersInfo with SPI_GETICONMETRICS.
//     CDotNetTabCtrl and CDotNetButtonTabCtrl now use this
//     font instead of a hardcoded 9 point Tahoma.
//   * The tab background is a "lightened" version of COLOR_BTNFACE.
//     The formula used in CDotNetTabCtrl isn't exactly the same
//     formula that VS.Net uses, but from my experiments, its
//     never more than 1 off for red, green, or blue
//     (with each of these being 0-255)
//   * The "inactive tab" text color is a "darkened" version of
//     COLOR_GRAYTEXT.  Again, the formula is an approximation
//     to what VS.Net is doing, but its seems to be very close.
//   * CDotNetTabCtrl was doing some outlines with a black ben
//     and a white pen.  After some experiments, I found that
//     VS.Net was actually using COLOR_BTNTEXT and COLOR_BTNHIGHLIGHT.
//     I've updated CDotNetTabCtrl to do the same.
//
// 2002/01/30: Daniel Bowen (DDB)
// - Added my version of CDotNetTabCtrl based on Pascal's
//   CDotNetTabCtrl2:
//    * Added support for divider lines between tabs
//    * Closer match to look of tabs used in VS.Net
//    * Support for bolding text of selected tab
// - Added CDotNetButtonTabCtrl (to look like VS.Net
//    view of HTML with the Design/HTML buttons)
//             

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

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


Written By
Architect
United States United States
Daniel Bowen used to work as a Software Engineer for Evans & Sutherland in Salt Lake City, Utah working on the modeling tools for high end flight simulators. He then worked for the startup company WiLife Inc. in Draper, Utah working on the software portion of an easy to use and affordable digital video surveillance system. WiLife Inc. is now part of Logitech Inc.

Comments and Discussions