分割窗口概述

分割窗口,顾名思义,就是将一个窗口分割成多个窗格,在每个窗格中都包含有视图,或者是同一类型的视图,或者是不同类型的视图。

MFC分割窗口的方式有两种,动态分割和静态分割。

动态分割窗口通常用于创建同一个文档对应的多个视图,而且这些视图一般都是同一类型的视图,能够在用户编辑文档的不同部分时提供方便。

大家看下Word里的动态分割窗口就很明白了,以Word 2007文档为例,在菜单中点击“视图”->“拆分”,就可以看到一条随鼠标移动的分隔条,当我们在文档中某个位置按下鼠标左键时,分割条就固定了下来,生成了上下两个分割窗格,通过滚动每个窗格中的垂直滚动条可以看到,两个窗格中的内容相同,这就是所说的对应同一个文档的同一类视图。

动态分割窗口最多可以有两行两列。

静态分割窗口比较常见。我们经常能看到某个软件打开后,界面窗口默认被分割成了几个窗格,这就是静态分割窗口。

静态分割窗口指在窗口创建时,分割的窗格就已经生成了,而且用户不能改变窗格的数量和顺序。静态分割窗口最多支持16行16列。通常静态分割窗口的每个窗格中包含不同类的视图,当然也可以是同一类的视图。

CSplitterWnd类

MFC中的分割窗口类-CSplitterWnd类提供了分割窗口的功能。CSplitterWnd类中包含一个分割器窗口,该分割器窗口就是一个包含多个窗格的窗口。我们分割窗口时就是直接在此分割器窗口中分割的。

下面是三个最常用的成员函数:

virtual BOOL Create(   
   CWnd* pParentWnd,   
   int nMaxRows,   
   int nMaxCols,   
   SIZE sizeMin,   
   CCreateContext* pContext,   
   DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT,   
   UINT nID = AFX_IDW_PANE_FIRST    
);  

创建动态分割窗口。参数pParentWnd为分割器窗口的父框架窗口;参数nMaxRows为分割器窗口的最大行数,不能超过2;参数nMaxCols为分割器窗口的最大列数,也不能超过2;参数sizeMin为窗格能显示的最小尺寸,如果窗格尺寸小于sizeMin则不显示;参数pContext为指向CCreateContext结构的指针,大多数情况下可以赋值为父框架窗口的pContext;参数dwStyle指定窗口风格;参数nID为分割窗口的ID,除非分割器窗口嵌入到另一个分割器窗口中,否则可以取值AFX_IDW_PANE_FIRST。

virtual BOOL CreateStatic(   
   CWnd* pParentWnd,   
   int nRows,   
   int nCols,   
   DWORD dwStyle = WS_CHILD | WS_VISIBLE,   
   UINT nID = AFX_IDW_PANE_FIRST    
);  

创建静态分割窗口。参数pParentWnd、dwStyle和nID同上;参数nRows为行数,不能超过16;参数nCols为列数,同样不能超过16。

virtual BOOL CreateView(   
   int row,   
   int col,   
   CRuntimeClass* pViewClass,   
   SIZE sizeInit,   
   CCreateContext* pContext    
);  

为静态分割窗口创建窗格视图。参数row指定分割器窗口中放置新视图的行;参数col指定放置新视图的列;参数pViewClass指定新视图的CRuntimeClass对象;参数sizeInit指定新视图的初始大小;参数pContext为指向CCreateContext结构的指针,通常可以赋值为传递给父框架窗口的重载函数CFrameWnd::OnCreateClient的pContext参数值。

动态分割窗口

创建动态分割窗口的一般步骤为:

1. 在父框架类中定义一个CSplitterWnd类型的成员对象。

2. 重载父框架类的CFrameWnd::OnCreateClient成员函数。

3. 在重载的CFrameWnd::OnCreateClient函数中调用CSplitterWnd成员对象的Create函数。

实例:我们要实现在主框架窗口的客户区中创建两行两列的动态分割窗口。

以下是创建动态分割窗口的具体步骤:

1. 在MainFrm.h文件中为CMainFrame类添加成员对象:CSplitterWnd m_wndSplitter;。

