所谓静态分割窗口,就是窗口在程序生存期其窗口的分割状态保持不变,而动态就是相对静态而言的,简单地说动态就像SQL Server2K的查询分析器那样,右边的窗口可以动态地分割成sql编辑环境和消息结果显示环境.
在MFC中要分割窗口,就需要用到CSplitterWnd类,但是有时候为了能够对分割实现更多的控制,就需要通过继承CSplitterWnd类来实现.下面简述一下其操作过程.
在创建了一个单文档的工程后,先添加类CSplitterWndEx,其基类为CSplitterWnd,在MainFrame引用了头文件后就添加一个CSplitterWndEX的成员变量:
CSplitterWndEx m_wndSplitter;
然后在MainFrame的客户区创建事件的处理函数中添加分割的代码:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { // TODO: 在此添加专用代码和/或调用基类 CRect rect; GetClientRect(rect);
if (!m_wndSplitter.CreateStatic(this,1,2)) { return FALSE; }
if (!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CLeftPaneView),CSize(rect.Width()/4,100),pContext)) { return FALSE; }
if (!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMainInterface),CSize(100,100),pContext)) { return FALSE; }
return TRUE;
//return CFrameWnd::OnCreateClient(lpcs, pContext); }
m_wndSplitter.CreateStatic(this,1,2)中的CreateStatic函数是用来静态拆分视图窗口,拆分成1行2列的情况,左边一般为操作的导航栏,而右边作为模块显示.
m_wndSplitter.CreateView (0,0,RUNTIME_CLASS(CLeftPaneView),CSize(rect.Width()/4,100),pContext)是用来 创建拆分后每一个Pane的视图的.前两个参数为Pane的位置索引,(0,0)就是指首行首列的位置;RUNTIME_CLASS是用动态创建类对象, 也就是要在Pane显示的视图(函数中的CLeftPaneView);后面的CSzie是创建的宽度和高度的值.
上面的操作就基本上完成了静态分割视图窗口的创建.
创建好静态的拆分视图窗口后,就可能需要通过在左边的区域来实施右边区域的视图切换,来显示不同的操作界面.
实现视图切换,需要在左区域的切换事件中添加处理函数,来调用在MainFrame中的切换函数.在MainFrame中的视图切换函数如下:
void CMainFrame::SwitchToView(int nViewType) { //视图切换,获取分割区域,按行,列索引作为参数 CView* pView=(CView*)m_wndSplitter.GetPane(0,1); //获取分割后右边的视图对象 CRect rcRight,rcFrame; pView->GetClientRect(&rcRight); GetClientRect(&rcFrame);
switch(nViewType) //判断视图切换,case中的比较参数是预先定义的宏 { case MAININTERFACE: { if (!pView->IsKindOf(RUNTIME_CLASS(CMainInterface))) //判断分割的视图类 { m_wndSplitter.DeleteView(0,1); //删除原Pane中的视图 m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMainInterface),CSize(rcRight.Width(),rcRight.Height()),NULL); //创建新视图 m_wndSplitter.RecalcLayout(); //在调整后重新显示分割窗口 } } break; case CUSTOMERMGT: { if (!pView->IsKindOf(RUNTIME_CLASS(CCustomerMgt))) { m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CCustomerMgt),CSize(rcRight.Width(),rcRight.Height()),NULL); m_wndSplitter.RecalcLayout(); } } break; default: break; } }
就是通过删除原视图,创建新视图,重新显示这三个操作再加简单的逻辑分支判断就实现了视图的切换.
当实现了基本的视图切换后,一个静态视图分割的过程就算是基本完成.不过有时候可能出于界面布局和美工的各方面考虑,希望对分割窗口实现大小固定,限制 使用者拖动分割条来调整两个分割的视图大小.此时,可以在实现继承了的CSplitterWndEx类中添加LButtonDown(鼠标按下), MouseMove(鼠标移动),LButtonUp(鼠标恢复)这三个事件处理函数.通过自定义处理函数里面的内容,可以实现限制拖动的效果.在这三个 事件处理函数中都将其他的代码删掉,包括调用CSplitterWnd基类的相应函数,都统统删除,然后添加一句简单的return,取消了鼠标拖动的默 认效果,如下:
void CSplitterWndEx::OnLButtonDown(UINT nFlags, CPoint point) { //固定左右视图的大小,禁止了对分割条的点击 return; }
基本的静态视图创建,切换和固定就完成了.
以上的代码都在VC2005中成功通过.