Click here to Skip to main content
Click here to Skip to main content
Go to top

Reusable base class for SplitterWnd

, 2 Sep 2001
Rate this:
Please Sign up or sign in to vote.
A class derived from CSplitterWnd which makes splitting and switching of views simple.

Introduction

Have you ever spent time trying to get the splitting windows right, then added a method of switching views and even worse, tried to make the individual splitters to expand over the whole window? And then you want to make the whole damn (sorry) thing persistent for the next time you start the program? Well I did, and every time I had to look up in old code and every time I made errors and every time it took me a long time to get it to work the way I had it planned.

Well, I now sat down and solved it - once for all. By writing a reusable base class. Of course, I had a little help from many useful articles posted by this and other sites. The methods ShowColumn and HideColumn are taken from an article posted by Oleg Galkin on www.codeguru.com, the articles by Caroline Englebienne, Adrian Roman and Dongik Shin helped me writing the methods to support switchable views.

And now I'm ready to share once more. You may use this class for your own projects as you like, but it is AS IS, use at your own risk, I cannot be held responsible for any damage...blah blah blah ...

To use this base class is simple, however there are a few things you need to consider, else you will get one of the many asserts from within the CSplitterWnd.

This class uses only static splitters and will only split each window once, either vertically or horizontally. Once the window is split, you can split one ore both panes again and again and... Have a look at the screen shot above. I simple split the first window into two panes, a left and right one. Then I split the left pane again, this time into a top and bottom pane. The bottom pane is now split again vertically and so on.

To do this, you need to include the source files ST_splitterwnd.h and ST_splitterwnd.cpp into your project.

Then add a ST_SplitterWnd member for each split to your CMainFrame:

    ST_SplitterWnd* m_pSplitterWnd;
    ST_SplitterWnd* m_pSplitterWnd2;
    ST_SplitterWnd* m_pSplitterWnd3;
    ST_SplitterWnd* m_pSplitterWnd4;

In CMainFrame::OnCreateClient, you need to create the first ST_SplitterWnd:

    m_pSplitterWnd = new ST_SplitterWnd();
    m_pSplitterWnd->Create(this,NULL,NULL,pContext,true);

