Anyone who ever tried to implement tab controls using plain Windows API will probably agree with me that it's a ****ing PITA to get it working properly.
Some of the problems you'll most likely be facing, mostly because of poor documentation:
- Handling and adjusting the windows for each tab
- Getting Windows to draw the themed background on the windows
- Adding transparent (32-bit) icons to tabs
After a lot of googling and guessing around, I got most of this stuff working.
I came up with a bunch of functions to help with getting tab controls work without having to deal with all the hassle.
The functions should be used exclusively, that is without modifying tab items yourself as the functions assume certain conditions and might cause undefined behaviour if things aren't as expected.
Some of the things you shouldn't do:
- Add a tab without using the appropiate function
- Remove a tab without using the appropiate function
- Change the tab items' lParam value (they hold the window handles)
- Change the tab's ImageList
- Call SetProp on the tab window with "TabCtrlCurWnd" ;D
You can still modify the tab control's GWLP_USERDATA.
A quick overview over the functions:
int AddTab(HWND TabWindow, HWND Window, char * Caption, int Index)
Adds a tab item to the tab control and associates the window to it.
The window is moved and resized to fit the tab control dimensions.
bool RemoveTab(HWND TabWindow, int Index)
Removes the tab item from the tab control.
bool TabCleanup(HWND TabWindow)
Removes all tab items from the tab control.
Cleans up internal resources and hides all windows associated with it.
It's recommended to call this function before the tab control is destroyed,
e.g. if you get a WM_CLOSE message in your dialogbox proc.
bool SetTabIcon(HWND TabWindow, int Index, HICON Icon)
Sets the tab item's icon.
Supports 32bit icons (24bit + 8bit alpha) if comctl32.dll v6 is used (ie. visual styles enabled).
The icon should be 16x16 in size and at least contain an 8bit (256 colors) channel.
int TabToFront(HWND TabWindow, int Index)
Selects the specified tab and shows the appropiate window.
For a more detailed overview over the functions take a look at tabs.h
In order for the tab selection to work, you will have to add this piece of
code to the tab control's parent window handler (usually the dialog procedure):
case TCN_SELCHANGE: // Get currently selected tab window to front
Alright, that should be it
Attached are the .h and .cpp and an example project.