MFC 视图窗口

目录

视图窗口概述

视图窗口的使用

视图窗口创建流程

命令消息 WM_COMMAND 处理顺序

对象关系


视图窗口概述

作用:提供了一个用于显示数据的窗口

关于视图窗口

  • 视图类是用来展示用户,文档类是用来存储和管理数据
  • 视图窗口是覆盖掉框架窗口的客户区
  • 视图窗口是框架窗口的子窗口,它的创建应该是在框架窗口的WM_CREATE消息处理中
  • 每个窗口都有自己消息映射机制,处理属于自己的消息
  • 所有消息中,只有命令消息 WM_COMMAND 是可以被多个类处理的,系统消息,自定义消息只能由对应的窗口处理

框架窗口的消息映射机制:CMyFrameWnd---CFrameWnd---CWnd

视图窗口的消息映射机制:CMyView---CView---CWnd

视图窗口的使用

如何使用?

  • 定义一个自己的视图类(CMyView) ,派生自Cview,并重写父类成员纯虚函数OnDraw(可以用于绘图)
  • 其余框架类和应用程序类代码不变。
  • 在处理框架窗口的WM_CREATE消息时,定义CMyView类对象,并调用Create函数创建视图窗口。

在框架窗口的 WM_CREATE 消息处理函数中创建

int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) {CMyView* pView = new CMyView;pView->Create(NULL, "MFCView", WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(0, 0, 200, 200), this,AFX_IDW_PANE_FIRST);this->m_pViewActive = pView;return CFrameWnd::OnCreate(pcs);
}

WS_CHILD, WS_VISIBLEWS_BORDER 是窗口风格(Window Style)的标志,用于指定窗口的样式和行为。

  • WS_CHILD 表示该窗口是一个子窗口,它位于父窗口内部,并随父窗口的移动和调整大小而相应变化。
  • WS_VISIBLE 表示该窗口是可见的,即在创建后立即显示在屏幕上。
  • WS_BORDER 表示该窗口有一个边框,用于提供视觉上的分隔和装饰

 AFX_IDW_PANE_FIRST:添加之后,视图窗口就会完全覆盖掉框架窗口的客户区。如果客户由多个视图窗口的话,其他视图窗口的创建函数AFX_IDW_PANE_FIRST+1……即可。

但是多个视图窗口中只能由一个是激活窗口。

想要创建成功需要重写纯虚函数,这个纯虚函数是在父类 CVIEW 中的,父类有纯虚函数,所以是抽象类,子类继承父类也是抽象类。所以需要重写纯虚函数才能成功创建

void CMyView::OnDraw(CDC* pDC) {pDC->TextOut(100, 100, "CMyView::OnDraw");
}

在未处理WM_PAINT消息时,这个函数是由父类来调用的处理的

这个是调用父类的消息处理函数 

void CView::OnPaint()
{// standard paint routineCPaintDC dc(this);OnPrepareDC(&dc);OnDraw(&dc);
}

这个函数的功能和处理函数WM_PAINT功能是一样的

void CMyView::OnPaint() {PAINTSTRUCT ps = { 0 };HDC hdc = ::BeginPaint(this->m_hWnd, &ps);::TextOut(hdc, 200, 200, "CMyView::OnPaint", strlen("CMyView::OnPaint"));::EndPaint(this->m_hWnd, &ps);
}

如果重写了WM_PAINT消息,就不会再调用重写的虚函数了,优先交给WM_PAINT消息处理函数处理。

视图窗口创建流程

下断点分析

进入这个函数

熟悉的窗口结构体

创建之前的窗口处理函数,(1)注册窗口(2)更改cs未空的成员

埋个钩子,对WM_CREATE消息感兴趣,保存对象到全局变量程序线程信息,并且在钩子回调函数绑定句柄与对象

视图窗口的创建与框架窗口的创建是一样的

命令消息 WM_COMMAND 处理顺序

给 CMyApp,CMyFrameWnd,CMyView三个添加 WM_COMMAND 消息处理函数

