
Introduction
This brief article describes a simple way to add a toolbar inside one or more panes of a splitter window. Typically when you create a splitter window in the OnCreateClient method of your CMainFrame class, you supply CView derived classes to the CSplitterWnd::CreateView method. However, the class supplied does not need to be a CView derived class. It can be any CWnd derived class. If you look inside the MFC code for the CSplitterWnd class you will see that the class uses CWnd pointers not CView pointers. Methods in the CSplitterWnd class that deal with windows, use CWnd pointers. For instance, CSplitterWnd::GetPane returns a CWnd. This allows us to use a CFrameWnd derived class instead of a CView derived class. Since the CFrameWnd class provides all the toolbar / docking support, we can easily add a toolbar to each splitter pane that is derived from CFrameWnd. Below is the OnCreateClient code from my sample application:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
m_wndSplit.CreateStatic(this, 1, 2);
m_wndSplit.CreateView(0,0,pContext->m_pNewViewClass, CSize(175, 500),
pContext);
m_wndSplit.CreateView(0,1,RUNTIME_CLASS(CSplitFrame), CSize(175, 500),
pContext);
SetActiveView((CView *) m_wndSplit.GetPane(0,0));
RecalcLayout();
return TRUE;
}
Now, your CFrameWnd derived class must do two things. First it has to create your view class in the OnCreateClient method. My sample code uses a CFormView derived class:
BOOL CSplitFrame::OnCreateClient(LPCREATESTRUCT lpcs,
CCreateContext* pContext)
{
CSplitView *pview;
CCreateContext context;
pContext = &context;
pContext->m_pNewViewClass = RUNTIME_CLASS(CSplitView);
pview = (CSplitView *) CreateView(pContext, AFX_IDW_PANE_FIRST);
if (pview == NULL)
return FALSE;
pview->SendMessage(WM_INITIALUPDATE);
SetActiveView(pview, FALSE);
return TRUE;
}
The second thing your CFrameWnd derived class must do is create the toolbar that will appear in the splitter pane:
int CSplitFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT,
WS_CHILD | WS_VISIBLE | CBRS_TOP
| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; }
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar.SetBorders(3, 3, 3, 3);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
return 0;
}
That's it! Now you have a fully dockable toolbar for your splitter window pane. Easy!