MFC中文档与视图(二)
Last Edit 2013/11/19
这篇主要是介绍一下怎么去分割视图。
视图的分割分为:动态分割,静态分割。所谓的静态分割是指软件一启动视图就分割完成,而动态分割是在使用过程中动态的去实现的。大家可能都用过Word里面拆分窗口,这就是动态分割的一个例子。
 
要实现分割要使用到MFC中一个CSplitterWnd类
常用的几个函数。
Create是动态分割用到的函数
  1.  
    virtual BOOL Create(
  2.  
    CWnd* pParentWnd,//分割窗口的父窗口框架
  3.  
    int nMaxRows, //最大的行 最大为2
  4.  
    int nMaxCols, //最大的列 最大为2
  5.  
    SIZE sizeMin, //规定一个窗口的最小尺寸,要是小于这个尺寸,分割的窗口就不会显示
  6.  
    CCreateContext* pContext, //上下文
  7.  
    DWORD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL | WS_VSCROLL | SPLS_DYNAMIC_SPLIT,
  8.  
    UINT nID = AFX_IDW_PANE_FIRST
  9.  
    );
CreateStatic创建静态窗口函数,参数含义同上。
  1.  
    virtual BOOL CreateStatic(
  2.  
    CWnd* pParentWnd,
  3.  
    int nRows,
  4.  
    int nCols,
  5.  
    DWORD dwStyle = WS_CHILD | WS_VISIBLE,
  6.  
    UINT nID = AFX_IDW_PANE_FIRST
  7.  
    );
CreateView为分割出来的区域创建指定的视图类
  1.  
    virtual BOOL CreateView(
  2.  
    int row,
  3.  
    int col,
  4.  
    CRuntimeClass* pViewClass,
  5.  
    SIZE sizeInit,
  6.  
    CCreateContext* pContext
  7.  
    );
一、动态分割的实现过程
 

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

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

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

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

在CFrameWnd::OnCreateClient添加如下代码

return m_wndSplitter.Create(this,2, 2, CSize(10, 10), pContext);

二、静态分割的实现过程

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

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

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

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

  1.  
    CRect m_crect;
  2.  
    GetClientRect(&m_crect);
  3.  
     
  4.  
    if (!m_wndSpliter.CreateStatic(this,2,1))
  5.  
    {
  6.  
    return FALSE;
  7.  
    }
  8.  
    if (!m_wndSpliter.CreateView(0,0,RUNTIME_CLASS(CmyWindowView),CSize(m_crect.Width(),m_crect.Height()/2),pContext))
  9.  
    {
  10.  
    return FALSE;
  11.  
    }
  12.  
     
  13.  
    if (!m_wndSpliter.CreateView(1,0,RUNTIME_CLASS(CmyWindowView),CSize(m_crect.Width(),m_crect.Height()/2),pContext))
  14.  
    {
  15.  
    return FALSE;
  16.  
    }
  17.  
    return TRUE;

三、综合实例

下面的这个实例是从网上看来的,记录一下,以便以后好查找。实现过程基本是按照作者的思路来的。

添加视图类

需要为3个窗格添加3个视图类。CLeftFormView、CTopListView、CBottomEditView,其基类分别为CFormView、CListView和CEditView。(注意是MFC类)

1、CLeftFormView类的实现

A、 添加对话框资源模板:添加CLeftFormView类之前,首先要向工程中添加CLeftFormView视图中对话框模板,如下图所示:

对话框模板的ID为“IDD_DIALOG1”,其Style属性设置为“Child”,Bolder属性设置为“None”。

B、添加CLeftFormView类。执行“Insert”→“New Class”菜单命令,弹出“New Class”对话框,在其中的Name编辑框中输入类名“CLeftFormView”,在Base Class列表框中选择基类“CFormView”选项,在Dialog ID列表框中选择“IDD_DIALOG1”对话框资源。单击Ok即可实现CLeftFormView类的添加。