2. 在Class View类视图中找到CMainFrame类,右键点击,在右键菜单中选择Properties,就会显示属性页,然后在属性页的工具栏上点击Tip为Overrides的按钮,下面的列表中就列出了能够重载的函数,找到OnCreateClient生成重载函数。

3. 在MainFrm.cpp文件中找到刚重载的OnCreateClient函数修改如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
{   
 // TODO: Add your specialized code here and/or call the base class   
 // 创建动态分割窗口,两行两列   
 return m_wndSplitter.Create(this,, , CSize(, ), pContext);   
  
 //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
}  

4. 在Resource View资源视图中,打开Menu下的IDR_MAINFRAME菜单,在View下添加一个菜单项,Caption设为Splitter Window,ID设为(一定要设为)ID_WINDOW_SPLIT。这样在运行结果界面中点击此菜单项时MFC会执行一些操作显示动态分割窗口。

5. 运行程序,点击菜单中的View->Splitter Window菜单项,即可看到创建动态分割窗口后效果。

静态分割窗口

创建静态分割窗口的一般步骤为:

1. 在父框架类中定义一个CSplitterWnd类型的成员对象。

2. 重载父框架类的CFrameWnd::OnCreateClient成员函数。

3. 在重载的CFrameWnd::OnCreateClient函数中调用CSplitterWnd成员对象的CreateStatic成员函数,然后可以调用CSplitterWnd成员对象的CreateView成员函数为每个窗格创建视图。

实例:在主框架窗口中的客户区创建一个两行一列的静态分割窗口。

以下是创建静态分割窗口的具体步骤:

1. 在MainFrm.h文件中为CMainFrame类添加成员对象:CSplitterWnd m_wndSplitter;。

2. 在Class View类视图中找到CMainFrame类,右键点击,在右键菜单中选择Properties,就会显示属性页,然后在属性页的工具栏上点击Tip为Overrides的按钮,下面的列表中就列出了能够重载的函数,找到OnCreateClient生成重载函数。

3. 在MainFrm.cpp文件中找到刚重载的OnCreateClient函数进行修改。若没有新建其他视图类,则上下两个窗格的视图可以都用CExampleView。为了能识别CExampleView类,还需在MainFrm.cpp文件中添加#include "ExampleView.h",在ExampleView.h文件中添加#include "ExampleDoc.h"。最终OnCreateClient函数修改如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)   
{   
    // TODO: Add your specialized code here and/or call the base class   
    CRect rc;   
  
    // 获取框架窗口客户区的CRect对象   
    GetClientRect(&rc);   
  
    // 创建静态分割窗口,两行一列   
    if (!m_wndSplitter.CreateStatic(this, , ))   
        return FALSE;   
  
    // 创建上面窗格中的视图   
    if (!m_wndSplitter.CreateView(, , RUNTIME_CLASS(CExampleView), CSize(rc.Width(), rc.Height()/), pContext))   
        return FALSE;   
  
    // 创建下面窗格中的视图   
    if (!m_wndSplitter.CreateView(, , RUNTIME_CLASS(CExampleView), CSize(rc.Width(), rc.Height()/), pContext))   
        return FALSE;   
  
    return TRUE;   
  
    //return CFrameWndEx::OnCreateClient(lpcs, pContext);   
}  

4. 运行程序,即可看到效果。

若想在其中某个窗格中再嵌套分割窗口,那么就需要再定义一个CSplitterWnd对象,以父窗格所在的CSplitterWnd对象为父框架窗口创建分割窗口即可。

实例:创建一个具有左上,左下和右边这三个视图的静态分割窗口。

以下是创建静态分割窗口的具体步骤:

1. 在MainFrm.h文件中为CMainFrame类添加成员对象:

protected:
                                    CSplitterWnd m_wndSplitter;
                                    CSplitterWnd m_wndSplitter1;

2. 在Class View类视图中找到CMainFrame类,右键点击,在右键菜单中选择Properties,就会显示属性页,然后在属性页的工具栏上点击Tip为Overrides的按钮,下面的列表中就列出了能够重载的函数,找到OnCreateClient生成重载函数。

