今天学习了MFC中拆分窗口,现将方法记录下.

想要在窗口视图中拆分成左右两个视图窗口,首先要注意的是拆分后要加载到左右的视图要符合动态创建的类,

也就是要在自己创建的视图类中添加动态创建机制宏.

类内声明宏:

  DECLARE_DYNCREATE(CSelectView)     //CSelectView为自己创建的视图类

类外实现宏:

  IMPLEMENT_DYNCREATE(CSelectView,CTreeView)  //CTreeView为父类

1.创建两个自己的视图类,

  CSelectView继承于CTreeView

  CMyDialg继承于CFromView

CSelectView用于树形控件显示,没啥可说的.着重说下,对话框的视图类,要注意是子窗口,无边框.所以在窗口属性中要把.Border设置为None,Style设置为Child

下面是两个类的声明:

#pragma once
#include <afxcview.h>  //树形视图类头文件
class CSelectView :
public CTreeView
{
DECLARE_DYNCREATE(CSelectView)
CSelectView();
protected:
//virtual void OnDraw(CDC* pDC) override;
private:
CTreeCtrl *m_pTreeCtrl;
public:
virtual void OnInitialUpdate();
DECLARE_MESSAGE_MAP()
afx_msg void OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult);
}; #include <afxext.h>  //窗口视图类头文件
// CMyDialog 窗体视图 class CMyDialog : public CFormView
{
DECLARE_DYNCREATE(CMyDialog) protected:
CMyDialog(); // 动态创建所使用的受保护的构造函数
virtual ~CMyDialog(); virtual void OnDraw(CDC* pDC) override; public:
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_DIALOG1 };
#endif
#ifdef _DEBUG
virtual void AssertValid() const;
#ifndef _WIN32_WCE
virtual void Dump(CDumpContext& dc) const;
#endif
#endif virtual void OnDragLeave() override; protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持 DECLARE_MESSAGE_MAP()
};

在类外分别加上实现宏

//CSelectView类

#include "CSelectView.h"
#include "MyApp.h" IMPLEMENT_DYNCREATE(CSelectView,CTreeView) //窗口类
#include "resource.h"
#include "CMyDialog.h" // CMyDialog IMPLEMENT_DYNCREATE(CMyDialog, CFormView)

注意,如果父类中有纯虚函数要在自己创建的类中实现,不然无法动态创建类对象

2.在主框架类中重写OnCreateClient()函数

//m_splitter:为类的成员变量:

CSplitterWnd m_splitter;

BOOL MyWnd::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
//拆分窗口(一行两列)
m_splitter.CreateStatic(this, 1, 2);
//创建视图类对象
  //第一列创建树形视图类,第二列创建对话框视图类
m_splitter.CreateView(0, 0, RUNTIME_CLASS(CSelectView),
CSize(200, 200), pContext);
m_splitter.CreateView(0, 1, RUNTIME_CLASS(CMyDialog),
CSize(200, 200), pContext); return TRUE;
}

这样就把主窗口拆分成左右两个视图窗口了,中间的分隔栏可以用鼠标左右拖动

3.加载数据到树形视图中

树形视图类要加载数据就要在初始化函数OnInitialUpdate()中

首先要定义一个CTreeCtrl类型的控件,用来操作数据

在树形视图类中添加

CTreeCtrl*  m_treeCtrl;

在OnInitialUpdate()中添加数据加载

void CSelectView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate(); // TODO: 在此添加专用代码和/或调用基类
m_pTreeCtrl = &GetTreeCtrl();//获取树形视图中的树形控件对象

//添加数据和样式,也可以添加图标,不过我没弄,
m_pTreeCtrl->ModifyStyle(0, TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS| TVS_SHOWSELALWAYS); m_pTreeCtrl->InsertItem(TEXT("显示数据"), 0,0,TVI_ROOT);
m_pTreeCtrl->InsertItem(TEXT("添加数据"), 0, 0, TVI_ROOT);
m_pTreeCtrl->InsertItem(TEXT("修改数据"), 0, 0, TVI_ROOT);
m_pTreeCtrl->InsertItem(TEXT("删除数据"), 0, 0, TVI_ROOT); }

4.更改右边的视图类

根据左边树形视图中的选择,右边更改相应的窗口视图类

在树视图的OnTvnSelchanged函数中处理选择项改变的事件

在主框架类中定义自定义消息用

//自定义消息
#define NM_A   (WM_USER+100)
#define NM_B   (WM_USER+101)
#define NM_C   (WM_USER+102)