#include <afxwin.h>
#include "resource.h"class CMyView : public CView {DECLARE_MESSAGE_MAP()
public:void OnDraw(CDC* pDC);afx_msg void OnPaint();afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyView, CView)ON_COMMAND( ID_NEW, OnNew )ON_WM_PAINT()
END_MESSAGE_MAP()
void CMyView::OnNew() {AfxMessageBox("视图类处理了WM_COMMAND消息");
}
void CMyView::OnPaint() {PAINTSTRUCT ps = { 0 };HDC hdc = ::BeginPaint(this->m_hWnd, &ps);::TextOut(hdc, 200, 200, "CMyView::OnPaint", strlen("CMyView::OnPaint"));::EndPaint(this->m_hWnd, &ps);
}
void CMyView::OnDraw(CDC* pDC) {pDC->TextOut(100, 100, "CMyView::OnDraw");
}class CMyFrameWnd : public CFrameWnd {DECLARE_MESSAGE_MAP()
public:afx_msg void OnPaint();afx_msg int OnCreate(LPCREATESTRUCT pcs);afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyFrameWnd, CFrameWnd)ON_WM_PAINT()ON_COMMAND( ID_NEW, OnNew )ON_WM_CREATE()
END_MESSAGE_MAP()
void CMyFrameWnd::OnNew() {AfxMessageBox("框架类处理了WM_COMMAND消息");
}
int CMyFrameWnd::OnCreate(LPCREATESTRUCT pcs) {CMyView* pView = new CMyView;pView->Create(NULL, "MFCView", WS_CHILD | WS_VISIBLE | WS_BORDER, CRect(0, 0, 200, 200), this,AFX_IDW_PANE_FIRST);this->m_pViewActive = pView;return CFrameWnd::OnCreate(pcs);
}
void CMyFrameWnd::OnPaint() {PAINTSTRUCT ps = { 0 };HDC hdc = ::BeginPaint(this->m_hWnd, &ps);::TextOut(hdc, 100, 100, "我是框架窗口客户区", strlen("我是框架窗口客户区"));::EndPaint(this->m_hWnd, &ps);
}class CMyWinApp : public CWinApp {DECLARE_MESSAGE_MAP()
public:virtual BOOL InitInstance();afx_msg void OnNew();
};
BEGIN_MESSAGE_MAP(CMyWinApp, CWinApp)ON_COMMAND(ID_NEW, OnNew)
END_MESSAGE_MAP()
void CMyWinApp::OnNew() {AfxMessageBox("应用程序类处理了WM_COMMAND消息");
}
BOOL CMyWinApp::InitInstance() {CMyFrameWnd* pFrame = new CMyFrameWnd;pFrame->Create(NULL, "MFCView", WS_OVERLAPPEDWINDOW, CFrameWnd::rectDefault,NULL, (CHAR*)IDR_MENU1);this->m_pMainWnd = pFrame;pFrame->ShowWindow(SW_SHOW);pFrame->UpdateWindow();return TRUE;
}
CMyWinApp theApp;

可以知道 WM_COMMADN 消息处理的顺序:视图类---框架类---应用程序类

值得一提的是,this->m_pViewActive = pView;  激活当前视图窗口,否则需要先点击以下视图窗口,才能点击 文件--新建。

对象关系

CMyApp 应用程序类是全局的,有一个成员变量,保存了CMyFrameWnd对象地址

CMyFrameWnd对象有一个成员变量保存了 CMyView 对象的地址

也就说说拿到了CMyApp就可以拿到所有对象。

注意:this->m_pViewActive = pView; 还可以激活当前窗口

把这句代码注释掉对比以下:

没有点击视图窗口,点击  文件--新建,是框架类处理的命令消息

点击视图窗口,点击  文件--新建,是视图类处理的命令消息

添加上后,点击  文件--新建,是视图类处理的命令消息

这句代码可以直接把这个窗口设置为激活状态。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/296507.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

整数规划-割平面法

整数规划-割平面法 割平面法思想Gomorys割平面法原理实例 谨以此博客作为学习期间的记录。 割平面法思想 在之前&#xff0c;梳理了分支定界法的流程:分支定界法 除了分支定界法&#xff0c;割平面法也是求解整数规划的另一个利器。 我们已经知道&#xff0c;线性规划的可行域…

全新资源素材站源码 功能齐备 界面干净整洁