3. 在MainFrm.cpp文件中找到刚重载的OnCreateClient函数进行修改。这里可以先建好三个视图类:CMessageView,CInputView,CUserView。

最终OnCreateClient函数修改如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// create splitter window
if (!m_wndSplitter.CreateStatic(this, , ))
return FALSE; if (!m_wndSplitter1.CreateStatic(
&m_wndSplitter, // our parent window is the first splitter
, , // the new splitter is 2 rows, 1 column
WS_CHILD | WS_VISIBLE | WS_BORDER, // style, WS_BORDER is needed
m_wndSplitter.IdFromRowCol(, )
// new splitter is in the first row, 2nd column of first splitter
))
{
TRACE0("Failed to create nested splitter\n");
return FALSE;
} if(!m_wndSplitter1.CreateView(,, RUNTIME_CLASS(CMessageView), CSize(,), pContext))
{
m_wndSplitter.DestroyWindow();
m_wndSplitter1.DestroyWindow();
return FALSE;
} if(!m_wndSplitter1.CreateView(,, RUNTIME_CLASS(CInputView), CSize(,), pContext))
{
m_wndSplitter.DestroyWindow();
m_wndSplitter1.DestroyWindow();
return FALSE;
} if(!m_wndSplitter.CreateView(, , RUNTIME_CLASS(CUserView), CSize(, ), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
} m_wndSplitter.SetColumnInfo(, ,);
m_wndSplitter1.SetRowInfo(, , );
return TRUE;
}

4. 运行程序,即可看到效果如下:

若想创建具有左边,右上和右下这三个视图的静态分割窗口,即可修改OnCreateClient函数如下:

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: 在此添加专用代码和/或调用基类
CRect rc;
// 获取框架窗口客户区的CRect对象
GetClientRect(&rc); //创建拆分窗口,分割为两列
if (!m_wndSplitter.CreateStatic(this, , ))
return FALSE;
//把窗口第2列再分割为两行
if (!m_wndSplitterRight.CreateStatic(&m_wndSplitter, , ,WS_CHILD | WS_VISIBLE | WS_BORDER, m_wndSplitter.IdFromRowCol(,)))
return FALSE; //创建视图
if(!m_wndSplitter.CreateView(, , RUNTIME_CLASS(CUserView), CSize(rc.Width()/ , rc.Height()), pContext))
{
m_wndSplitter.DestroyWindow();
return FALSE;
} if(!m_wndSplitterRight.CreateView(,, RUNTIME_CLASS(CMessageView), CSize(rc.Width()*/, rc.Height()*/), pContext))
{
m_wndSplitter.DestroyWindow();
m_wndSplitterRight.DestroyWindow();
return FALSE;
} if(!m_wndSplitterRight.CreateView(,, RUNTIME_CLASS(CInputView), CSize(rc.Width()*/, rc.Height()/), pContext))
{
m_wndSplitter.DestroyWindow();
m_wndSplitterRight.DestroyWindow();
return FALSE;
} return TRUE;
}

最后一个左边,右上和右下三视图的实例花了不少功夫,一直报错,结果是 m_wndSplitterRight.CreateView(0,0,......) 这里的 0,0 没搞清楚。

整理于此,希望能给遇到同样问题的朋友一些帮助~~~~~