void CSelectView::OnTvnSelchanged(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
// TODO: 在此添加控件通知处理程序代码
*pResult = 0;
HTREEITEM hSel = pNMTreeView->itemNew.hItem;  //获取树控件选中的项
CString str = m_pTreeCtrl->GetItemText(hSel);  //获取选中项的字符串数据
//根据选择的项发送自定义消息(NM_A,NM_B)来更改右边的视图窗口类
  //我就随便定义了两个消息NM_A,NM_B,都响应OnMyChange函数
  
if (str == TEXT("添加数据"))
{
::PostMessage(AfxGetMainWnd()->GetSafeHwnd(),NM_A, (WPARAM)NM_A, 0);
}
else if (str == TEXT("修改数据"))
{
::PostMessage(AfxGetMainWnd()->GetSafeHwnd(), NM_B, (WPARAM)NM_B, 0);
} }

在主框架中捕获消息

BEGIN_MESSAGE_MAP(MyWnd,CFrameWnd)
ON_WM_CREATE()
ON_COMMAND(ID_BTN_NEW,&MyWnd::OnBtnNew)
ON_COMMAND(ID_BTN_EDIT,&MyWnd::OnBtnEdit)
ON_COMMAND(ID_BTN_DELETE,&MyWnd::OnBtnDelete)
ON_COMMAND(ID_BTN_QUIT,&MyWnd::OnBtnQuit)
ON_COMMAND(ID_BTN_MIN,&MyWnd::OnBtnMin)
ON_COMMAND(ID_BTN_FIND,&MyWnd::OnBtnFind)
ON_WM_PAINT()
ON_MESSAGE(NM_A,&MyWnd::OnMyChange)//自定义消息函数
ON_MESSAGE(NM_B,&MyWnd::OnMyChange)//自定义消息函数
ON_WM_SIZE()
END_MESSAGE_MAP()

在OnMyChange中实现窗口视图类的切换

