// History of CoolTabCtrls.h prior to codeproject article about it
// History (Date/Author/Description):
// 2002/06/12: Daniel Bowen
// - Several updates to make CCustomTabCtrl derived classes act
// more like a common control:
// * Window Styles: CTCS_*. Use the same bits as the
// tab control style where possible
// (CTCS_BOTTOM == TCS_BOTTOM, etc.)
// * Notifications: CTCN_*. Use the same bits as the
// tab control notifications where possible
// (CTCN_SELCHANGE == TCN_SELCHANGE, etc.)
// * Structures:
// * Better implementation of custom drawing. It now works much
// more similar to how custom drawing works for common controls.
// * Remove the dependancy on REFLECT_NOTIFICATIONS.
// No common control needs notifications reflected, and neither
// does this now.
// * Don't have the tab itself depend on TCN_INITIALIZE/CTCN_INITIALIZE.
// There's no precedent for this type of notification in any of the
// common controls. Instead, there is an overrideable "Initialize()"
// function if a derived class needs to do some initialization
// outside of handling WM_SETTINGCHANGE (which is sent during the
// default initialization)
// * Remove "SetSizeSettings" and "GetSizeSettings", since there is
// no precident for this in a common control, and was mainly being
// used by derived classes (who have access to the member variable).
// - Style updates:
// * CTCS_BOLDSELECTEDTAB. New. Instead of exposing methods
// "SetBoldSelectedTab" and "GetBoldSelectedTab", use this style.
// * CTCS_TOOLTIPS. Now required if you want the tab control
// to use tooltips (instead of always using tooltips).
// * CTCS_SCROLL. New. This enables "scroll buttons". When the tab
// items don't get all the real estate they want, they overflow
// and the scroll button for that side is enabled.
// You can call the methods Get/SetScrollDelta and
// Get/SetScrollRepeat to adjust how much is scrolled, and
// how fast scrolling is repeated when holding down the button.
// * CTCS_CLOSEBUTTON. New. This enables a "close" button. When this
// button is clicked, the parent gets a "CTCN_CLOSE" notification.
// * CTCS_HOTTRACK. New. Enables hot tracking tab items.
// If you are targetting Windows 2000/98 or later, be sure to
// #define WINVER and/or _WIN32_WINNT to 0x0500 or later before
// including this file (usually in your precompiled header)
// so that the new "COLOR_HOTLIGHT" is used.
// Note: If you specify CTCS_SCROLL or CTCS_CLOSEBUTTON,
// those buttons are always hot tracked regardless of this style.
// - Structure updates:
// * Rename NMCOOLTABITEM to NMCTCITEM
// * Rename NMCOOLTAB2ITEMS to NMCTC2ITEMS
// * CTCHITTESTINFO (instead of TCHITTESTINFO)
// * NMCTCCUSTOMDRAW (extends NMCUSTOMDRAW). The precident for
// this strucuture are custom draw structures like
// NMTBCUSTOMDRAW (toolbar) and NMLVCUSTOMDRAW (list view)
// * TC_SIZES renamed to CTCSETTINGS. This structure may hold
// more settings in the future.
// - Tab Item updates:
// * rename CCoolTabItem to CCustomTabItem
// * remove HWND from CCustomTabItem, and have new "CTabViewTabItem"
// that inherits from CCustomTabItem.
// - "State" member variable. Several state and flag related things
// are kept as bits in a new state member variable.
// - New default WinTraits used that specifies CTCS_TOOLTIPS by default
// - Message handlers shouldn't be overrideable functions. OnSettingChange
// was guilty of this. Change it so that the function isn't called
// directly, and that each derived class implementing OnSettingChange
// has the corresponding message map entry for it.
// - EnsureVisible. Useful when CTCS_SCROLL is set, and you want to see
// a tab that is scrolled partially or completely out of view.
// The precident for this is the list view message "LVM_ENSUREVISIBLE".
// - Resizing:
// * UpdateLayout - In your derived class, instead of overriding UpdateLayout,
// override UpdateLayout_Default and/or UpdateLayout_ScrollToFit
// * Override CalcSize_CloseButton and/or CalcSize_ScrollButtons to
// support the close button and/or scroll buttons
// - Drawing:
// * Overrideables: DoPrePaint, DoItemPaint, DoPostPaint. 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.
// * Paint the close button and scroll buttons in DoPostPaint
// (depending if the corresponding styles are set)
// - Move updating of the tab item tool tip RECT updating to
// "UpdateTabItemTooltipRects" in the base CCustomTabCtrl class.
// - Hit test also can check for close button and scroll buttons.
// - GetItemRect accounts for any scroll offset.
// - Rename m_fontBold to m_fontSel, and always use it as the "selected item font"
// - Handle WM_CAPTURECHANGE and clear any mouse down tracking
// (even if we do a ReleaseCapture when we have the capture,
// WM_CAPTURECHANGE is sent).
// - Fix small issues with DeleteAllItems that would cause an ASSERT.
// The current selection wasn't being properly cleared, and
// would be erroneously set to 0 (which is a valid index of the first item)
// 2002/05/13: Daniel Bowen (DDB)
// - Compile under VC 7 and update a few minor issues
// 2002/05/09: Daniel Bowen (DDB)
// - Move CDotNetTabCtrl and CDotNetButtonTabCtrl out of CoolTabCtrls.h
// into DotNetTabCtrl.h. Relevant history also moved.
// - Renamed CFlatTabCtrl to how Bjarke renamed it - CSimpleDotNetTabCtrl
// - Don't depend on atlmisc.h directly (CRect, CPoint, etc.).
// If compiling under VC7 then you'll need atlstr.h,
// and if under VC6 then you'll still need atlmisc.h
// (for the time being...).
// - NM_DBLCLK
// - NM_RDBLCLK
// - Update most notifications and operations that could use it
// (SetCurSel, DeleteItem, etc.) to use the new NMCOOLTABITEM or
// - Use CAtlArray instead of CSimpleArray to hold the items.
// If compiling under VC 7, use CAtlArray. If compiling under
// VC 6, have a "fake" CAtlArray that inherits from CSimpleArray,
// but has a public interface like CAtlArray. This was needed
// so that items can be inserted at any position.
// - Several suggestions from Bjarke Viksoe
// * DefWindowProc() in OnCreate
// * bHandled = FALSE in OnDestroy (so others can see the message)
// * Handle WM_SIZE, and call UpdateLayout.
// * Call UpdateLayout in OnSettingChange
// * Updates to CButtonTabCtrl, CFolderTabCtrl, and CSimpleDotNetTabCtrl
// - Let the handler of notifications we send be able to cancel
// the default handling of LButtonDown, RButtonDown,
// LButtonDblClk, RButtonDblClk, DeleteItem
// This is done by returning a non-zero value from the
// notification handler.
// - Additional arguments to InsertItem to select the item inserted
// - MoveItem and TCN_MOVEITEM
// - SwapItemPositions and TCN_SWAPITEMPOSITIONS
// - Additional arguments to DeleteItem to not get the default
// handling of changing the selected item if the selected
// item is being deleted, and an argument to say not to send
// a notification about the deletion.
// 2002/04/23: Daniel Bowen (DDB)
// - Tooltips. The way we implement tooltips is to have as many
// "tools" as there are tabs. The relationship of
// tool ID => tab index is:
// tool ID = tab index + 1 (to avoid 0 as an ID)
// Adding and removing tabs adds and removes the "last" tooltip tool.
// In UpdateLayout, we set the RECTs for the tooltip tools,
// and we have it ask us for the text all the time,
// and give back the text for the corresponding tab.
// - New "CCoolTabItem" class that is used instead of TCITEM.
// - CCustomTabCtrl now has another template parameter -
// the items "array" type. Its default is "CCoolTabItem".
// If you want, you could use your own class that inherits
// from CCoolTabItem when creating a new type of tab control.
// - The "sizes" parallel array is now obsoleted, because
// the RECT for the tab is kept in CCoolTabItem.
// - Several of the public "Interfaces" have been modified.
// This was done in conjunction with what would make more
// sense for CCoolTabItem. Here an attempt at the list:
// * GetItem - Now returns a pointer to the corresponding tab item
// * SetItem - I've obsoleted it for now. It can come back
// if someone really wants it. Now, instead of calling SetItem,
// call GetItem to get the pointer to the TItem, update
// what you want through the methods on TItem (i.e., CCoolTabItem),
// then call UpdateLayout and Invalidate if appropriate.
// * FindItem - Since TItem (CCoolTabItem) doesn't have a "mask"
// guy anymore, FindItem has a new parameter to specify
// which fields to care about in the search. These flags
// are an enumeration in CCoolTabItem.
// * InsertItem - You can build a TItem instance and pass
// a pointer to that in, or you can use the new version
// of InsertItem where you can just pass function arguments.
// - New "CreateNewItem" and "DeleteItem" that manage the memory
// allocation/deallocation of the TItem; These are overrideable.
// - Call SetCurSel and SetFocus so that they are overrideable.
// - Some variable renaming.(idx => nIndex, cnt => nCount, etc.)
// - Some format changes in CCustomTabCtrl (tabs, brace placement, etc.)
// 2002/04/22: Daniel Bowen (DDB)
// - Changed "struct TC_SIZES" from using int's to using char's.
// This makes an instance take up 4 bytes instead of 16 bytes.
// - 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.
// 2002/01/30: Daniel Bowen (DDB)
// - Rename Bjarke's original CDotNetTabCtrl to CFlatTabCtrl
// - Added my version of CDotNetTabCtrl based on Pascal's
// * 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)
// - Utilize COffscreenDrawRect for flicker-free drawing
// (requires updated atlgdix.h containing COffscreenDrawRect)
// - Handle WM_RBUTTONDOWN to allow switching tabs,
// and fire NM_RCLICK notification
// - When changing the selection, redraw entire client area
// to avoid visual artifacts in case an implementation
// doesn't keep each tab the same size always
// (such as if the selected tab is bolded and slightly bigger,
// or if there are divider lines between tabs).
// - Added method "FindItem" that let's you search for an item
// with some or all the members that have the requested values.
// It is meant to work similar to CListViewCtrl::FindItem and
// LVM_FINDITEM (since there are no similar messages for tab controls)
// - Updated "DeleteItem" to better handle the case when the
// deleted item is before the selected item. It now keeps the
// same item selected that was selected before, and adjusts
// m_iCurSel as appropriate (this was needed for doing TabbedMDI.h)
// - Updated "GetItem" so that if bits in the mask are requested
// that aren't acutally in the stored item, those bits are cleared,
// so that the caller of "GetItem" can determine which bits
// it got, compared to which it asked for.
// This update also allows you to let some tabs have images and
// others not have images, and have it work properly.
// 11/06/2001: Pascal Binggeli (PBI)
// - Added support for ImageList
// - Added support for not subclassing from CStatic.
// - Added CDotNetTabCtrl2 class.