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

一个偶然的机会又重新接触了MFC窗口的分割,自己结合资料重新写了一个窗口分割的程序,现将具体流程跟大家分享一下:

1.我们先创建一个MFC单文档类的程序,具体分割方式先将单文档整个客户区分成两行一列,首先我们在MFC的CMainFrame类中定义一个CSplitterWnd类的对像m_wndSplitter,在主窗口类中我们可以通过对象m_wndSplitter,调用CSplitterWnd类的所有成员函数,为了将窗口分割成两行一列,我们在CMainFrame类中重载OnCreateClient函数,在OnCreateClient函数中编写代码,我们现将窗口分割:

CRect rect;
   GetClientRect(&rect); //产生第一次静态分割
   m_wndSplitter.CreateStatic(this, //父窗口指针
  2,1); //行数与列数

将主窗口分割成两行一列

然后将分割的窗口与一个特定的类关联起来。

m_wndSplitter.CreateView(0,0, //窗格的行列序数
  RUNTIME_CLASS(CFengeView),//视图类

CSize(rect.Width(),rect.Height()-rect.Height()/5),pContext);//父窗口创建参数

m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(Cliftdown),
  CSize(rect.Width(),rect.Height()/5),pContext); //给分割的窗口关联上对于的类
 //不在调用基类的OncreateClient函数
return true;

这里分割开的两个窗口一个关联基础视类,另一个因为我们要用作一些信息的显示用,我们创建一个新类,这个新类的基础类是CEditView,完成后要注意头文件也要关联上,否则CMainFrame 不认识新创建的类。运行一下如果报以下错误:

error C2143: syntax error : missing ';' before '*'
                             error C2501: 'CFengeDoc' : missing storage-class or type specifiers
                             error C2501: 'GetDocument' : missing storage-class or type specifiers

我们在视类的头文件的开头添加#include "fengeDoc.h"即可,再次运行

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

OK接下来我们要在这个基础上再次进行分割,将第一行分割成两列,第一行的第一列我们要求它有输入功能主要是信息的录入,以及按钮的添加,第一行的第二列我们要求它一列表的形式显示

我们添加录入的信息。为了完成以上功能我们首先添加一个对话框资源,给这个对话框资源关联上一个新类,新类的基础类是 CFormView,同时为了能以一个类表的形式显示录入的信心我们还有添加一个新的类,这个类的基础类是CListView,好了类添加完成我们要在第一次分割的基础上再次分割,这次分割的流程和第一次的思路是一样的,但要注意几点不同:1.我们要在基础视类中添加一个CSplitterWnd类的对像m_wndSplitter1,2.直接在基础视类中重载OnCreate函数中添加分割代码具体代码如下:

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

CRect rect;
 GetClientRect(&rect); //  获得窗口的创建信息指针
CCreateContext *pContext=(CCreateContext *)lpCreateStruct->lpCreateParams;
m_wndSplitter1.CreateStatic(this,1,2); //产生第二次的静态分割
 //为第一个窗格产生视图
m_wndSplitter1.CreateView(0,0,//窗口的行列序数
  RUNTIME_CLASS(Cliftup),//视图类
CSize(rect.Width()/4,rect.Height()),//
pContext);
//为第二个窗格产生视图
m_wndSplitter1.CreateView(0,1,RUNTIME_CLASS(Crightup),CSize(1,1),pContext);
return 0;

同时在主视类中添加OnSize函数并在函数中添加代码:

CView::OnSize(nType, cx, cy);
CRect rect;
GetClientRect(&rect);
int x=rect.Width();
int y=rect.Height();
m_wndSplitter1.MoveWindow(-2,-2,x,y+3);
m_wndSplitter1.SetColumnInfo(0,x/4,0); //左边窗格位置
m_wndSplitter1.SetColumnInfo(1,x-x/4,0); //右边窗格位置
m_wndSplitter1.RecalcLayout();

除了要添加上识别头文件外,还要注意当程序报错说找不到CListView类时我们在新建的Crightup类的头文件中添加# include <afxcview.h>。给对话框中的按钮添加一个消息响应函数,消息响应函数就在对话框所关联的类下即Cliftup类。为了将我们在对话框中录入的信息显示出来,要先创建一个数组用来存放这些信息,这里我们在CFengeDoc类中创建一个CStringArray类型的数字infoArray[4],同时定义一个BOOL类型的变量add;注意一定要在构造函数中给add初始化要不然会报错的,接下来给对话框的四个编辑框关联上四个CString类型的变量。分别是m_num,m_name,m_zhuanye,m_home.

下边我们要做的是把几块儿视图区联系起来,首先在Cliftup类下的按钮响应函数中填写一下代码:

UpdateData(TRUE);

if(m_num.IsEmpty()||m_name.IsEmpty())

{

AfxMessageBox("填写不能为空");

return 1;

}

CFengeDoc*pDoc=((CFengeDoc*)GetDocument();

pDoc->InfoArray[0].InsertAt(0,m_num);

pDoc->InfoArray[1].InsertAt(0,m_name);

pDoc->InfoArray[2].InsertAt(0,m_zhuanye);

pDoc->InfoArray[3].InsetAt(0,m_home);

pDoc->add=true; //添加了数据
pDoc->UpdateAllViews(NULL); //更新所有视图
m_num=_T("");
m_name=_T("");
m_zhuanye=_T("");
m_home=_T("");
UpdateData(FALSE); //各控件的内容清空

接下来在Cliftdown类中重载OnInitialUpdate() 函数,在函数中添加代码:

CEdit &mEdit=GetEditCtrl(); //获取编辑视图的控件
mEdit.SetWindowText("等待用户输入学生的信息!");//设置显示信息
mEdit.EnableWindow(FALSE); //编辑控件不可编辑

再次在Cliftdown类中重载另一个函数OnUpdate,在函数中添加代码:

CFengeDoc* pDoc=(CFengeDoc*)GetDocument(); // 获取文档指针
if(pDoc->add) // 添加了数据
{
CString str;
str="已经成功添加了学号为"+pDoc->infoArray[0].GetAt(0)+"的学生信息!";
CEdit &mEdit=GetEditCtrl(); //获取编辑视图控件
mEdit.SetWindowText(str); //显示信息

}

然后再Crightup类中重载函数OnInitialUpdate() ,在函数中添加代码:

CString m_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]);

}

在Crightup类中重载函数PreCreateWindow并添加代码:

cs.style=cs.style|LVS_REPORT;// 设置成报告列表的显示形式

同时再次在Crightup类中重载函数OnUpdate,并在函数中添加代码:

CFengeDoc* pDoc=(CFengeDoc*)GetDocument(); //获取文档指针都要获取文档类指针,把文档类当成了桥梁
if(pDoc->add) //添加了数据
{
CListCtrl& listctrl=GetListCtrl(); // 获取列表的控件
listctrl.DeleteAllItems(); //删除所有项
for(int i=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));
}

}

OK现在运行一下:

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

上一篇:Sql Server数据库备份脚本以及如何在阿里云云数据库RDS还原数据库(代码源自阿里云)


下一篇:老司机实战Windows Server Docker:2 docker化现有iis应用的正确姿势