LRESULT MyWnd::OnMyChange(WPARAM wParam, LPARAM lParam)
{
CCreateContext context;//动态创建机制结构体
switch (wParam)
{
case NM_A://创建IDD_DIALOG1对话框视图类CMyDialog
{
context.m_pNewViewClass = RUNTIME_CLASS(CMyDialog);//要创建的视图类
context.m_pCurrentFrame = this;    //当前窗口类
context.m_pLastView = (CFormView*)m_splitter.GetPane(0, 1); //要在哪列创建新的视图类,(我这是要在右边,也就是第0行1列)
m_splitter.DeleteView(0, 1);  //删除原来的视图类
m_splitter.CreateView(0, 1, RUNTIME_CLASS(CMyDialog), CSize(200, 200), &context);  //动态创建新的视图类(大小无所谓,最后都是平铺分隔的左右窗口)
CMyDialog *pNewView = (CMyDialog*)m_splitter.GetPane(0, 1); //获取新创建的视图类对象
m_splitter.RecalcLayout();  
pNewView->OnInitialUpdate();  //初始化新视图类
m_splitter.SetActivePane(0, 1);  //激活新的视图类 }
break;
case NM_B: //创建IDD_DIALGO2对话框视图类MyAddDlg
{
context.m_pNewViewClass = RUNTIME_CLASS(MyAddDlg);
context.m_pCurrentFrame = this;
context.m_pLastView = (CFormView*)m_splitter.GetPane(0, 1);
m_splitter.DeleteView(0, 1);
m_splitter.CreateView(0, 1, RUNTIME_CLASS(MyAddDlg), CSize(200, 200), &context);
MyAddDlg *pNewView = (MyAddDlg*)m_splitter.GetPane(0, 1);
m_splitter.RecalcLayout();
pNewView->OnInitialUpdate();
m_splitter.SetActivePane(0, 1); }
break;
case NM_C:
break;
}
/*if (wParam == NM_A)
{
MessageBox(TEXT("添加数据"));
}
else if(wParam==NM_B){
MessageBox(TEXT("修改数据"));
}*/ return 0;
}

效果:

这样就方便用对话框来拖拽控件来布局界面

MFC 静态拆分视图窗口的更多相关文章

  1. MFC之拆分窗口

    7.3.1 多视图 许多文档只要求单个视图,但每个文档可支持一个以上的视图.为了帮助编程人员实现多个视图,文档对象保留它的视图列表.为添加和移去视图提供成员函数,例如,提供的UpdateAllView ...

  2. MFC 静态文本的自绘 空心字的实现

    想在对话框里,显示几个字是很简单的,只要用静态文本的输出就可以了.然而有时候我们需要显示特效的字,我们希望显示的文字就像Word里的艺术字一样,看起来美观.这时我们可以重写CStatic类.用Draw ...

  3. vs mfc 静态文本 改变字体大小

    VC的对话框字体设置对所有控件都有效,你不能单独地改变某个静态文本的字体.对于你的问题,需要首先用CreateFont来建立一个字体对象,然后调用控件的SetFont,就可以了. 例子: 1.改静态文 ...

  4. MFC 静态文本框

    窗体上操作控件内容,需要句柄,在控件处使用鼠标右键——添加变量. DoDataExchange()函数会自动生成代码,把ID与变量绑定(即DDX_Control(pDX, IDC_TEXT, objT ...

  5. MFC如何使用静态MFC库

    大部分MFC程序都是使用 在共享DLL中使用MFC ,但是VS每一个版本都需要一个 MFC运行库,实在是有点烦人. 所以我选择了使用静态MFC库,虽然文件会大一些,但是至少不麻烦了. VS这个做的不够 ...

  6. VS2010 MFC中 静态编译设置方法

    问题:VS2010 c++编写的程序在别人的机子运行不了,缺少mfc100u.dll xxx100d.dll等 解决方法:1.将这些dll打包,和应用程序一起发布;2.采用MFC静态编译; 静态编译: ...

  7. VC++ 窗口拆分CSplitterWnd

    前言         当前许多优秀的软件都采用“多视”技术. 所谓“多视”,是指在同一个框架窗口里同时显示多个视图. 通过运用这种技术,可以在框架的有限控件内同时提供用户更大的信息量,并且使得用户界面 ...

  8. C++ MFC学习 (六)

    由于微软在VS2013 及之后不建议再使用 C/C++ 的传统库函数 scanf,strcpy,sprintf 等,所以直接使用这些库函数会提示 C4996 错误 VS建议采用带 _S的函数,如: s ...

  9. [MFC] MFC编译程序,缺少MFC动态链接库的解决

    问题:VS2010 c++编写的程序在别人的机子运行不了,缺少mfc100u.dll xxx100d.dll等的解决方法   解决方法: 1.将这些dll打包,和应用程序一起发布; 2.采用MFC静态 ...

  10. MFC编译程序,缺少MFC动态链接库的解决

    MFC编译程序,缺少MFC动态链接库的解决 问题:VS2010 c++编写的程序在别人的机子运行不了,缺少mfc100u.dll xxx100d.dll等的解决方法 解决方法: 1.将这些dll打包, ...

随机推荐

  1. vim 中代码的折叠和打开

    # vim 中代码的折叠和打开 reference: vim中代码的折叠和打开(有删改) https://www.cnblogs.com/xuxm2007/archive/2011/11/10/224 ...

  2. ubuntu 安装 github desktop

    原文: https://gist.github.com/berkorbay/6feda478a00b0432d13f1fc0a50467f1 sudo wget https://github.com/ ...

  3. Android发布,全志T507四核A53@1.4GHz工业平台,含税仅168元起!

    近年来,Android系统在工业自动化.仪器仪表.医疗.安防等工业领域的使用日趋广泛.为了满足广大工业用户的需求,创龙科技针对全志T507-H工业平台进行了Android系统适配. 创龙科技T507- ...

  4. Swagger注解说明

    常用注解: - @Api()用于类: 表示标识这个类是swagger的资源 - @ApiOperation()用于方法: 表示一个http请求的操作 - @ApiParam()用于方法,参数,字段说明 ...

  5. 机器学习策略篇:详解数据分布不匹配时,偏差与方差的分析(Bias and Variance with mismatched data distributions)

    详解数据分布不匹配时,偏差与方差的分析 估计学习算法的偏差和方差真的可以帮确定接下来应该优先做的方向,但是,当训练集来自和开发集.测试集不同分布时,分析偏差和方差的方式可能不一样,来看为什么. 继续用 ...

  6. supervisor.conf部署及维护

    启动服务 supervisord -c /etc/supervisord.conf 启动服务 supervisorctl start 关闭服务 supervisorctl stop

  7. [oeasy]python0012_字符_character_chr函数_根据序号得到字符

    ​ 字符(character) 回忆上次内容 上次了解了ord函数 这个函数可以通过字符得到序号 那么可以反过来吗? 通过序号得到字符可以吗? ​ 编辑 ord的逆运算chr 有来就有回 ​ 编辑 好 ...

  8. 栈—顺序栈(C实现)

    // Code file created by C Code Develop // 顺序栈 #include "ccd.h" #include "stdio.h" ...

  9. JavaScript小面试~数组相关的方法和运用(学习笔记)

    1,稀疏数组 稀疏数组是指数组中的某个下标未给出值或某个下标的值被删除.例如: let arrayOne=['xiaozi',,12,,true,23] let arrayTwo=[1,2,3,3,4 ...

  10. 5/15课下作业:评价一下steam软件

    用户界面: 登录后会弹出特惠广告,广告内容可能不常用.主界面简洁方便,启动游戏,购买游戏,浏览社区,浏览自己内容一目了然 记住用户选择: 登录一次后会记住用户的账户密码,可以直接进行用户间的切换,会记 ...