C、添加CLeftFormView类的相关资源:利用Class Wizard在CLeftFormView中,为对话框模板的4个编辑控件分别添加CString类型的成员变量m_Num、m_Name、m_Magor、m_Home,并为“提交”按钮添加BN_CLICKED消息响应函数OnSubmit()。

2、CTopListView类的实现

同样使用“New Class”对话框,添加CTopListView类,将其基类选择类型为CListView。然后使用Class Wizard重载该类的PreCreateWindow()函数,在其中定义列表视的类型,代码如下:

  1.  
    BOOLCTopListView::PreCreateWindow(CREATESTRUCT& cs)
  2.  
    {
  3.  
    // TODO: Add your specialized code hereand/or call the base class
  4.  
    cs.style=cs.style|LVS_REPORT;// 设置成报告列表的显示形式
  5.  
     
  6.  
    return CListView::PreCreateWindow(cs);
  7.  
    }

使用Class Wizard重载CTopListView类的OnInitialUpdate()函数,在其中添加列表的表头,代码如下:

  1.  
    voidCTopListView::OnInitialUpdate()
  2.  
    {
  3.  
    CListView::OnInitialUpdate();
  4.  
    // TODO: Add your specialized code hereand/or call the base class
  5.  
    CString m_ColumnLabelStr[]={"学号","姓名","专业","籍贯"}; //表头字段
  6.  
    CListCtrl & listctrl=GetListCtrl();//获取列表的控件
  7.  
    DWORD dwStyle =listctrl.GetExtendedStyle();
  8.  
    dwStyle|= LVS_EX_FULLROWSELECT; // 选中某行使整行高亮(只适用与report风格的listctrl)
  9.  
    dwStyle |= LVS_EX_GRIDLINES;
  10.  
    dwStyle |=LVS_EX_UNDERLINEHOT;
  11.  
    listctrl.SetExtendedStyle(dwStyle);//列表风格
  12.  
    int width[6]={80,80,110,150};
  13.  
    for(int i=0;i<4;i++)
  14.  
    {
  15.  
    listctrl.InsertColumn(i,m_ColumnLabelStr[i],LVCFMT_LEFT,width[i]);//设置表头
  16.  
  17.  
    }

3、CBottomEidtView类的实现

同样使用New Class对话框,添加CBottomEditView类,将其基类选择为“CEditView”。而后使用Class Wizard重载该类的OnInitialUpdate()函数,在其中实现初始化设置,代码如下

  1.  
    void CBottomEditView::OnInitialUpdate()
  2.  
    {
  3.  
    CEditView::OnInitialUpdate();
  4.  
    //TODO: Add your specialized code here and/or call the base class
  5.  
    CEdit &mEdit=GetEditCtrl(); //获取编辑视图的控件
  6.  
    mEdit.SetWindowText("等待用户输入学生的信息!");//设置显示信息
  7.  
    mEdit.EnableWindow(FALSE);//编辑控件不可编辑
  8.  
    }

静态分割窗口的实现

窗口的分割过程中是首先在主框架CMainFrame中,将窗口分割成上下两个窗格,对应的视图分别为CGuoView和CBottomEditView。而后,再在CGuoView视图中将窗格分为左右两个窗格,对应的视图分别为CLeftFormView和CTopListView,实现过程如下。

1、 在CMainFrame类的头文件中,声明一个CSplitterWnd类的成员变量m_wndSplitter1,用于第一个窗口的分割

  CSplitterWnd    m_wndSplitter1; //用于产生第一次的静态的分割

2、 使用Class Wizard重载CMainFrame类的OnCreateClient()函数,在其中实现第一次的窗口分割

  1.  
    BOOLCMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
  2.  
    {
  3.  
    //TODO: Add your specialized code here and/or call the base class
  4.  
    CRect rect;
  5.  
    GetClientRect(&rect); //产生第一次静态分割
  6.  
    m_wndSplitter1.CreateStatic(this, //父窗口指针
  7.  
    2,1); //行数与列数
  8.  
    m_wndSplitter1.CreateView(0,0, //窗格的行列序数
  9.  
    RUNTIME_CLASS(CGuoView),//视图类
  10.  
    CSize(rect.Width(),rect.Height()-rect.Height()/5),pContext);//父窗口创建参数
  11.  
    m_wndSplitter1.CreateView(1,0,RUNTIME_CLASS(CBottomEditView),
  12.  
    CSize(rect.Width(),rect.Height()/5),pContext);
  13.  
    //不在调用基类的OncreateClient函数
  14.  
    return true;
  15.  
    }

包含相应的头文件,在MainFrame.cpp文件的开始加入下列语句

#include "GuoView.h"

#include "BottomEditView.h"

3、 在视图窗口类CGuoView的头文件中声明一个CSplitterWnd类的成员变量m_wndSplitter2,用于第二次窗口分割。

protected:

CSplitterWnd m_wndSplitter2; //用于第二次窗口的分割

4、 使用Class Wizard重载CGuoView类的OnCreateClient()和OnSize()函数,实现窗口第二次分割并设置窗格的大小。

  1.  
    int CGuoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  2.  
    {
  3.  
    if(CView::OnCreate(lpCreateStruct) == -1)
  4.  
    return-1;
  5.  
    //TODO: Add your specialized creation code here
  6.  
    CRectrect;
  7.  
    GetClientRect(&rect); // 获得窗口的创建信息指针
  8.  
    CCreateContext *pContext=(CCreateContext *)lpCreateStruct->lpCreateParams;
  9.  
    m_wndSplitter2.CreateStatic(this,1,2);//产生第二次的静态分割
  10.  
    //为第一个窗格产生视图
  11.  
    m_wndSplitter2.CreateView(0,0,//窗口的行列序数
  12.  
    RUNTIME_CLASS(CLeftFormView),//视图类
  13.  
    CSize(rect.Width()/4,rect.Height()),//
  14.  
    pContext);
  15.  
    //为第二个窗格产生视图
  16.  
    m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CTopListView),CSize(1,1),pContext);
  17.  
    return0;
  18.  
    }

