今天学习了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. 基于 SQLite 3 的 C 学习:1-开发流程 与 基本函数

    背景 SQLite 是 一个 常用于 嵌入式平台的 轻量级的 关系型数据库. 我们已经介绍了 移植 SQLite 3 ,这一讲我们来介绍它的开发,这里仅仅涉及最基本的开发. 高级api:https:/ ...

  2. FLUTTER 中 Isolate 的一个例子.

    isolate 起因 最近看了一点isolate的东西, 自己写了一个例子. 普通的的 consummer-producer例子是只有前后两端的,实际上,会把前后两端再进行包装. 我这里这个例子,是把 ...

  3. VS License Header Manager 插件

    /************************************************************************************* * * 文 件 名: %F ...

  4. 从安装到配置,教你用Argo CD对接CCE集群完成测试、生产部署

    本文分享自华为云社区<Argo CD对接CCE完成不同测试.生产环境业务部署>,作者: 可以交个朋友. 一 背景说明 Argo CD是用于Kubernetes的声明性GitOps持续交付工 ...

  5. Python数据分析方法与技巧

    背景介绍 数据分析是数据科学领域的核心技能之一,它涉及到数据的收集.清洗.处理.分析和可视化. 数据分析是指通过收集.清洗.处理.分析和可视化数据来发现隐藏的模式.趋势和关系的过程. 数据分析是数据科 ...

  6. PHP 缓存技术

    PHP 缓存介绍 什么是缓存 数据交换的缓冲区(称作Cache) 临时文件交换区 缓存作用 减少网络延迟,加快页面打开速度 减少数据查询次数,降低数据库压力 降低系统负荷,极大的提升系统性能 常用缓存 ...

  7. [oeasy]python0048_注释_comment_设置默认编码格式

    注释Comment 回忆上次内容 使用了版本控制 git 制作备份 进行回滚   尝试了 嵌套的控制结构 层层 控制   不过 除非 到不得以 尽量不要 太多层次的嵌套   这样 从顶到底 含义 明确 ...

  8. oeasy 教您玩转 linux 010207 黑客帝国 matrix

    我们来回顾一下 上一部分我们都讲了什么? 蒸汽机车sl 变身小机车-l 变身飞天机车-F 让我们再开一次车 sl 上次还想看看黑客帝国来着?! 黑客帝国Matrix apt search matrix ...

  9. 格式输出函数printf()详解_C语言

    printf函数称为格式输出函数,其关键字最末一个字母f即为"格式"(format)之意.其功能是按用户指定的格式,把指定的数据显示到显示器屏幕上. printf函数调用的一般形式 ...

  10. php8.3开启jit技术

    查看是否开启:$jitEnabled = ini_get('jit.enabled'); echo "JIT Enabled: " . ($jitEnabled == '1' ? ...