VS2010 MFC中 窗口分割的实现的更多相关文章

  1. VS2010 MFC中制作Visual Studio风格的停靠侧栏窗口(CDockablePane里嵌套FormView表单视图)

    VS2010 MFC中制作Visual Studio风格的停靠侧栏窗口(CDockablePane里嵌套FormView表单视图) 1. 在资源窗口里新建一个FormView的Dialog,修改ID为 ...

  2. 【MFC】MFC中窗口重绘

    MFC中窗口重绘 摘自:http://blog.csdn.net/shuilan0066/article/details/5859057 在刷新窗口时经常要调用重绘函数 MFC提供了三个函数用于窗口重 ...

  3. MFC中窗口启动后,CEdit编辑框默认光标位置设置,顺序的调节方法

    MFC中窗口启动后,CEdit编辑框默认光标位设置,顺序的调节方法 在编辑界面按下ctrl+D键,就会出现所有控件的Tab键顺序,按照自己想要的顺序依次点击控件,就可以重新安排顺序.数值1就是默认停留 ...

  4. MFC中窗口静态分割&视图切换

    目录 窗口静态分割 单个分割器 声明 准备视图 静态分割窗口&添加视图 使视图大小随窗口大小改变 多个分割器 声明 静态分割窗口&添加视图 使视图大小随窗口大小改变 视图切换 视图之间 ...

  5. VS2010 MFC中 单独添加ODBC数据库记录集类(CRecordset)方法

    基于VS2010 MFC的项目是之前建好的,后来需要添加数据库. 方法分享于此. 1.  打开自己的项目,项目->添加类. 2. 选MFC ODBC使用者,点右下角的添加. 3. 点数据源. / ...

  6. VS2010 MFC中 创建文件夹及文件判空的方法

    1. MFC中 创建文件夹的方法如下: CString strFolderPath = "./Output"; //判断路径是否存在 if(!PathIsDirectory(str ...

  7. VS2010 MFC中 静态编译设置方法

    问题:VS2010 c++编写的程序在别人的机子运行不了,缺少mfc100u.dll xxx100d.dll等 解决方法:1.将这些dll打包,和应用程序一起发布;2.采用MFC静态编译; 静态编译: ...

  8. MFC中如何分割CString类型的数据

    [才疏学浅,难免有纰漏,若有不正确的地方,欢迎指教] MFC中有一个库函数 Tokenize(); 函数原型:CStringT Tokenize( PCXSTR pszTokens , int& ...

  9. MFC中窗口重绘

    搬家于CSDN 2015-05-14 MFC提供了三个函数用于窗口重绘 InvalidateRect(&Rect) Invalidate() UpdateWindow() 当需要更新或者重绘窗 ...

随机推荐

  1. Composer 下载安装类库

    安装 Composer 你需要先下载 composer.phar 可执行文件. curl -sS https://getcomposer.org/installer | php composer.js ...

  2. Leetcode 525.连续数组

    连续数组 给定一个二进制数组, 找到含有相同数量的 0 和 1 的最长连续子数组. 示例 1: 输入: [0,1] 输出: 2 说明: [0, 1] 是具有相同数量0和1的最长连续子数组. 示例 2: ...

  3. 聊聊、SpringBoot 静态资源访问

    SpringBoot 1.X 版本和 SpringBoot 2.X 版本在静态资源访问上有一些区别,如果直接从 1.X 升级到 2.X 肯定是有问题的.这篇文章就来讲讲这方面问题,也是项目中的坑. 先 ...

  4. hibernate注解配置举例说明

    Hibernate Annotation   (Hibernate 注解)   进入:http://www.hibernate.org 说明文档: 英文:http://docs.jboss.org/h ...

  5. sass和postcss

    sass是css预处理器 需要安装node-sass支持 核心是c++编写 集成 sass-loader 把scss装换成css css-loader 找出@import和url()导入的语法,告诉w ...

  6. BZOJ 1010: [HNOI2008]玩具装箱toy(DP+斜率优化)

    [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊 ...

  7. 【bzoj2836】魔法树 树链剖分+线段树

    题目描述 输入 输出 样例输入 4 0 1 1 2 2 3 4 Add 1 3 1 Query 0 Query 1 Query 2 样例输出 3 3 2 题解 树剖+线段树模板题,不过为什么写的人这么 ...

  8. BZOJ4196 [Noi2015]软件包管理器 【树剖】

    题目 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件 ...

  9. 粟粟的书架(bzoj 1926)

    Description 幸福幼儿园 B29 班的粟粟是一个聪明机灵.乖巧可爱的小朋友,她的爱好是画画和读书,尤其喜欢 Thomas H. Co rmen 的文章.粟粟家中有一个 R行C 列的巨型书架, ...

  10. URL重写IIS7(URL Rewrite Module) 比之前的urlrewrite更方便使用

    原文发布时间为:2011-02-24 -- 来源于本人的百度文章 [由搬家工具导入] 微软在IIS7中添加了URL的重写模块,并且免费使用,可以导入.htaccess规则,确实是个不错的选择 URL ...