至此,窗口的分割完成,编译运行程序,就会发现三叉窗口已经实现。如果在编译连接程序的时候出现如下面的错误:

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2143: syntax error : missing ';' before '*'

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2501: 'CGuoDoc' : missing storage-class or type specifiers

c:\documents and settings\chenqi\桌面\guo\guoview.h(23) :error C2501: 'GetDocument' : missing storage-class or type specifiers

则可以在CGuoView类头文件的前面加上这么一句class CGuoDoc; 就没有问题了。

MFC界面分割以及挂载的更多相关文章

  1. MFC界面相关源码

    这是这4篇MFC界面的相关源码.建议学习Visual C++的看看这2本微软官方出的教材. [MFC Windows程序设计(第2版,修订版)](美)Jeff Prosise著 [Windows程序设 ...

  2. C++做四则运算的MFC计算器(一)MFC界面创建

    学习最有效的方法就是实战,这两篇文章写了做MFC加减乘除计算器的过程. 第一写前台MFC界面搭建,第二写后台计算原理及代码. MFC编程参考教程:http://www.jizhuomi.com/sch ...

  3. windows核心编程课程实践---多线程文件搜索器(MFC界面)

    课上完了连老师见都没见一面QAQ....记录一下该小项目 效果如下: 1.实现文件搜索功能,并封装为类 1)首先是文件搜索类Rapidfinder的构造函数和析构函数和文件信息初始化函数和文件路径规格 ...

  4. MFC 窗口分割与通信

    一.关于CSplitterWnd类我们在使用CuteFtp或者NetAnt等工具的时候,一般都会被其复杂的界面所吸引,在这些界面中窗口被分割为若干的区域,真正做到了窗口的任意分割. 那么我们自己如何创 ...

  5. 为MFC界面添加一个Log Window

    前言 由于早期的图像处理程序基于VC6.0,MFC也是采用VC6.0开发的.在实际处理中,我不仅需要界面的显示,有很多时候,我需要算法处理的过程中的信息,比如每个阶段的耗时,处理的图像大小,以及如果需 ...

  6. VC6.0中MFC界面换肤简例

    利用VC中的MFC进行界面设计时,发现界面上的各控件无法简易地进行调整,比如字体大小.颜色.格式等. 为了改变外观,小小地美化一下,今天决定动手一试. 网上提供的库和方法不计其数,我选择了SkinMa ...

  7. MFC窗口分割以及各窗口间的通讯

    一个偶然的机会又重新接触了MFC窗口的分割,自己结合资料重新写了一个窗口分割的程序,现将具体流程跟大家分享一下: 1.我们先创建一个MFC单文档类的程序,具体分割方式先将单文档整个客户区分成两行一列, ...

  8. 【转】MFC界面更新实现方法

    原文网址:http://www.cnblogs.com/skywatcher/p/3572311.html 1.更新窗口 即采用UpdateWindow()函数立即发送WM_PAINT消息更新整个窗口 ...

  9. MFC界面更新实现方法

    1.更新窗口 即采用UpdateWindow()函数立即发送WM_PAINT消息更新整个窗口. void CEditTestDlg::OnBnClickedBtnSysUpdate() { CStri ...

随机推荐

  1. 什么是HTML DOM对象

    HTML DOM 对象 HTML DOM Document 对象 Document 对象 每个载入浏览器的 HTML 文档都会成为 Document 对象. Document 对象使我们可以从脚本中对 ...

  2. linux目录结构特点

    #####linux目录结构特点一切从根开始linx中每个设备可以挂载在任何目录上面磁盘/设备/分区没有挂载 无法使用 举例-linux下面使用光盘###1.把光盘放入到光驱中 ###2.linux中 ...

  3. Mac appStore下载软件报500错误的解决方法

    Step1.打开"启动台": Step2:打开"其他": Step3:打开"终端": Step4:复制如下代码,主要不要作任何更改,不要有多 ...

  4. 将项目添加到服务上时报web modules的错误

    将项目添加到服务上时报web modules的错误如下图: 这是tomcat的版本和web modules的版本不支持造成的,如果在如下地方修改不了: 这时候就要在项目的根目录修改如下图: 用工具打开 ...

  5. 本地Git仓库和Github仓库的关联

    1.我们首先创建一个文件夹(用于保存本地仓) 在我们想要创建的路径下右键鼠标打开Git Bash Here(创建一个文件夹,并进入文件夹) 2.通过命令git init把我们刚才创建的文件夹变成Git ...

  6. dict字典的一些优势和劣势

    01. 键必须是可散列的一个可散列的对象必须满足以下要求. (1) 支持 hash() 函数,并且通过 __hash__() 方法所得到的散列值是不变的. (2) 支持通过 __eq__() 方法来检 ...

  7. HDU 3565 Bi-peak Number(数位DP)题解

    题意:我们定义每一位先严格递增(第一位不为0)后严格递减的数为峰(比如1231),一个数由两个峰组成称为双峰,一个双峰的价值为每一位位数和,问L~R双峰最大价值 思路:数位DP.显然这个问题和pos有 ...

  8. docker入门实例

    Docker 是什么? 我们在理解 Docker 之前,首先得先区分清楚两个概念,容器和虚拟机. 每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用. 每一台虚拟机包括应 ...

  9. springboot2.0 JPA配置自定义repository,并作为基类BaseRepository使用

    springboot2.0 JPA配置自定义repository,并作为基类BaseRepository使用 原文链接:https://www.cnblogs.com/blog5277/p/10661 ...

  10. 微信小程序点击列表添加 去除属性

    首先说一下场景:我所循环的数据是对象数组,设置了一个属性当作标记,通过这个标记的值判断是否给改元素添加样式 wxml: <view> <view wx:for="{{lis ...