Have you ever wanted to use a split window in you program but didn't want all
extra garbage of the Doc/View architecture?
In the new project wizard in order to make the 'Split Window' check box
available you have to choose the 'Document/View architecture support'. This puts
a lot of extra unneeded code in your project if all you wanted was a split main
window.
In this article I am going to walk you through creating a simple SDI with a
split main window, a tool bar, and status bar. The window will be split into a
left and right pane that are resource based and can be modified easily in the
resource editor just like making a simple dialog based application.
These instructions and project files are for Visual Studio 2005; while they may
work in older versions of Visual Studio you'll be on your own to adapt them.
Start Visual Studio and create a new project. Select MFC application, give your
project a name and click 'OK'.


Click next.

In order to keep this as simple as possible we will use minimal options for our
project.
Choose 'Single document', uncheck 'Document/View architecture', uncheck 'use
Unicode libraries' and select 'Use MFC in static library'. Click next.

We don't want any database support so just click next.

On this page we will keep the defaults. This will give use a status bar and a
tool bar. Nice things to have in an SDI project. Hit next.

Uncheck 'ActiveX controls' and 'Common Control Manifest' unless you know you are
going to be using ActiveX controls and the new XP specific controls in your
project there is no reason for the extra overhead. Hit next.

Here is where it would be nice if they let us choose what kind of child view we
want but they don't so just hit finish.
Compile and run the project.

Notice that the icon on the title bar is set to a default icon instead of the
one defined in the projects resource file. This is a bug in Visual studio that's
been around for years. Here's how to fix it.

In the IDE select the class view and double click on 'InitInstance'.

You should see.

To change the icon on the title bar first we need to create one then we need to
tell the main application window to use it. Place the following code after the
UpdateWindow but before the return.
//Create and load the titlebar icon
HICON hIcon;
hIcon = LoadIcon(IDR_MAINFRAME);
AfxGetMainWnd()->SendMessage(WM_SETICON,TRUE,(LPARAM)hIcon);
Contrary to what you might think 'LoadIcon' doesn't actually load the icon, it
just creates it. We have to tell the application to use the new icon with a
SendMessage.
Your 'InitInstance' should now look like this.

Now when you compile and run you should see the resource defined icon on the
title bar.
You can now use the resource editor change the icon to want ever you want.
Now its time to add the split window I promised. In order to have a split window
we will use a class called 'CSplitterWnd'.
In the class view right click on CMainFrame and select 'Add Variable'. Change
the access to 'Protected', the variable type to 'CSplitterWnd' and the variable
name to 'm_wndSplitter' and click 'Finish'.

Since the split will be in the client area the code for it will need to be in an
override function called 'OnCreateClient' in the 'CMainFrame'.
In the class view select 'CMainFrame'. In the properties area press the
'Overrides' button and scroll down to 'OnCreateClient' and add the function with
the combo box to the right'

Add the following code to the 'OnCreateClient' function.
// create splitter window
if (!m_wndSplitter.CreateStatic(this, 1, 2))
return FALSE;
This will create a static split window for us that will have one row and two
columns.
But wait don't compile yet. We still need to tell the splitter what to display
in each pane and we need to get rid of the old view Visual Studio created for
us.
For this tutorial let use resource based forms. That will make it easy to add
controls and use this project as a template for building other applications.
Switch to resource view, expand the dialog leaf, right click and choose 'Insert
Dialog'. This will insert a new dialog resource and open it in the resource
editor.

Delete the 'OK' and the 'Cancel' buttons. Right click on the dialog and choose
properties.
In properties change:
Border to 'None'.
Control to 'True'.
ID to 'IDD_FORM_LEFT'.
Style to 'Child'.

Now add a new dialog in the same manner but make the ID: IDD_FORM_RIGHT
In the resource view double click IDD_FORM_LEFT. This will open up the left form
in the resource editor. Right click on the dialog in the editor and choose 'add
class'.
Change the base class to 'CFormView', the name to 'CFormLeft' and hit finish.

