Click here to Skip to main content
6,629,377 members and growing! (23,473 online)
Email Password   helpLost your password?
Desktop Development » Tabs & Property Pages » Tabs and Property Pages     Intermediate

Tab controls and Splitters - mixing together

By Igor Katrayev

WTL class that tabs and splits child views in your SDI application
VC7, VC7.1, VC8.0Win2K, WinXP, Win2003, ATL, WTL, VS.NET2003, Dev
Posted:30 Dec 2003
Views:59,223
Bookmarked:30 times
Announcements
Loading...
 
Search    
Advanced Search
Add to IE Search
printPrint   add Share
      Discuss Discuss   Broken Article?Report  
14 votes for this article.
Popularity: 4.26 Rating: 3.72 out of 5
1 vote, 7.1%
1
1 vote, 7.1%
2
1 vote, 7.1%
3

4
11 votes, 78.6%
5

Tab controls and Splitters - mixing together

Introduction

Despite there being a lot of examples of tabbed and splitter view usages and implementations I couldn't find a solution that mixed it together. So I developed a WTL class to simplify building SDI applications that use the tabbed and splitted views. At first time I tried to use a standard window tab control. But later I couldn't resist to use an amazing tab control implementation done by Bjarke Viksoe(CCustomTabCtrl) and Daniel Bowen(CDotNetTabCtrl).

What it does

There are three main features of this class. Using drag and drop operations you can

  • change a tab position in tab control
  • drag a tabbed client view into the other client view pane
  • arrange tabbed client view against the edges of another tabbed pane ( split vertically or horizontally with the others)

Using the code

The main class that adds all features above is SplitPane. You should not meet any difficulties to use it in your application. First of all you need to include the follow files in the place where they can be accessible by compiler:

atlgdix.h Additional GDI/USER wrappers. Written by Bjarke Viksoe
CustomTabCtrl.h A base class to help implement Tab Controls with different appearances. Written by Bjarke Viksoe. Several improvements by Daniel Bowen.
DotNetTabCtrl.h Tab control derived from CCustomTabCtrl meant to look like the tabs in VS.Net (MDI tabs, solution explorer tabs, etc.). Written by Daniel Bowen
DockTabPane.h Tab Control and Tab Pane implementation. Uses all include files above
DockTabSplitPane.h Split Pane implementation. Includes DockTabPane.h

Then create SDI application project with ATL/WTL Wizard. You have to turn off "Minimize CRT use in ATL" configuration option. Add Split Pane class as a main view in it with the following steps:

  • Include DockTabSplitPane.h, for instance, in stdafx.h file.
  • For your CMainFrame class add SplitPane class member and an inheritance from CallBackListener interface class:
class CMainFrame
    : public CFrameWindowImpl< CMainFrame>
    , public CUpdateUI< CMainFrame>
    , public CMessageFilter
    , public CIdleHandler
    , public DockSplitTab::CallBackListener
    ....
    DockSplitTab::SplitPane mainPane;
    ....
public:
    CMainFrame();

The objective of CallBackListener class is to provide Split Pane notifications to the owner or parent object. I think it's simpler then win32 messages. Along with the inheritance from MainFrame class you can design a special class adapter that implements all communication needs between SplitPane and its owner. So don't forget initialize mainPane with a pointer to this class as showed below:

...
CMainFrame::CMainFrame()
    : mainPane( this, true)
    ...
{}
...

The second parameter for mainPane constructor sets tab control bar on the top for all tab panes that Split Pane contains. To finish mainPane put Split Pane window creation code in CMainFrame::OnCreate event handler and assign it to m_hWndClient property:

LRESULT CMainFrame::OnCreate(UINT, WPARAM, LPARAM, BOOL&) {
    ...
    this->m_hWndClient = this->mainPane.create( this->m_hWnd);
    ...
}

That's it. We have finished Split Pane definition as a main view window for the application. Do not forget to define function handlers for CallBackListener interface. How to do this see demo project.

I use DockSplitTab namespace for all definitions. Of course you can put the line of code below instead of using the namespace specifier for each name.

using namespace DockSplitTab;

SplitPane class

Public methods:

// creates a new Split Pane window with parentWnd and rect parameters

HWND create( parentWnd, rect);

// adds the new client view window to Split Pane.

// The new client view is added into the focused tab pane

bool append( caption, clientViewWnd, tooltip, imageIndex);

// detaches the client view window from Split Pane. 

// This method changes a parent window of the client window view 

