关闭按钮和消息处理
当用户用鼠标单击Close按钮时,窗格容器向父窗口发送一个WM_COMMAND消息,命令的ID是ID_PANE_CLOSE。如果你在分隔窗口中使用了窗格容器,你需要响应整个消息,调用SetSinglePaneMode()隐藏这个窗格。(但是,不要忘了提供用户一个重新显示窗格的方法!)
CPaneContainer的消息链也用到了FORWARD_NOTIFICATIONS()宏,和CSplitterWindow一样,窗格容器在客户窗口和它的父窗口之间传递通知消息。在ClipSpy这个例子中,在list控件和主框架窗口之间隔了两个窗口(窗格容器和分隔窗口),但是FORWARD_NOTIFICATIONS()宏可以确保所有的通知消息被送到主框架窗口。 高级功能
在这一节,我将介绍一些如何使用WTL的高级界面特性。
嵌套的分隔窗口
如果你要编写一个email的客户端程序,你可能需要使用嵌套的分隔条,一个水平的和一个垂直的分隔条。使用WTL很容易做到这一点:创建一个分隔窗口作为另一个分隔窗口的子窗口。
为了演示这种效果,我将为ClipSpy添加一个水平分隔窗口。首先,添加一个名为m_wndHorzSplitter的CHorSplitterWindow类型的成员,像创建垂直分隔窗口m_wndVertSplitter那样创建这个水平分隔窗口,使水平分隔窗口m_wndHorzSplitter成为顶层窗口,将m_wndVertSplitter创建成m_wndHorzSplitter的子窗口。最后将m_hWndClient设置为m_wndHorzSplitter,因为现在水平分隔窗口占据整个主框架窗口的客户区。
LRESULT CMainFrame::OnCreate() { //... // Create the splitter windows. m_wndHorzSplit.Create ( *this, rcDefault, NULL,dwSplitStyle, dwSplitExStyle );
m_wndVertSplit.Create ( m_wndHorzSplit, rcDefault, NULL,dwSplitStyle, dwSplitExStyle ); //... // Set the horizontal splitter as the client area window. m_hWndClient = m_wndHorzSplit;
// Set up the splitter panes m_wndPaneContainer.SetClient ( m_wndFormatList ); m_wndHorzSplit.SetSplitterPane ( SPLIT_PANE_TOP, m_wndVertSplit ); m_wndVertSplit.SetSplitterPanes ( m_wndPaneContainer, m_wndDataViewer ); //... } |
最终的结果是这个样子的:
在窗格中使用ActiveX控件
在分隔窗口的窗格中使用ActiveX控件与在对话框中使用ActiveX控件类似,使用CAxWindow类的方法在运行是创建控件,然后将这个CAxWindow指定给分隔窗口的窗格。下面演示了如何在水平分隔窗口下面的窗格中使用浏览器控件:
// Create the bottom pane (browser) CAxWindow wndIE; const DWORD dwIEStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_HSCROLL | WS_VSCROLL;
wndIE.Create ( m_wndHorzSplit, rcDefault, _T("http://www.codeproject.com"), dwIEStyle );
// Set the horizontal splitter as the client area window. m_hWndClient = m_wndHorzSplit;
// Set up the splitter panes m_wndPaneContainer.SetClient ( m_wndFormatList ); m_wndHorzSplit.SetSplitterPanes ( m_wndVertSplit, wndIE ); m_wndVertSplit.SetSplitterPanes ( m_wndPaneContainer, m_wndDataViewer ); |
特殊绘制
如果你想改变分隔条的外观,例如在上面使用一些材质,你可以从CSplitterWindowImpl派生新类并重载DrawSplitterBar()函数。如果你只是想调整一下分隔条的外观,可以复制CSplitterWindowImpl类的函数,然后稍做修改。下面的例子就在分隔条中使用了斜交叉线图案。
template <bool t_bVertical = true> class CMySplitterWindowT : public CSplitterWindowImpl<CMySplitterWindowT<t_bVertical>, t_bVertical> { public: DECLARE_WND_CLASS_EX(_T("My_SplitterWindow"), CS_DBLCLKS, COLOR_WINDOW)
// Overrideables void DrawSplitterBar(CDCHandle dc) { RECT rect;
if ( m_br.IsNull() ) m_br.CreateHatchBrush ( HS_DIAGCROSS,t_bVertical RGB(255,0,0) : RGB(0,0,255) );
if ( GetSplitterBarRect ( &rect ) ) { dc.FillRect ( &rect, m_br );
// draw 3D edge if needed if ( (GetExStyle() & WS_EX_CLIENTEDGE) != 0) dc.DrawEdge(&rect, EDGE_RAISED,t_bVertical (BF_LEFT | BF_RIGHT) : (BF_TOP | BF_BOTTOM)); } }
protected: CBrush m_br; };
typedef CMySplitterWindowT<true> CMySplitterWindow; typedef CMySplitterWindowT<false> CMyHorSplitterWindow; |
这就是结果(将分隔条变宽是为了更容易看到效果):
|