MFC窗口分割/拆分

    开发环境:Visual Studio 2012

1 单文档窗口分割

    单文档窗口分割可以借助CSplitterWnd类来实现,具体操作见参考资料[2]。由于静态窗口分割使用的更多,这里只描述在创建静态窗口过程中遇到的问题。

1.1 问题1

    由于要使用到*View类,而*View类又用到*Doc类,因此需要在MainFrm.cpp中添加其头文件,例如

#include "WindowSplitDoc.h"
#include "WindowSplitView.h"
    需要注意的是,*Doc.h必须在*View.h前面。

1.2 问题2

    如果只是调用CSplitterWnd类的CreateStatic函数创建了静态分割窗口,而没有调用其CreateView函数来创建视图,则在运行时报错:

    if (!m_wndSplitter.CreateStatic(this, 2, 1))   
        return FALSE;  
MFC窗口分割/拆分_第1张图片

1.3 问题3

    CMainFrame::OnCreateClient函数默认的返回值为

return CFrameWndEx::OnCreateClient(lpcs, pContext);
    必须将其改为

return TRUE;
    否则,分割不成功!

2 多文档窗口分割

    根据参考资料[9]的125页的说明,这里将介绍一种非常简单的实现方法,这种方法同样适用于单文档窗口分割。

    在MFC提供的程序设计向导MFC AppWizard的如下界面中,选择“用户界面功能”MFC窗口分割/拆分_第2张图片

    在如下界面中,勾选“拆分窗口”,然后点击“完成”即可。

MFC窗口分割/拆分_第3张图片

   运行上述的程序,你可能没有看到拆分窗口,那是因为分界线在最顶端和最左端!要把鼠标移到最顶端/最左端分界线的位置,按住左键往下/右移动就可以看到拆分效果了。

    注意: 这种方法的拆分结果默认情况下是动态的,而且是拆分为4个窗口。可以按参考资料[2]修改为静态拆分,或者修改拆分窗口的布局。

3 对话框窗口分割

    基于对话框的MFC程序窗口的分割,可以见参考资料[1][7]。鉴于参考资料有些表述不清的地方,这些将详细记录对话框窗口分割过程。

3.1 创建基于对话框的程序

    创建一个MFC对话框程序MySplitterDlg。

MFC窗口分割/拆分_第4张图片

3.2 插入Dialog

    在“资源视图”中选择右键单击Dialog,选择“插入Dialog”:

MFC窗口分割/拆分_第5张图片

    用上述方法插入两个对话框:

MFC窗口分割/拆分_第6张图片

    根据参考资料[1]的说明,将上述新添加的两个对话框的属性BorderStyle分别设置为NoneChild

    为了便于区别两个不同的对话框,将各种的默认按钮控件都以及其其它控件都删除,然后分别添加静态文本控件,文件内容分别为“IDD_DIALOG1”和“IDD_DIALOG2”。

3.3 创建对话框类

    为上述的两个对话框分别创类CMyFormView0CMyFormView1,基类别选CDialog,一定要选择CFormView


    创建完成后,类视图如下:

MFC窗口分割/拆分_第7张图片

3.4 增加WM_CREATE消息响应函数OnCreate

    通过“类向导”为“CMySpliterDlgDlg类(不要选择其它类)添加WM_CREATE的消息响应函数:

MFC窗口分割/拆分_第8张图片

3.5 编辑OnCreate

    添加了消息函数OnCreate之后,编辑其内容如下:

int CMySplitterDlgDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogEx::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	// Because the CFRameWnd needs a window class, we will create a new one. I just copied the sample from MSDN Help.
    // When using it in your project, you may keep CS_VREDRAW and CS_HREDRAW and then throw the other three parameters.
    //需要注册窗口类
    CString strMyClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW,  
                   ::LoadCursor(NULL, IDC_ARROW),    (HBRUSH) ::GetStockObject(WHITE_BRUSH),   
                  ::LoadIcon(NULL, IDI_APPLICATION));

    // Create the frame window with "this" as the parent
    m_pMyFrame = new CFrameWnd;
    m_pMyFrame->Create(strMyClass,_T(""), WS_CHILD,   CRect(0,0,300,300), this);
    m_pMyFrame->ShowWindow(SW_SHOW);

    // and finally, create the splitter with the frame as the parent
    m_cSplitter.CreateStatic(m_pMyFrame,1, 2); //在Frame里切分视图窗口为1×2,就是一行两列
    m_cSplitter.CreateView(0,0, RUNTIME_CLASS(CMyFormView0),   CSize(100,100), NULL);//第一行一列
    m_cSplitter.CreateView(0,1, RUNTIME_CLASS(CMyFormView1), CSize(100,100), NULL);//第一行二列

	return 0;
}

    注意:m_pMyFrame-Create()中的字符串(双引号中的空字符串)需要使用_T()进行长字符转换,见上述代码。


3.5.1 添加CFrameWnd变量    

    由于上述程序中用到变量m_pMyFrame,因此需要在类CMySplitterDlgDlg中添加

public:
	CFrameWnd *m_pMyFrame;

    为了防止内存泄露,在onDestroy()中添加

if (m_pMyFrame) delete m_pMyFrame;

3.5.2 添加Dialog头文件    

    此外,由于上述程序还用到了3.3小结所创建的类CMyFormView0和CMyFormView1,因此需要在MySplitterDlgDlg.cpp中添加其头文件

#include "MyFormView0.h"
#include "MyFormView1.h"
3.5.3 添加CSplitterWnd变量

    由于分割窗口时使用到了CSplitterWnd类(见上述OnCreate函数),因此需要在类CMySplitterDlgDlg中添加

CSplitterWnd m_cSplitter;

3.6 编辑OnSize

    添加了消息函数OnCreate之后,编辑其内容如下:

void CMySplitterDlgDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	CRect cRect;
	GetWindowRect(&cRect);
	ScreenToClient(&cRect);
	m_pMyFrame->MoveWindow(&cRect);
	m_pMyFrame->ShowWindow(SW_SHOW);
}

    说明:参考资料[7]中将上述的内容添加在OnInitDialog()函数中。那样虽然也可以显示分割效果,但是放大窗口时分割的窗口并不同步放大。因此,还是将其放在OnSize()中比较适合。


3.7 效果图

MFC窗口分割/拆分_第9张图片

参考资料

[1]基于MFC的窗口拆分

[2]VS2010/MFC编程入门之四十一(文档、视图和框架:分割窗口)

[3]MFC分割窗口的实现

[4]不用splitter控件 简单实现对mfc对话框的分割的方法

[5]Creating a Splitter Window in a Dialog Box in Three Easy Steps

[6]高分悬赏基于对话框的mfc分割两个窗口

[7]VC实现对话框窗口任意分割

[8]MFC中CSplitter的应用以及在View中添加按钮

[9]《MFC Windows应用程序设计》(第3版). 任哲 等编著.  清华大学出版社

[10]MFC中单文档窗口的拆分

[11]MFC拆分窗口及它们之间的数据交换

你可能感兴趣的:(MFC)