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

Simple Splitter with CWnd-derived Panes

Rate me:
Please Sign up or sign in to vote.
4.96/5 (37 votes)
18 Apr 20044 min read 222.5K   8.9K   64   50
A splitter window class, which combines the basic CSplitterWnd functionality and professional look with the ability to use CWnd-derived panes

Introduction

Yes, it's yet another splitter window class. So why I release a new class, when there are plenty of similar classes? The answer is simple. All splitter window classes at CodeProject can be IMHO divided into two parts:

  • These derived from original MFC CSplitterWnd. They look nice and give a lot of advantages to classical CSplitterWnd, but deriving from CSplitterWnd restrict you to use only CView-derived windows in it.
  • The others, which I can use in various windows - but when I compiled and tested them, they didn't look as pretty as the CSplitterWnd.

In this article, I offer a class, which is not derived from CSplitterWnd. It allows you to use simple CWnd-derived windows. But it's combined with professional looking of the original CSplitterWnd. Some routines I took from MFC source code. Please be forbearing while reading this article. It's my first article at CodeProject :).

Features

My goal in CSimpleSplitterWnd design was to simulate the basic features of CSplitterWnd. With this class, you can make several panes arranged either horizontally or vertically. It doesn't offer automatic splitting, shared scroll bars and intersection trackers. I didn't find it very useful - but if there are enough people, who did, I can add some of these features. :) The idea of CSimpleSplitter (compared to CSplitterWnd) is that pane windows are independent of each other, hence they are also responsible for their scrolling and borders.

Using the Code

The layout of splitter is set in constructor:

C++
CSimpleSplitter(int nPanes, UINT nOrientation = SSP_HORZ,   
 int nMinSize = 30, int nBarThickness = 3);

nPanes is number of the panes, nOrientation should be either SSP_HORZ or SSP_VERT. nMinSize is the minimal height (or width) of any pane - it is important in recalculating layout algorithm, when you resize the splitter. nBarThickness is height or width of bars between panes. All of these properties remain fixed during lifetime of the splitter instance. The creation of splitter and its panes is straightforward:

C++
BOOL Create(CWnd* pParent, UINT nID = AFX_IDW_PANE_FIRST);
BOOL CreatePane(int nIndex, CWnd* pPaneWnd, DWORD dwStyle,   
 DWORD dwExStyle, LPCTSTR lpszClassName = NULL);

Panes are indexed from 0 to nPanes - 1. The parameters dwStyle, dwExStyle and lpszClassName are passed to pPaneWnd->CreateEx() (If you want to bind a created window with a pane, use SetPane instead). You can specify for example the borders of panes there. In demo app, the "large" panes have a WS_EX_CLIENTEDGE extended style, while the three "flat" panes have WS_EX_STATICEDGE extended style. The splitter bar alone is only a gray rectangle, so if you don't specify any edge and set the gray background to pane windows, you can use the splitter in dialogs too.

The following five methods are analogous to CSplitterWnd methods, so they don't require a special documentation.

C++
int GetPaneCount() const;void SetPane(int nIndex, CWnd* pPaneWnd);
CWnd* GetPane(int nIndex) const;
virtual void SetActivePane(int nIndex);
CWnd* GetActivePane(int* pIndex) const;

However, setting the pane widths or heights uses different technique:

C++
void SetPaneSizes(const int* sizes);

You pass an array of nPanes integers. They specify relative sizes of panes. You can use any scale, the panes are resized proportionally to the sum of the array members. When you resize the whole splitter, the sizes of panes are changed proportionally to their actual sizes. If necessary, they're adjusted to m_nMinSize.

C++
void GetPaneRect(int nIndex, CRect& rcPane) const;
void GetBarRect(int nIndex, CRect& rcBar) const;

With these functions, you can retrieve the position of panes in splitter client coordinates. Bars are indexed from 1 to nPanes - 1.

And that's all. Look at the SimpleSplitterApp demo, especially the CMainFrame::OnCreate code, you will know everything!

Points of Interest

When I programmed the splitter, I was confused, how the framework redraws resized window. If you resize the top or left border, the framework first only move the window content in corresponding direction, and then it calls OnPaint(). So the window was redrawn twice and in the splitter this looked ugly.

Fortunately, there is a message handler CWnd::OnWindowPosChanging. You can avoid the initial moving of content, if you see SWP_NOCOPYBITS as you see in CSimpleSplitter and CChildWnd code. I think that this is useful in many other cases that splitters.