Repeat this process on the IDD_FORM_RIGHT resource but make the class name
'CFormRight'.

Now we have views for the splitter to display.
Add the of MainFrm.cpp and the header lines:
#include "FormLeft.h"
#include "FormRight.h"
Scroll
down to the 'OnCreateClient' function and add the create view calls to the
splitter. Add the following code after the splitter create but before the
return.
if (!m_wndSplitter.CreateView(0, 0, RUNTIME_CLASS(CFormLeft), CSize(125, 100), pContext) ||
!m_wndSplitter.CreateView(0, 1, RUNTIME_CLASS(CFormRight), CSize(100, 100), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
}
Your
OnCreateClient should look like this.

We're almost there. Now we need to get rid of the view Visual Studio made for us
and any uses of the old view.
Scroll up to the OnCmdMsg function and remove:
if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
return TRUE;
Scroll up to the OnSetFocus function ad remove:
m_wndView.SetFocus();
Scroll up to the OnCreate function and remove:
// create a view to occupy the client area of the frame
if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("Failed to create view window\n");
return -1;
}
At the top of MainFrm.h remove:
#include "ChildView.h"
Scroll down and remove:
CChildView m_wndView;
Switch to the solution explorer, right click on 'ChildView.h' and choose remove.
On the pop up box press the delete button.

Delete 'ChildView.cpp' in the same manner.

You can compile and run now and you will have an SDI with a split window. Try it
out, drag the split bar around,

It doesn't do anything at this point but you can add controls with the resource
editor.
However, the controls in each pane can only affect controls in the same pane. In
order to have controls in the left pane affect controls in the right pane we
will need to reroute some messages.
In the class view, right click on 'CformLeft' and choose 'add variable'. Make
the access protected, the type 'CWnd*' and the name 'm_target'. Hit finish.

In the class view, right click on 'CFormLeft' and choose 'add function'. Make
the return type void, the name 'SetTarget' and add a parameter of type 'CWnd*'
named 'm_cwnd'. Hit finish.

In the SetTarget function add the code:
m_target = m_cwnd;
You should see:

Next we will need to override the OnCommand function. Select 'CFormLeft' in the
class view. Click the overrides button and scroll down to OnCommand and use the
dropdown box to add the function.

In the OnCommand function add the following code:
if(m_target)
{
m_target->SendMessage(WM_COMMAND, wParam, lParam);
}
else
{
CFormView::OnCommand(wParam, lParam);
}
return true;
You should see:

This will send the messages from this form to the target window we set. Now we
want to set the target to the form in the right pane.
Add the following code to the OnCreateClient function in CMainFrame after the
splitter creates views and before the return:
//set the target for mapped messages
((CFormLeft*)m_wndSplitter.GetPane(0,0))->SetTarget(m_wndSplitter.GetPane(0,1));
Your function should now look like:

Now lets add some controls and use it. Open IDD_FORM_RIGHT in the resource
editor and add a static text control.

Change the ID to IDC_STATIC_HELLO, the caption to 'Click the button' and the
text align to center.

Right click on the static control and choose add variable. Click the control
type check box, the type 'CStatic' and the name 'm_hello'. Click finish.

Open IDD_FORM_LEFT in the resource editor and add a button.

Change the ID to IDC_BUTTON_HELLO and the caption to 'Say Hello'.

Right click on the button and choose 'Add Event Handler'. Select message type
BN_CLICKED and 'CFormRight' from the class list, then hit add and edit.

In the OnBnClickedButtonHello function add the following code:
m_hello.SetWindowText("Hello Window Splitter!");
Your function should look like:

Compile and run your program. Click the Say Hello button and you should see the
test change in the right pane. Now try dragging the split bar and you should see
the text in the right pane move with the splitter bar.

I hope you found this article useful.