The Create method is defined as follows:

    bool Create(CWnd* pParentWnd, // this will do
      CRuntimeClass* pView1, // Add the view for 
                             // the left(or top) pane or NULL
      CRuntimeClass* pView2, // Add the view for
                             // the right(or bottom) pane or NULL
      CCreateContext* pContext, // pass the pContext pointer
                                // from the OnCreateClient
      bool bVertical, // set to true if the window
                      // is split vertically else false
      int nID = AFX_IDW_PANE_FIRST); // this parameter
                                     // does not need redefinition
{

Note: If you want to split a window into further subdivisions, pass NULL to the pView1 and/or pView2 parameter. If you fail to do this, the application will assert.

The view1 and view2 is used to pass the view class to the SplitterWnd, just like it is done with the 'normal' CSplitterWnd. It has to be passed using the macro RUNTIME_CLASS, e.g.:

RUNTIME_CLASS(CSplitterWndTestView3)

Use the method AddSubDivision to apply a further split:

   m_pSplitterWnd2 = 
     m_pSplitterWnd->AddSubDivision(LEFT_SIDE,
     RUNTIME_CLASS(CSplitterWndTestView3),NULL,pContext,false);

The above sample will split the left pane horizontally and fill the top pane with a view, while leaving the bottom part empty for further splitting by passing NULL. The method AddSubDivision is defined as follows:

    ST_SplitterWnd* AddSubDivision(int nSide, // use LEFT_SIDE, 
                                              // RIGHT_SIDE, TOP_SIDE
                                              // or BOTTOM_SIDE
        CRuntimeClass* pView1, // Add the view for the
                               // left(or top) pane or NULL
        CRuntimeClass* pView2, // Add the view for the
                               // right(or bottom) pane or NULL
        CCreateContext* pContext, // pass the pContext pointer
                                  // from the OnCreateClient
        bool bVertical); // true for a vertical split,
                         // false for a horizontal split

Basically, the parameters are used in the same way as the Create parameters. The first parameter (nSide) is used to describe the pane in which the split has to be added. Four constants (LEFT_SIDE, RIGHT_SIDE, TOP_SIDE and BOTTON_SIDE) are defined for this purpose. The last parameter tells the method to perform a vertical split (true) or a horizontal split (false). The AddSubDivision returns a pointer to a new instance of a ST_SplitterWnd object which can be split again (and again..):

   m_pSplitterWnd3 = m_pSplitterWnd2->AddSubDivision(BOTTOM_SIDE,
                             NULL,
                             RUNTIME_CLASS(CSplitterWndTestView2),
                             pContext,
                             true);   
   m_pSplitterWnd4 = m_pSplitterWnd3->AddSubDivision(LEFT_SIDE,
                             RUNTIME_CLASS(CSplitterWndTestView4),
                             RUNTIME_CLASS(CSplitterWndTestView5),
                             pContext,
                                        false);

An additional feature of this class is the possibility to switch between views within a pane. In order to do this, you use the method AddView. Note: When using AddView, the pane to which the views must be added must not contain a view, with other words, they must be initialized with NULL just like the pane which will be split once more.

    m_nViewNo1 = m_pSplitterWnd->AddView(RIGHT_SIDE,
                         RUNTIME_CLASS(CSplitterWndTestView),
                         pContext);
    m_nViewNo2 = m_pSplitterWnd->AddView(RIGHT_SIDE,
                         RUNTIME_CLASS(CSplitterWndTestView6),
                         pContext);

The method AddView is defined as follows:

        int AddView(int nSide, // use LEFT_SIDE, RIGHT_SIDE,
                              // TOP_SIDE or BOTTOM_SIDE
          CRuntimeClass * pViewClass,  // Add the view for the 
          CCreateContext* pContext);  // pass the pContext pointer
                                     // from the OnCreateClient

Basically that will do the job. There are three more methods of interest: SetInitialStatus, SwitchToView and ToggleSide:

  • SetInitialStatus is used to restore the settings, such as size and position of each pane, from the registry.
  • SwitchToView toggles between multiple views within a pane.
  • ToggleSide hides and displays a pane.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Daniel Zuppinger
Chief Technology Officer
Switzerland Switzerland
Professional IT developer since 1983. First projects with Cobol, then Pascal, Modula2, C and since Visual C++ 1.0 also with C++. Works since 1986 as Consultant, between 1990 and 2008 for Infobrain in Switzerland, currently employed by enValue (also Switzerland).
Current field is the project management and development of software for Bank applications.
Married, two daughters, Hobbies : Paragliding, Orienteering, Mountainbiking, Photography

Comments and Discussions

 
QuestionMFC application Pinmembertaimmoor25-Feb-12 5:10 
Questionsplitting window Pinmembertaimmoor25-Feb-12 2:00 
AnswerRe: splitting window PinmemberDaniel Zuppinger25-Feb-12 4:50 
Questionsplitterwnd in CMDIFrameWnd Pinmemberwuman21-Oct-08 18:53 
Generalexcellent ! PinmemberRudyRen18-Oct-08 18:17 
QuestionHow to show 3 different views in 3 subpanels in right panel by using splitterwnd? Pinmembersrikadi29-Sep-08 17:38 
GeneralCSpitterWnd with Tabs Pinmembergodspeed1238-Jul-08 12:42 
QuestionHow can I use this class in .net 2003? Pinmemberxiaod_l17-May-07 2:45 
Hi,all
I am a beginner,I want to use this class in .net 2003.When I use it in .net 2002,the project can be compiled but couldn't run. Could you give me any advice?
 
Thanks
GeneralGreat Job Pinmemberkishine1o1-Feb-07 16:42 
QuestionList View Gone Mad????? PinmemberregisterTHIS9-Oct-06 13:49 
AnswerRe: List View Gone Mad????? Pinmembermurray w10-Feb-07 16:33 
GeneralRegarding CSplitter/Multiple Views in SDI PinmemberBhushan198013-Jul-06 23:18 
Questionhow to register database in windowsxp platform Pinmemberli zhiyuan22-Jun-06 20:59 
GeneralWarning Level 4 and Crashes Pinmemberdhawan_boss7-Apr-06 18:09 
GeneralUpdate View Pinmemberhever30-Jan-06 6:05 
GeneralRe: Update View Pinmemberhever31-Jan-06 7:40 
AnswerRe: Update View Pinmemberhever31-Jan-06 10:45 
AnswerRe: Update View PinmemberJol7-Sep-06 21:47 
GeneralRe: Update View Pinmembercnsyr13-Apr-06 0:00 
GeneralDefault active pane Pinmemberornatale10-Jan-06 5:01 
QuestionRegistry Entries Pinmemberozantopoglu2-Jan-06 23:40 
Questionhow could u split a 3X3 view, it is a 3 column and 3 row view. Pinmemberskygg14-Nov-05 20:35 
Questionproblems with ST_SplitterWnd and CFrameWnd Pinmember#93709-Nov-05 10:13 
GeneralDoesn't Work PinmemberDave22n2-Nov-05 7:23 
AnswerI thought so too... PinmemberBoeroBoy27-Feb-06 11:43 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140916.1 | Last Updated 3 Sep 2001
Article Copyright 2001 by Daniel Zuppinger
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid