欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

VC6.0 MFC 视图的切分

程序员文章站 2024-03-16 13:56:04
...

视图的切分

一、前期

1、新建一个工程,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
2、新建一个“Dialog”,首先将“确定”、“取消”按钮去掉,并右击对话框,选择“属性”,对其做些改变,具体如下图所示。(这个对话框是为新建一个视图做准备的)
VC6.0 MFC 视图的切分
3、右击对话框,选择“建立类向导…”,注意的一点是,在基类“Base class”中选择“CFormView”,点击“OK”,点击“确定”,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分这样我们内嵌子视图的准备工作就做好了。

4、接下来,我们在CMainFrame框架类中做一些工作。(框架是个载体,视图是它里面内嵌的东西,要想改变内嵌的东西,必须先从框架着手)。切分视图,我们需要用到一个定义的类(CSplitterWnd),给它定义成员变量CSplitterWnd m_wndSlitter; ,添加位置如下图所示。
VC6.0 MFC 视图的切分
5、然后右击CmainFrame,选择“Add Virtual Function…”,给框架类添加虚函数OnCreateClient,对虚函数进行重载,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(!m_wndSlitter.CreateStatic(this,1,2)) //建立当前窗口的格局。this为父窗口的指针
//第二个参数为将当前窗口切分为几行,第三个参数表示每行有多少列
		return false;
	m_wndSlitter.CreateView(0,0,RUNTIME_CLASS(CChapterView),CSize(300,100),pContext); //0行0列,CChapterView是系统定义的类名
	m_wndSlitter.CreateView(0,1,RUNTIME_CLASS(CMyView),CSize(500,100),pContext);  //0行1列,CMyView我们自己创建的类
	return true;  //有了这个return,下面的return就执行不到了
	return CFrameWnd::OnCreateClient(lpcs, pContext);
}

6、将对应的头文件嵌入进来,如下图所示。
VC6.0 MFC 视图的切分
7、这时编译运行会出现错误,这个错误对应的代码本身没有错,是系统自动产生的,真实原因是由于我们通过视图类的加载,把它作为子视图进行加载的话,它和原先的MFC框架里的文档类进行联系产生了问题。那么这时候我们只需要把文档类嵌入进来,如下图所示。
VC6.0 MFC 视图的切分
8、编译运行后结果如下图所示。
VC6.0 MFC 视图的切分

二、中期

9、我们再插入两个对话框(画圆、画矩形),如下图所示(记得将“确定”、“取消”按钮给删除)。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
10、分别给上面的两个对话框建立类,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
11、在刚刚建立的两个类里面分别画圆和画矩形,由于刚刚新建的两个类里面没有OnDraw函数,我们可以右击CdrawCircleView,选择“Add Virtual Function…”,将OnDraw虚函数添加进来(画矩形CdrawRectangleView同理),如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
12、接下来就在OnDraw()里画圆和矩形,如下图所示。
VC6.0 MFC 视图的切分

void CDrawCircleView::OnDraw(CDC* pDC) 
{
	// TODO: Add your specialized code here and/or call the base class
	pDC->Ellipse(50,50,600,600);  //仅作为测试用,所以只画个大概就行
}

画矩形同理:
void CDrawRectangleView::OnDraw(CDC* pDC) 
{
	// TODO: Add your specialized code here and/or call the base class
	pDC->Rectangle(200,200,600,600);	
}

13、接下来的问题就是如何加载这样两个视图,这时候我们就可以加菜单,并为菜单建立消息映射函数,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
14、在框架类里面,把两个新的视图类头文件给嵌入进来,如下图所示。
VC6.0 MFC 视图的切分
15、然后再到它的消息响应函数里面(OnMDrawCircle()和OnMDrawRectangle()),添加代码如下图所示。
VC6.0 MFC 视图的切分

void CMainFrame::OnMDrawCircle() 
{
	// TODO: Add your command handler code here
	m_wndSlitter.DeleteView(0,1); //加载之前先要删除,删除以后又重新加载(删除0行1列)
	m_wndSlitter.CreateView(0,1,RUNTIME_CLASS(CDrawCircleView),CSize(500,100),NULL); //用画圆的视图加载进来
	m_wndSlitter.RecalcLayout(); //重新计算一下布局
}

void CMainFrame::OnMDrawRectangle() 
{
	// TODO: Add your command handler code here
	m_wndSlitter.DeleteView(0,1);
	m_wndSlitter.CreateView(0,1,RUNTIME_CLASS(CDrawRectangleView),CSize(500,100),NULL);
	m_wndSlitter.RecalcLayout();
}

16、此时运行结果如下图所示。
VC6.0 MFC 视图的切分

三、后期

17、现在,我们通过参数传递,首先在这样两个视图里面建立接收参数的机制。这种方法跟以前画圆和矩形方法一样,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分

void CDrawCircleView::DrawCircle(CDC *pDC, POINT center, int radius)
{
	pDC->Ellipse(center.x - radius,center.y - radius,center.x + radius,center.y + radius);
}

VC6.0 MFC 视图的切分

void CDrawRectangleView::DrawRectangle(CDC *pDC, POINT p1, POINT p2)
{
	pDC->Rectangle(p1.x,p1.y,p2.x,p2.y);

}

18、这样两个接口接好了,我们就来建立对话框,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
(矩形的不再赘述)
VC6.0 MFC 视图的切分
19、建立上面两个的类向导,如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
20、把对话框类导入进来,如下图所示。
VC6.0 MFC 视图的切分
21、然后在画圆和画矩形的消息响应函数里面,把对话框属性调出来,如下图所示。
VC6.0 MFC 视图的切分

CDlg_CircleParaSet dlg_circleParaSet;
dlg_circleParaSet.DoModal();
//========================================================
CDlg_RectangleParaSet dlg_rectangleParaSet;
dlg_rectangleParaSet.DoModal();

22、此时,编译运行后的结果如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分
23、如何把对话框成员变量的值传递给画圆和画矩形的视图类,也就是让CDrawCircleView里面的OnDraw()和CDrawRectangleView里面的OnDraw()获取到,这是我们研究的难点。因为一个视图,它牵涉到类之间的数据传递。OnDraw()里面就一个参数pDC,它没有提供某些参数来接收外界传过来的参数,于是我们引入另外一种机制——全局变量。

24、新建“文件”,如下图所示。
VC6.0 MFC 视图的切分
25、再新建一个它配套的Source File,如下图所示。
VC6.0 MFC 视图的切分
26、首先在GlobalParas.h里写上一些东西,代码如下。

#if !defined(GlobalParas_H)
#define GlobalParas_H
//待会儿在这添加代码
#endif

27、然后在GlobalParas.cpp里写上一些东西,如下图所示。
VC6.0 MFC 视图的切分
28、再将GlobalParas.cpp里定义的int变量复制到GlobalParas.h里,因为是头文件,所以把赋值给去掉,加上extern,如下图所示。
VC6.0 MFC 视图的切分
29、接下来把对话框里的值传到全局变量里面去(全局量在任何地方都可以用)。在CDrawCircleView里把GlobalParas.h头文件嵌入进来(CDrawRectangleView里也一样),如下图所示。
VC6.0 MFC 视图的切分
30、在框架类里,也要把全局量的头文件嵌入进来,如下图所示。
VC6.0 MFC 视图的切分
31、嵌入进来以后,我们对其进行设置。分别将对话框中画圆的参数和画矩形的参数传给全局变量,如下图所示。
VC6.0 MFC 视图的切分

void CMainFrame::OnMDrawCircle() 
{
	// TODO: Add your command handler code here
	CDlg_CircleParaSet dlg_circleParaSet;
	if(IDOK == dlg_circleParaSet.DoModal())
	{
		global_circle_x = dlg_circleParaSet.m_x;
		global_circle_y = dlg_circleParaSet.m_y;
		global_circle_r = dlg_circleParaSet.m_r;
	}
	m_wndSlitter.DeleteView(0,1); //加载之前先要删除,删除以后又重新加载(删除0行1列)
	m_wndSlitter.CreateView(0,1,RUNTIME_CLASS(CDrawCircleView),CSize(500,100),NULL); //用画圆的视图加载进来
	m_wndSlitter.RecalcLayout(); //重新计算一下布局
}

void CMainFrame::OnMDrawRectangle() 
{
	// TODO: Add your command handler code here
	CDlg_RectangleParaSet dlg_rectangleParaSet;
	if(IDOK == dlg_rectangleParaSet.DoModal())
	{
		global_rectangle_lx = dlg_rectangleParaSet.m_lx;
		global_rectangle_ly = dlg_rectangleParaSet.m_ly;
		global_rectangle_rx = dlg_rectangleParaSet.m_rx;
		global_rectangle_ry = dlg_rectangleParaSet.m_ry;
	}
	m_wndSlitter.DeleteView(0,1);
	m_wndSlitter.CreateView(0,1,RUNTIME_CLASS(CDrawRectangleView),CSize(500,100),NULL);
	m_wndSlitter.RecalcLayout();
}

32、然后分别在CDrawCircleView和CDrawRectangleView的OnDraw()里去调用,如下图所示。
VC6.0 MFC 视图的切分

void CDrawCircleView::OnDraw(CDC* pDC) 
{
	// TODO: Add your specialized code here and/or call the base class
	//pDC->Ellipse(50,50,600,600);
	DrawCircle(pDC,CPoint(global_circle_x,global_circle_y),global_circle_r);
	
}

VC6.0 MFC 视图的切分

void CDrawRectangleView::OnDraw(CDC* pDC) 
{
	// TODO: Add your specialized code here and/or call the base class
	//pDC->Rectangle(200,200,600,600);
	DrawRectangle(pDC,CPoint(global_rectangle_lx,global_rectangle_ly),CPoint(global_rectangle_rx,global_rectangle_ry));
	
}

33、编译运行,最终实现效果如下图所示。
VC6.0 MFC 视图的切分
VC6.0 MFC 视图的切分