History

  • 11. 2. 2004 - First version released
  • 24. 3. 2004 - Some bugs fixed (see the messages below). In the SetPaneSizes function, now you should pass only relative sizes, not absolute.

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
Czech Republic Czech Republic
Nowadays, I'm studying Econometrics and Software Systems at Charles University in Prague. Parallel to it, I work as a Windows developer in a railway interlocking company.
I consider myself as a C++ fundamentalist, simply because I haven't ever found any better language. If you know about any, please drop me a mail (and we can dispute about it Smile | :) )
Some friends say that I'm workoholic and I answer, yes, of course and what is wrong?
You can visit my homepage, but it's completely in Czech Smile | :)

Comments and Discussions

 
Praisestill works Pin
Southmountain10-Jul-21 15:16
Southmountain10-Jul-21 15:16 
QuestionWill Not Work with Static Windows Pin
zdanman29-Dec-19 12:20
zdanman29-Dec-19 12:20 
QuestionLicensing Pin
Member 1130795118-Jul-18 3:51
Member 1130795118-Jul-18 3:51 
Questioncause intel graphics driver crash in Windows10 Pin
Jason.LYJ26-Mar-16 18:28
professionalJason.LYJ26-Mar-16 18:28 
GeneralMy vote of 5 Pin
JunfengGuo14-Jul-15 14:51
JunfengGuo14-Jul-15 14:51 
GeneralRe: My vote of 5 Pin
JunfengGuo14-Jul-15 15:22
JunfengGuo14-Jul-15 15:22 
GeneralRe: My vote of 5 Pin
JunfengGuo14-Jul-15 15:52
JunfengGuo14-Jul-15 15:52 
QuestionThanks Pin
Jonnie White1-Jun-15 0:04
Jonnie White1-Jun-15 0:04 
GeneralMy vote of 5 Pin
Jonnie White1-Jun-15 0:03
Jonnie White1-Jun-15 0:03 
QuestionHow would I install a dialog bar within a given SimpleSplitter pane? Pin
Michael B Pliam23-Oct-12 12:13
Michael B Pliam23-Oct-12 12:13 
QuestionOnly 3 stars for me Pin
llothar29-Jan-12 16:03
llothar29-Jan-12 16:03 
QuestionMDI Child window with CFormView panes are not re-sized Pin
Shashidhar Kamath8-Dec-11 11:16
Shashidhar Kamath8-Dec-11 11:16 
QuestionHow to add CDialog based object as one of the pane Pin
Shashidhar Kamath7-Dec-11 9:46
Shashidhar Kamath7-Dec-11 9:46 
Questionhow to use the simple splitter with CWnd-derived panes Pin
errieman13-Jul-11 21:22
errieman13-Jul-11 21:22 
GeneralGetBarRect fix Pin
ChrisJohnShort19-Dec-06 12:25
ChrisJohnShort19-Dec-06 12:25 
GeneralCListView Pin
Devil for ever5-Jun-06 10:17
Devil for ever5-Jun-06 10:17 
QuestionDoKeyboardSplit() Pin
Ortwin Basselmann2-Mar-06 22:29
Ortwin Basselmann2-Mar-06 22:29 
QuestionHow to create a splitter inside CWnd derived class object? Pin
Paul, Snehasish2-Feb-06 20:06
Paul, Snehasish2-Feb-06 20:06 
GeneralSetting pane with arbitray parent Pin
Diarrhio26-Jul-05 20:18
Diarrhio26-Jul-05 20:18 
GeneralAdding Dialog Controls directly Pin
geekahedron22-Apr-05 11:02
geekahedron22-Apr-05 11:02 
GeneralRe: Adding Dialog Controls directly Pin
Robert A. T. Káldy11-May-05 6:04
Robert A. T. Káldy11-May-05 6:04 
GeneralRe: Adding Dialog Controls directly [modified] Pin
Member 458205418-Apr-08 5:16
Member 458205418-Apr-08 5:16 
GeneralResizing when parent resizes Pin
Andrew Phillips27-Jan-05 19:54
Andrew Phillips27-Jan-05 19:54 
GeneralNeed help with splitter Pin
New Student21-Oct-04 13:53
New Student21-Oct-04 13:53 
GeneralRe: Need help with splitter Pin
Robert A. T. Káldy24-Oct-04 10:15
Robert A. T. Káldy24-Oct-04 10:15 

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.