静态分割窗口与多视图实例
来源:互联网 发布:php源码分析工具 编辑:程序博客网 时间:2024/06/04 18:28
转自:http://blog.csdn.net/u011478505/article/details/11620145
静态分割窗口与多视图实例
所谓多视,是指在同一个框架窗口下同时显示多个视图。通过运用这种技术,可以在框架的有限的空间内同时提供给用户更大的信息量,并且使得用户界面更加的友好,增强了软件的可操作性。
窗口分割的基本概念
按照分割的时机的不同,窗口分割可以分为两类:动态分割和静态分割。
动态分割是指用户可以动态的分割和合并窗口。动态分割最多可以有2行2列个窗口,并且所有的窗格只能使用同一种视图类。
静态分割是指窗口在创建时,分割窗格窗口的窗格已经创建好了,且窗格的数量和顺序不会改变了,窗格为一个分隔条所分割,用户可以拖动分割条调整相应的窗格的大小。静态分割窗口最多可以有16行16列的窗格,但是各个窗格可以使用不同的视图类。
无论创建那一种分割,都必须在创建时指定最大的行数和列数,这些值是有CSplitterWnd对象进行管理。对于静态分割,必须创建指定数目的所有窗格以填满行和列。而对于动态分割,第一个窗格将在框架创建CSplitterWnd对象时自动创建。
窗口分割支持类CSplitterWnd
CSplitterWnd类主要为窗口的风格提供了封装,窗口被分厂各个窗格后,又该类的对象负责管理。对于windows而言,CSplitterWnd
是一个真正的窗口,它完全占据了框架窗口的用户区域,而视图则占据了分割窗口的床片区域。CSplitterWnd窗口不参与命令传递机制。
使用时,CSplitterWnd对象通常为其父框架窗口CFrameWnd或CMDIChildWnd(MID应用中)对象的内嵌成员。CSplitterWnd对象创建过程如下。
在父框架窗口中嵌入CSplitterWnd类的对象成员;
重载父框架窗口的CFrameWnd::OnCreateClient成员函数;
从上一步重载的函数内部调用Create创建动态分割窗口或者调用CreateStatic创建静态的分割窗口。
下面介绍CsplitterWnd类的几个常用的函数
创建动态分割窗口函数Create
该函数用于动态创建分割窗口,同时将该窗口与类CSplitterWnd相关联,其生声明如下:
BOOL Create(CWnd*pParentWnd, int nMaxRows, int MaxCol, SIZE sizeMin, CcreateContext* pContext, DOWRD dwStyle = WS_CHILD | WS_VISIBLE | WS_HSCROLL| WSVSCROLL | SPLS_DYNAMIC_SPLIT, UINT nID=AFX_IDW_PANE_FIRST);
各主要参数的含义如下:
pParentWnd:分割窗口的父框架窗口的指针
nMaxRows和你MaxCols:行与列的最大值,二者均不大于二
sizeMin:指定窗格被显示时的最小值。例如拖动分割框的幅度小于相应的值时,窗格将不会显示,但是可以调用该类的另外两个成员对此值进行改变。
BOOL CMainFrame::onCreateClient(LPCREATESTRUCT lpcs,CcreateConText*pContext)
{
return m_wndSplitter.Create(this ,2,2, /*设置行与列的数目*/Csize(10,10), /*窗格显示时最小值*/ pContext);
}
创建静态分割窗口函数CreateStatic
该函数用于创建静态分割窗口,同时将该窗口与类CSplitterWnd相关联,其声明如下:
BOOL CreateStatic(CWnd* pParentWnd, int nRows,int nCols, DWORD dwStyle=WS_CHILD|WSVISBLE,UINTnID=AFX_IDW_PANE_FIRST);
主要参数的含义如下:
pParentWnd:分割窗口的父框架窗口指针
nRows和nCols:行与列的最大值,二者均不大于16
dwStyle:窗口风格,默认为子窗口可见,如果添加滚动条,则需另外设置WS_HSCROLL和WS_VSCROLL。
创建窗格视图函数CreateView
CreateView函数为静态分割窗口创建窗格视图,在框架显示分割窗口之前,静态分割窗口的所有窗格都必须创建完毕。其声明如下:
Virtual BOOL CreateView(int row,intcol,CRuntimeClass* pViewClass,SIZE sizeInit, CcreateConText *pContext);
各个主要参数的含义如下:
row :分割窗口中新建视图所在的行。
col:分割窗口中新建视图所在的列。
pViewClass:新建视图的CRuntimeClass的指针。
sizeInit:新建视图的初始化大小。
创建静态分割窗口,并指定各窗格的视图的典型代码如下:
BOOLCMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,CcreateConText* pContext)
{
BOOLbCreateSpltr=m_wndSplitter.CreateStatic(this,2,1);//静态分割
m_wndSplitter.CreateView(0,0,RUNTIME_CLASS(COneView),CSize(0,0),pContext);
m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CAnotherView),CSize(0,0),pContext);
return (bCreateSpltr);
}
另外,CSplitterWnd还提供了一些用于获取和设置窗格属性的函数,常用的函数及其功能如下表。
CSplitterWnd类中的其他常用函数及实现的功能
成员函数
函数说明
GetColumnCount
获取窗口分割的窗格的列数
GetRowCount
获取窗口分割的窗格的行数
SetRowInfo
为窗格行设置最小宽和理想宽,行的最小值决定了行何时因为太小而不能显示
SetColnuInfo
为窗格列设置最小高和理想好,列的最小值决定了列何时因为太小而不能显示
OnDrawSplitter
此函数有框架负责调用,主要用来绘制或者指定分割窗口的确切特性
OnInvertTracker
使用设置分割条的属性,该函数在调整窗格大小期间有框架负责调用
静态分割与多视图实例
实例说明
实例为一个基于单文档的MFc应用程序,通过静态分割窗口的方式三叉切分窗口,即共有三个窗格。程序实现的功能是用户可以输入学生的信息,并添加到列表视图中。程序最终运行的结果如下图:
程序运行结果
其中左侧的基本信息输入的窗格采用的是CFormView类型的视图,在用户可以其中进行信息的录入,单击“提交”按钮,数据就添加道文档中了,并在右侧的列表视图中显示。右侧信息显示的窗格采用的是CListView类型的视图,显示文档中存储的所有学生信息。而底部的窗格采用的是CEditView类型的视图,用于提示用户上一步添加的数据。下面介绍具体的实现过程。
创建工程
使用AppWizard创建一个基于单文档的应用程序框架工程,工程名为“Guo”,其余的现象均采用默认设置。
添加视图类
需要为3个窗格添加3个视图类。CLeftFormView、CTopListView、CBottomEditView,其基类分别为CFormView、CListView和CEditView。
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()函数,在其中定义列表视的类型,代码如下:
BOOLCTopListView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Add your specialized code hereand/or call the base class
cs.style=cs.style|LVS_REPORT;// 设置成报告列表的显示形式
return CListView::PreCreateWindow(cs);
}
使用Class Wizard重载CTopListView类的OnInitialUpdate()函数,在其中添加列表的表头,代码如下:
voidCTopListView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
// TODO: Add your specialized code hereand/or call the base class
CStringm_ColumnLabelStr[]={"学号","姓名","专业","籍贯"};
//表头字段
CListCtrl& listctrl=GetListCtrl();//获取列表的控件
DWORD dwStyle =listctrl.GetExtendedStyle();
dwStyle|= LVS_EX_FULLROWSELECT;
// 选中某行使整行高亮(只适用与report风格的listctrl)
dwStyle |= LVS_EX_GRIDLINES;
dwStyle |=LVS_EX_UNDERLINEHOT;
listctrl.SetExtendedStyle(dwStyle);//列表风格
int width[6]={80,80,110,150};
for(int i=0;i<4;i++)
{
listctrl.InsertColumn(i,m_ColumnLabelStr[i],LVCFMT_LEFT,width[i]);//设置表头
}
}
3、CBottomEidtView类的实现
同样使用New Class对话框,添加CBottomEditView类,将其基类选择为“CEditView”。而后使用Class Wizard重载该类的OnInitialUpdate()函数,在其中实现初始化设置,代码如下:
void CBottomEditView::OnInitialUpdate()
{
CEditView::OnInitialUpdate();
//TODO: Add your specialized code here and/or call the base class
CEdit &mEdit=GetEditCtrl(); //获取编辑视图的控件
mEdit.SetWindowText("等待用户输入学生的信息!");//设置显示信息
mEdit.EnableWindow(FALSE);//编辑控件不可编辑
}
静态分割窗口的实现
窗口的分割过程中是首先在主框架CMainFrame中,将窗口分割成上下两个窗格,对应的视图分别为CGuoView和CBottomEditView。而后,再在CGuoView视图中将窗格分为左右两个窗格,对应的视图分别为CLeftFormView和CTopListView,实现过程如下。
1、 在CMainFrame类的头文件中,声明一个CSplitterWnd类的成员变量m_wndSplitter1,用于第一个窗口的分割
protected: // control bar embedded members
CStatusBar m_wndStatusBar;
CToolBar m_wndToolBar;
CSplitterWnd m_wndSplitter1; //用于产生第一次的静态的分割
2、 使用Class Wizard重载CMainFrame类的OnCreateClient()函数,在其中实现第一次的窗口分割。
BOOLCMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//TODO: Add your specialized code here and/or call the base class
CRect rect;
GetClientRect(&rect); //产生第一次静态分割
m_wndSplitter1.CreateStatic(this, //父窗口指针
2,1); //行数与列数
m_wndSplitter1.CreateView(0,0, //窗格的行列序数
RUNTIME_CLASS(CGuoView),//视图类
CSize(rect.Width(),rect.Height()-rect.Height()/5),pContext);//父窗口创建参数
m_wndSplitter1.CreateView(1,0,RUNTIME_CLASS(CBottomEditView),
CSize(rect.Width(),rect.Height()/5),pContext);
//不在调用基类的OncreateClient函数
return true;
}
包含相应的头文件,在MainFrame.cpp文件的开始加入下列语句
#include "GuoView.h"
#include "BottomEditView.h"
3、 在视图窗口类CGuoView的头文件中声明一个CSplitterWnd类的成员变量m_wndSplitter2,用于第二次窗口分割。
protected:
CSplitterWnd m_wndSplitter2; //用于第二次窗口的分割
4、 使用Class Wizard重载CGuoView类的OnCreateClient()和OnSize()函数,实现窗口第二次分割并设置窗格的大小。
int CGuoView::OnCreate(LPCREATESTRUCTlpCreateStruct)
{
if(CView::OnCreate(lpCreateStruct) == -1)
return-1;
//TODO: Add your specialized creation code here
CRectrect;
GetClientRect(&rect); // 获得窗口的创建信息指针
CCreateContext*pContext=(CCreateContext *)lpCreateStruct->lpCreateParams;
m_wndSplitter2.CreateStatic(this,1,2);//产生第二次的静态分割
//为第一个窗格产生视图
m_wndSplitter2.CreateView(0,0,//窗口的行列序数
RUNTIME_CLASS(CLeftFormView),//视图类
CSize(rect.Width()/4,rect.Height()),//
pContext);
//为第二个窗格产生视图
m_wndSplitter2.CreateView(0,1,RUNTIME_CLASS(CTopListView),CSize(1,1),pContext);
return0;
}
void CGuoView::OnSize(UINT nType, intcx, int cy)
{
CView::OnSize(nType,cx, cy);
//TODO: Add your message handler code here
CRect rect;
GetClientRect(&rect);
intx=rect.Width();
inty=rect.Height();
m_wndSplitter2.MoveWindow(-2,-2,x,y+3);
m_wndSplitter2.SetColumnInfo(0,x/4,0); //左边窗格位置
m_wndSplitter2.SetColumnInfo(1,x-x/4,0); //右边窗格位置
m_wndSplitter2.RecalcLayout();
}
至此,窗口的分割完成,编译运行程序,就会发现三叉窗口已经实现。如果在编译连接程序的时候出现如下面的错误:
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; 就没有问题了。
窗格视图与文档的交互
窗口中分割的各窗格视图对应着同一文档对象CGuoDoc,每个CView派生类都已经继承了GetDocument()函数,因此只要在调用后进行类型的强制转换就可以获取文档的对象。如:CGuoDoc* pDoc=(CGuoDoc*)GetDocument();
本实例在文档对象CGuoDoc中,通过数组类对象存储学生信息,当在CLeftFormView视图中,输入学生信息单击“提交”按钮时,就将输入信息写入文档中的数组对象,并重绘各视图。
1、在CGuoDoc类的头文件中声明数组对象和数据修改标记,如下:
Public:
CStringArray infoArray[4];
bool add;
并在构造函数中将add的值初始化为FALSE。
2、在CLeftFormView类的按钮响应函数OnSubmit()中,添加代码实现控件数据的保存并更新所有视图。
voidCLeftFormView::OnSubmit()
{
//TODO: Add your control notification handler code here
UpdateData(TRUE);// 获取对话框的控件数据
if(m_Num.IsEmpty()||m_Name.IsEmpty()) //判断是否为空
{ AfxMessageBox("学号和姓名不能为空!");return; }
CGuoDoc*pDoc=(CGuoDoc*)GetDocument();// 获取文档
pDoc->infoArray[0].InsertAt(0,m_Num); // 输入数据插入数据
pDoc->infoArray[1].InsertAt(0,m_Name);
pDoc->infoArray[2].InsertAt(0,m_Magor);
pDoc->infoArray[3].InsertAt(0,m_Home);
pDoc->add=true; //添加了数据
pDoc->UpdateAllViews(NULL); //更新所有视图
m_Num=_T("");
m_Name=_T("");
m_Magor=_T("");
m_Home=_T("");
UpdateData(FALSE); //各控件的内容清空
}
包含CGuoDoc类的头文件,在CLeftFormView.cpp文件开始加入下列语句:
#include "GuoDoc.h"
3、重载视图类CTopListView和CBottomEditView中OnUpdate()函数,实现视图更新。
void CTopListView::OnUpdate(CView*pSender, LPARAM lHint, CObject* pHint)
{
//TODO: Add your specialized code here and/or call the base class
CGuoDoc*pDoc=(CGuoDoc*)GetDocument(); //获取文档指针
if(pDoc->add) //添加了数据
{
CListCtrl& listctrl=GetListCtrl();// 获取列表的控件
listctrl.DeleteAllItems(); //删除所有项
for(inti=0;i<pDoc->infoArray[0].GetSize();i++) //列表框中插入数据
{
listctrl.InsertItem(i,pDoc->infoArray[0].GetAt(i));
listctrl.SetItemText(i,1,pDoc->infoArray[1].GetAt(i));
listctrl.SetItemText(i,2,pDoc->infoArray[2].GetAt(i));
listctrl.SetItemText(i,3,pDoc->infoArray[3].GetAt(i));
}
}
}
void CBottomEditView::OnUpdate(CView*pSender, LPARAM lHint, CObject* pHint)
{
//TODO: Add your specialized code here and/or call the base class
CGuoDoc* pDoc=(CGuoDoc*)GetDocument();// 获取文档指针
if(pDoc->add) // 添加了数据
{
CString str;
str="添加了学号为"+pDoc->infoArray[0].GetAt(0)+"的学生信息!";
CEdit &mEdit=GetEditCtrl(); //获取编辑视图控件
mEdit.SetWindowText(str); //显示信息
}
}
同样需要在这两个视图类的资源文件中包含文档对象的头文件,如下:
#include "GuoDoc.h"
至此,实例开发结束,编译运行工程,即可实现要求的结果。
- 静态分割窗口与多视图实例
- 静态分割窗口与多视图实例
- [转] 静态分割窗口与多视图实例
- MFC静态分割视图窗口,切换,固定
- 可切换视图的单文档静态分割窗口总结
- 可切换视图的单文档静态分割窗口总结
- 可切换视图的单文档静态分割窗口总结
- 单文档多视图(分割窗口)
- 单文档多视图(分割窗口)
- 分割视图窗口
- MFC窗口静态分割
- 制作对话框与视图结合的分割窗口
- VC实现视图窗口分割
- 多视图静态切分SDI窗口
- 分窗口与多视图
- MFC CSplitterWnd 静态分割窗口
- 静态分割窗口+关联对话框
- 分割窗口(动态,静态)
- Hibernate.cgf.xml配置文件常用属性
- 切换界面之后 SwipeRefreshLayout 动画效果暂停,以及不消失的解决方案
- 达内素颜-百度
- iframe使用方法
- 初识struts
- 静态分割窗口与多视图实例
- StrangeIoC —— Unity MVC 专属框架
- mvc注解
- 判断一个时间段是否与另一时间段相冲突
- C++ operator关键字(重载操作符)
- Spring 触发器定时器的应用
- 欢迎使用CSDN-markdown编辑器
- Lucene5学习之使用MMSeg4j分词器
- 深入分析JavaWeb Item21 -- JSTL核心标签库