源码介绍 简单安装说明&#xff1a; 1、整站程序上传后台 2、然后导入数据库文件到数据库&#xff0c; 3、修改conf里面的conf的数据库名字及密码 4、配置伪静态 规则&#xff1a; location ~* \.(htm)$ { rewrite "^(.*)/(.?).htm(.*?)$" $1/index.php?$2…

【postgres】8、Range 类型

文章目录 8.17 Range 类型8.17.1 内置类型8.17.2 示例8.17.3 开闭区间8.17.4 无穷区间 https://www.postgresql.org/docs/current/rangetypes.html 8.17 Range 类型 Range 类型&#xff0c;可以描述一个数据区间&#xff0c;有明确的子类型&#xff0c;而且子类型应该能被排序…

IgH调试注意事项

1&#xff0c;不要在虚拟机测试&#xff0c;否则IgH无法收发数据包 现象&#xff1a;虚拟机中运行IgH master并绑定网卡后&#xff0c;主站由ORPHANED状态转换成IDLE状态&#xff0c;但无法收发数据报。 这是因为虚拟机用的是虚拟网卡&#xff0c;需通过iptables将数据包到转…

有关List的线程安全、高效读取:不变模式下的CopyOnWriteArrayList类、数据共享通道:BlockingQueue

有关List的线程安全 队列、链表之类的数据结构也是极常用的&#xff0c;几乎所有的应用程序都会与之相关。在java中&#xff0c; ArrayList和Vector都使用数组作为其内部实现。两者最大的不同在与Vector是线程安全的。 而ArrayList不是。此外LinkedList使用链表的数据结构实现…

【VB测绘程序设计】案例4——简单的四则运算练习Select Case语句的使用(附源码)

【VB测绘程序设计】案例4——简单的四则运算练习(附源码) 文章目录 前言一、界面预览二、程序介绍总结前言 在新手学习VB程序设计中,四则运算是基础,通过设计的TexT、按钮、label等控件,定义变量,实现简单程序的编写,提高对VB程序的入门训练。 一、界面预览 二、程序介…

【MybatisPlus快速入门】(2)SpringBoot整合MybatisPlus 之 标准数据层开发 代码示例

目录 1 标准CRUD使用2 新增3 删除4 修改5 根据ID查询6 查询所有7 MyBatis-Plus CRUD总结 之前我们已学习MyBatisPlus在代码示例与MyBatisPlus的简介&#xff0c;在这一节中我们重点学习的是数据层标准的CRUD(增删改查)的实现与分页功能。代码比较多&#xff0c;我们一个个来学习…

【开源】基于JAVA语言的企业项目合同信息系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 合同审批模块2.3 合同签订模块2.4 合同预警模块2.5 数据可视化模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 合同审批表3.2.2 合同签订表3.2.3 合同预警表 四、系统展示五、核心代码5.1 查询合同…

九、W5100S/W5500+RP2040之MicroPython开发<HTTPOneNET示例>

文章目录 1. 前言2. 平台操作流程2.1 创建设备2.2 创建数据流模板 3. WIZnet以太网芯片4. 示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代&#xff0c;MicroPython和树莓派PICO正…

2023,测试开发人的年终总结

根据TesterHome社区发帖整理。从该年终总结可以看出当前测试行业&#xff0c;哪怕是测试开发也是竞争很厉害。作为测试同仁&#xff0c;不但要掌握功能测试、接口测试、性能测试&#xff0c;掌握各种工具使用&#xff0c;还得懂开发&#xff0c;懂Java/Python&#xff0c;懂VUE…

【零基础入门Docker】什么是Dockerfile Syntax

✍面向读者&#xff1a;所有人 ✍所属专栏&#xff1a;零基础入门Docker专栏https://blog.csdn.net/arthas777/category_12455882.html 目录 编写Dockerfile和Format的语法 2. MAINTAINER 3. RUN 4. ADD 6. ENTRYPOINT 7. CMD 8. EXPOSE 9. VOLUME 11. USER 12. ARG …

MySQL创建member表失败

最近在做一个项目&#xff0c;在台式机上可以跑通&#xff0c;也测试了各个已完成的接口&#xff0c;提交到了GitHub后想着用宿舍的电脑跑一下&#xff0c;在测试member表相关接口时就出错了。报了SQL语法错误&#xff0c;但SQL语句很简单&#xff0c;就根据手机号查询不至于出…