Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / MFC

Splitter Window Tutorial

Rate me:
Please Sign up or sign in to vote.
4.43/5 (78 votes)
13 Jan 20034 min read 346.7K   12.4K   89   60
Implementing CSplitterWnd controls in MFC SDI applications

Sample Image - SplitterWindowTutorial.gif

Introduction

This article was written to cover the basics of using the default MFC CSplitterWnd objects. I looked for a long time for a basic introduction to using the objects but could only find subclasses or otherwise adapted CSplitterWnd tutorials. I hope this article helps those who, like me, just want a basic introduction to the basic object.

Background

A CSplitterWnd or splitter window is a way to split the screen into two or more different panes (see screenshot or applications such as 3D editors). A pane itself is usually filled with a CView or CWnd derived object to provide different views of a document (or user interface functionality).

Splitter windows come in two forms - static and dynamic. This tutorial will only cover static splitters since the dynamic ones are slightly more complex. The main difference between the two is that a dynamic splitter can be split and collapsed by the user while a static splitter cannot.

Using the Code

Step 1 - Declare the Data

Use AppWizard to create a new single document application with document/view support. Add a CSplitterWnd object to your Main Frame header file and a boolean flag for splitter management.

C++
CSplitterWnd m_mainSplitter;
BOOL m_bInitSplitter;

m_mainSplitter will be used to split the window into two panes like the screenshot above. The boolean flag will be used for checking that the splitter has been setup before managing resizing. Ensure that in the constructor of your Main Frame class, you initialize the boolean value to FALSE.

Step 2 - Create the Splitter

A splitter window should be created during the initialization of the client area of the main frame window. Add a function for the OnCreateClient message in your Main Frame class and insert splitter creation code as follows:

C++
//calculate client size 
CRect cr; 
GetClientRect( &cr);

if ( !m_mainSplitter.CreateStatic( this, 1, 2 ) ) 
{ 
    MessageBox( "Error setting up splitter frames!", 
                  "Init Error!", MB_OK | MB_ICONERROR ); 
    return FALSE; 
}

The parameters to CreateStatic() are the parent window (this) and the number or rows and columns. The client rectangle size is obtained to help with sizing later on.

Step 3 - Create the Views

Each pane in the splitter, unless it has a splitter nested inside, must have a view attached to it before it can be displayed. After the CreateStatic call, use the following code to create a default view for the pane. Notice that each column in the splitter must have a view created since it doesn't have a nested splitter inside. This caused me a lot of problems (understanding the requirements on views), so take some time to look at various code samples to gain a deeper understanding. The boolean flag is then updated to TRUE to indicate that the splitters have been created.

C++
if ( !m_mainSplitter.CreateView( 0, 0, 
       RUNTIME_CLASS(CSplitterWindowTutorialView), 
       CSize(cr.Width()/2, cr.Height()), pContext ) ) 
{ 
    MessageBox( "Error setting up splitter frames!", 
                "Init Error!", MB_OK | MB_ICONERROR );
    return FALSE; 
}

if ( !m_mainSplitter.CreateView( 0, 1, 
        RUNTIME_CLASS(CSplitterWindowTutorialView), 
        CSize(cr.Width()/2, cr.Height()), pContext ) ) 
{ 
    MessageBox( "Error setting up splitter frames!", 
        "Init Error!", MB_OK | MB_ICONERROR );
    return FALSE; 
}

m_bInitSplitter = TRUE;

To use RUNTIME_CLASS(CSplitterWindowTutorialView), you must include your view class header file in MainFrm.cpp and include your document class in your view class header just before:

C++
#endif // _MSC_VER > 1000.

This will allow you to use your view class in the Main Frame class. Lots of problems occur if you do not include your document class in the view class header though - another thing to watch out for!

Step 4 - Replace the Return Value

Replace:

C++
return CFrameWnd::OnCreateClient(lpcs, pContext);

with:

C++
return TRUE;

The default return value from the existing code will not show our work since it returns the default method to the frame window.

Step 5 - Manage Resizing

SetRowInfo and SetColumnInfo are responsible for managing the size of the splitters. Add a handler for the WM_ONSIZE message and add the following code:

