COXTabViewContainer
Copyright © The Code Project 1997 - 2005, All Rights Reserved

For most applications it's not enough to use only one window to provide all output. There are different solutions for this problem like splitters or docking windows. But they usually have common inconvenience: all windows are shown at the same time. They take a precious screen space while they may be rarely used. 

COXShortcutBar control can be used in order to show a number of child windows while keeping only one active (fully displayed) at a time. But COXShortcutBar was primarily designed to show icons and have a set of notifications that make sense only while using such controls as treeview or listview. 

Very good example of how the problem could be resolved can be found in Developer Studio IDE. For instance "Output" window (with "Build", "Debug", "Find in Files..." panes) or "Result List" window (with "Search", "Lookup", "See Also" and "History" panes). We call them TabViews. 

TabViews can be a good alternative for splitter window when you need to have more than one view per document. Also TabViews can be used within docking window and used as a container for associated windows that are usually implemented as dialog bars. 

So we designed new class that implements TabViews: COXTabViewContainer. 

COXTabViewContainer is easy to use. If you previously worked with splitter windows, the implementation of TabViews will be familiar to you. 
Here is the list of steps that should be taken in order to deploy TabViews in your application: 

First Case: COXTabViewContainer will be used as a container for document view(s). 
1.	Embed a COXTabViewContainer member variable in the parent frame (main frame window for SDI application, MDIChild window for MDI application).
2.	Override the parent frame's CFrameWnd::OnCreateClient member function.
3.	From within the overridden OnCreateClient, call the Create member function of COXTabViewContainer. In this function you have to specify the parent window and optionally you can specify the initial rectangle, window styles and window ID.
4.	After COXTabViewContainer window was successfully created you can populate it with window objects using AddPage or InsertPage function. If you are inserting view object you have to specify runtime class and context information in order not to break documentview architecture. If you are adding window object that is not a document view then you have to create it before adding to COXTabViewContainer window. In AddPage or InsertPage functions you can specify text that will be used as page title in tab button. 

Second Case: COXTabViewContainer will be used as a container for windows within control bar. 
1.	Create your own CControlBar-derived class (you can use our COXSizeControlBar as parent class if you need sizable docking windows). Let's call CMyControlBar.
2.	Embed a COXTabViewContainer member variable in this class.
3.	Override CMyControlBar::OnCreate member function.
4.	From within the overridden OnCreate, call the Create member function of COXTabViewContainer. In this function you have to specify the parent window and optionally you can specify the initial rectangle, window styles and window ID.
5.	After COXTabViewContainer window was successfully created you can populate it with window objects using AddPage or InsertPage function. You have to create window object before adding it to COXTabViewContainer. In AddPage or InsertPage functions you can specify text that will be used as page title in tab button.
6.	Override CMyControlBar::OnSize member function and resize in it COXTabViewContainer object as appropriate

			
The most challenging problem was to support scrolling functionality for windows that would be used as COXTabViewContainer pages. Unfortunately, different windows object that support scrolling (CEdit, CTreeCtrl, CListBox, CListCtrl, CRichEditCtrl, CEditView, CTreeView, CListView, CScrollView to name just the standrad ones) implement it in a different way and the handling of scrolling happens internally in these objects. So in order to control it we should have provided derivations for all of above mentioned classes. Luckily we managed to resolve this problem in different way so it doesn't require any efforts from programmer's side.

Actually, the only thing you have to do is to declare the class of window object that is going to be used as COXTabViewContainer page in a specific way. 
If you declare you class as follows:
	class CMyView : public CEditView 
now you have to do that in the following way:
	class CMyView : public COXTabViewPage<CEditView>

or if you don't derive your own class and just use an object of existing one, e.g.: 
	CEdit m_edit; 
instead you have to define it as: 
	COXTabViewPage<CEdit> m_edit;

COXTabViewPage is internal template based Ultimate Toolbox class that was designed specifically to provide smooth integration of scrolling functionality for any
window within COXTabViewContainer object. All the details of implementation is hidden for different type of windows is hidden. There is no any public functions that you should specifically use. 

But there is one limitation. The base class that is used for derivation has to have default constructor. Some classes doesn't have it (e.g. CFormView). You can resolve this problem through using intermediate class that will be derived from the one that doesn't have default constructor and implement it. Then you just derive your window object class that will be used as COXTabViewContainer page from this intermediate class. Out of standard only CFormView doesn't have default constructor.

Below you will find the steps that should be taken in order to derive classes from CFormView class. 
1.	Use Class Wizard to build CFormView derived class on the base of dialog template as you usually do (let's call it CMyFormView)
2.	CMyFormView will have default constructor which uses CFormView constructor with dialog ID specified.
3.	define another class that will be used as view in your application:

The steps that should be taken in order to implement COXTabViewContainer in CControlBar derived window can be applied to the general case as well. We just decided to show it using CControlBar derived window because we feel it is going to be used as parent window for COXTabViewContainer in most cases. 
Above we described the process of creating and populating of COXTabViewContainer object. In most cases that would be all the code you need. For those who need to change dynamically the contents of COXTabViewContainer object we provide a set of the following functions. 

In order to remove any page at run time you have to use DeletePage function. 

To access scroll bar objects that we use internally in order to provide scrolling functionality for COXTabViewContainer pages you have to call GetHorzScrollBar and GetVertScrollBar functions. 

To set/retrieve the page title that is displayed in corresponding tab button use GetPageTitle and SetPageTitle functions. 

To set/retrive active page index call GetActivePageIndex and SetActivepageIndex functions. 

Refer to the class reference for list and description of all public functions.

Also take look at the following samples that can be found in .\samples\gui subdirectory of your ultimate Toolbox directory: 
	TabViews		- text editor with three panes: text editor, hex viewer, list view with statistics on number of unique symbols found in text. 
	Dynamic TabViews 	- MDI application that shows how to addremove pages dynamically