MFC窗体视口分割及消息响应
一、 窗体视口分割方法:
1、 在此处讲述的是对视口进行的静态分割。 2、 分割详解:
在MFC中要分割窗体视口,就需要用到CSplitterWnd类,但是有时候为了能够对 割实现更多的控制,就需要通过继承CSplitterWnd类来实现.这里讲述的控制是固定分割条,下面简述一下其操作过程.
在创建了一个单文档的工程后,先添加类CSplitterWndEx,其基类为CSplitterWnd,在MainFrame引用了头文件后就添加一个CSplitterWndEX的成员变量: CSplitterWndEx m_wndSplitter; 和
bool isInit //用于判断窗体视口是否分割,其初始化在MainFrame的构造函数中,初始值为false
然后在MainFrame的客户区创建事件的处理函数中添加分割的代码:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) {
// TODO: Add your specialized code here and/or call the base class if(!m_wndSplitter.CreateStatic(this,1,2)) //将窗体视口口分为一行二列 return FALSE;
CRect rc;
GetClientRect(&rc); //获取窗体视口的大小
//用框架生成的视口实体化分割出来的视口的一行一列的位置 //重点注意 :在MainFrm.cpp中要加上#include "SplitWndView.h"
//而且在 SplitWndView.h中要添加 #include "SplitWndDoc.h"
if(!m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(CSplitWndView),CSize(rc.Width()/2,rc.Height()),pContext)) return FALSE;
//CView1是自定义类,其基类为CView或者CScrollView,如果是CScrollView,视 //口可以生成滚动条,实体化分割出来的视口的一行二列的位置
if(!m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CView1),CSize(rc.Width()/2,rc.Height()),pContext)) return FALSE;
isInit=true; //窗体视口分割成功
return TRUE; }
二、
保证窗口大小改变分割条的相对位置不变
在MainFrame的客户区创建事件的处理函数中添加分割的代码以保证窗口大小改变时分割条的相对位置不变:
void CMainFrame::OnSize(UINT nType, int cx, int cy) {
CFrameWnd::OnSize(nType, cx, cy);
// TODO: Add your message handler code here CRect rc;
GetClientRect(&rc);
if(isInit&&nType!=SIZE_MINIMIZED) // 保持分割条在窗口中间 { m_wndSplitter.SetRowInfo(0,cy,0);
m_wndSplitter.SetColumnInfo(0,rc.Width()/2,50);
m_wndSplitter.SetColumnInfo(1,rc.Width()/2,50); m_wndSplitter.RecalcLayout(); //刷新层 } }
三、 固定分割条不让光标拖动
固定分割条不让光标移动它,这里需要在CSplitterWndEx类中屏蔽光 移动消息,代码如下:
void CSplitterWndEx::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default return //CSplitterWnd::OnMouseMove(nFlags, point); }
四、
不同视口对菜单项的消息响应
要解决这个问题,首先要理解MFC的命令传送机制是通过框架窗口的OnCmdMsg函数实现的,它将诸如菜单、工具栏等命令按以下顺序进行传送:
活动视图、文档、文档模板、框架窗口、应用程序对象,如果其中一级具有该命令的处理,则传送在此终止。
因为你的程序有两个视图,所以非活动视图将接收不到传送的命令,所以要自定义命令传送过程:
覆盖框架窗口的OnCmdMsg函数,先调用缺省的OnCmdMsg函数(即上面的传送过程),如果命令没有被处理(缺省的OnCmdMsg返回FALSE),则获取当前所有视图指针,并调用每个视图的OnCmdMsg函数,将命令消息传送给每个视图就可以了。
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) {
if ( CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo) ) return TRUE;
POSITION pos
CSplitWndDoc * pDoc = (CSplitWndDoc * ) GetActiveDocument (); if ( pDoc != NULL )
pos = pDoc->GetFirstViewPosition ();
while ( pos != NULL ) {
CView* pNextView = pDoc->GetNextView ( pos ); if ( pNextView != GetActiveView() )
{
if ( pNextView->OnCmdMsg ( nID, nCode, pExtra, pHandlerInfo ) ) return TRUE; } }
return FALSE; }