C++
void CMainFrame::OnSize(UINT nType, int cx, int cy) 
{
    CFrameWnd::OnSize(nType, cx, cy);
    CRect cr;
    GetWindowRect(&cr);

    if (  m_bInitSplitter && nType != SIZE_MINIMIZED )
    {
        m_mainSplitter.SetRowInfo( 0, cy, 0 );
        m_mainSplitter.SetColumnInfo( 0, cr.Width() / 2, 50);
        m_mainSplitter.SetColumnInfo( 1, cr.Width() / 2, 50);

        m_mainSplitter.RecalcLayout();
    }
}

In the above code, we first check that the splitters have been initialized by checking the boolean value. This check is required since I think a WM_SIZE message is passed to the frame before the create method is ran - therefore, the object won't exist the first time this code runs and would crash if you didn't check for its existence.

The application should now run and provide something resembling the screenshot at the start of the article! I will probably add a second article in this series to add further nested splitters and other views based on forms! Stay tuned...

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.


Written By
Web Developer
United Kingdom United Kingdom
I am a software developer in the United Kingdom with 4 years experience programming in various languages including C++ and Java. I have an interested in coding theory, graphics programming, computer games, software security and cryptography.

Comments and Discussions

 
QuestionRc Resource Pin
Steven Wongsun10-Jul-13 22:09
Steven Wongsun10-Jul-13 22:09 
AnswerRe: Rc Resource Pin
Member 912584711-Oct-17 8:21
Member 912584711-Oct-17 8:21 
GeneralNew Message Format Pin
Member 1005455628-May-13 5:23
Member 1005455628-May-13 5:23 
GeneralMy vote of 4 Pin
iampradeepsharma4-Feb-13 18:39
iampradeepsharma4-Feb-13 18:39 
GeneralMy vote of 5 Pin
Jon3456021-Oct-12 12:27
Jon3456021-Oct-12 12:27 
QuestionSeriously How Stupid Pin
xox_c0bra_xox22-Jun-12 16:14
xox_c0bra_xox22-Jun-12 16:14 
AnswerRe: Seriously How Stupid Pin
Member 912584711-Oct-17 8:23
Member 912584711-Oct-17 8:23 
GeneralMy vote of 4 Pin
Dai Yan26-Apr-11 17:18
Dai Yan26-Apr-11 17:18 
GeneralSplitter window Pin
cj_aviraj8-Jan-08 23:39
cj_aviraj8-Jan-08 23:39 
GeneralRe: Splitter window Pin
DCP2-Mar-08 23:00
DCP2-Mar-08 23:00 
GeneralRe: Splitter window Pin
ollydbg2331-Jul-08 20:57
ollydbg2331-Jul-08 20:57 
GeneralRe: Splitter window Pin
angel42013-Oct-08 9:26
angel42013-Oct-08 9:26 
GeneralRe: Splitter window Pin
angel42013-Oct-08 11:54
angel42013-Oct-08 11:54 
Generalnested splitters Pin
saggy216-May-07 20:13
saggy216-May-07 20:13 
GeneralMissing Resource files... Pin
SatheeshCodeMFC22-Nov-06 18:08
SatheeshCodeMFC22-Nov-06 18:08 
GeneralSome issues, but fundamentally ok Pin
GrabBot9-Oct-06 7:47
GrabBot9-Oct-06 7:47 
GeneralBlinking when resizing Pin
nomind21-Aug-06 1:22
nomind21-Aug-06 1:22 
GeneralMissing res subdirectory Pin
Hans Dietrich5-Jul-06 22:06
mentorHans Dietrich5-Jul-06 22:06 
GeneralRe: Missing res subdirectory Pin
GrabBot9-Oct-06 7:44
GrabBot9-Oct-06 7:44 
Generalmissing rc2 file Pin
ehsan_kh5-Jul-06 21:36
ehsan_kh5-Jul-06 21:36 
Generalsubdirectories Pin
ruede10-Mar-06 4:38
ruede10-Mar-06 4:38 
QuestionHow CFormView SDI create splitter?is it possible Pin
emilie560220-Oct-05 22:37
emilie560220-Oct-05 22:37 
AnswerRe: How CFormView SDI create splitter?is it possible Pin
kencocomputers26-Aug-06 12:13
kencocomputers26-Aug-06 12:13 
Questionhow to imlement in MDI Pin
vikas amin23-Aug-05 2:04
vikas amin23-Aug-05 2:04 
Generalvery helpful! Pin
Tabris_55511-Apr-05 18:50
Tabris_55511-Apr-05 18:50 

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

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