// to the Split Pane parent one.

bool detachClientView( clientViewWnd);

// returns the client view window that receives the keyboard focus

HWND focusedClientView();

// sets the keyboard focus to a tab pane at the specified position

bool setFocusTo( x, y)

// sets the keyboard focus to the specified client view window

bool setFocusTo( clientViewWnd) {

// returns the number of client view windows in Split Pane

int getClientViewCount();

// returns the rectangle of tab pane, if any, is at a specified position

bool getClientViewRect( point, &rect);

// move the client view window (sourceWnd) to the same 

// tab pane where the specified client view window is located

void moveClientView( HWND sourceWnd, HWND targetWnd);

// move all client view windows to the specified split pane.

void moveClientViewsTo( SplitPane* targetPane);

// splits source client view window (sourceWnd) with the target client view

void splitClientView( sourceWnd, targetWnd, targetArea);

// set and get Image List

void setImageList( HIMAGELIST imgList);
HIMAGELIST getImageList();

CallBackListener interface class

This class provides a notification interface between SplitPane and its owner class.

// triggered when client view client view wnd has gained the keyboard focus

virtual void clientActivate( childWnd, clientViewWnd) = 0;

// triggered when client view client view wnd 

// got doble mouse click on the tab button

virtual void clientDblClick( childWnd, clientViewWnd) = 0;

// triggered the close button was pushed for the client view client

virtual void clientCloseClick( childWnd, clientViewWnd) = 0;

// drag and drop notifications

virtual void dragStart(  childWnd, clientViewWnd, x, y, keysPressed) = 0;
virtual void dragOver(   childWnd, clientViewWnd, x, y, keysPressed) = 0;
virtual void dragDrop(   childWnd, clientViewWnd, x, y, keysPressed) = 0;
virtual void dragCancel( childWnd, clientViewWnd) = 0;

// performs the drag and drop tracking with drag and drop notifications

void trackDragAndDrop( HWND hWnd, POINT startPoint, 
    bool lockWindowUpdate = false);

What's inside

I don't believe in "black box" concept. I think it's always better to know what's inside so I try to give some explanations what's inside of SplitPane class. The basic building block is Pane class that can be used independently in your application as showed for SplitPane if you do need only tabbed pane and ability to change a tab position for tabbed views. SplitPane owns the hierarchy of Tab Pane objects using VSpliter and HSpliter classes which are specializations of standard WTL::CSplitterWindowImpl<> class template. You can check it using Spy++ utility.

class ClientProperties - provides three Client View attributes: caption, tooltip and image index
the required parameter for Pane::get method.
class TabControlItem - inherited from CCustomTabItem class and includes client view window handler member.
class TabControl - specializes CDotNetTabCtrlImpl<> class template.
class Pane - container class for a tab control and all client view windows linked with the tab control
class RectTracker - helper class to draw tracker rectangle during drag and drop operations
class VSplitter - vertical splitter window. Specializes CSplitterWindowImpl<> class template
class HSplitter - horizontal splitter window. Specializes CSplitterWindowImpl<> class template
class SplitPane::DragContext - inherited from RectTracker class.

What to do next

Obviously it needs some serialization mechanism. Any other ideas? ;-)

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

About the Author

Igor Katrayev


Member

Occupation: Web Developer
Location: United States United States

Other popular Tabs & Property Pages articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 9 of 9 (Total in Forum: 9) (Refresh)FirstPrevNext
GeneralVC6 Project? PinmemberFred Koestner9:20 6 Jan '04  
GeneralRe: VC6 Project? PinmemberIgor Katrayev10:47 6 Jan '04  
GeneralRe: VC6 Project? PinmemberFred Koestner11:09 6 Jan '04  
GeneralRe: VC6 Project? PinmemberIgor Katrayev11:14 6 Jan '04  
GeneralIs there any MFC version? PinsussAnonymous7:35 1 Jan '04  
GeneralRe: Is there any MFC version? PinmemberIgor Katrayev5:03 2 Jan '04  
GeneralRe: Is there any MFC version? PinmemberJuanValdez4:42 6 Jan '04  
Generalsplitter PinmemberIgor Vigdorchik12:50 31 Dec '03  
GeneralRe: splitter PinmemberIgor Katrayev5:15 2 Jan '04  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 30 Dec 2003
Editor: Nishant Sivakumar
Copyright 2003 by Igor Katrayev
Everything else Copyright © CodeProject, 1999-2009
Web20 | Advertise on the Code Project