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!