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.mzph.cn/news/241388.shtml

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

相关文章

vue的插槽解析

插槽 好处&#xff1a;组件的内容结构可定制 用slot插槽进行占位 语法: 子组件中通过slot进行占位 理解&#xff1a;父组件&#xff0c;在子组件标签嵌套的内容就会被渲染到slot地方 一、默认插槽 //子组件 <slot>slot插槽</slot> //方法一<slot name"…

qt,滚动条,放大缩小拖动图片

头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QLabel> #include <QWheelEvent> #include <QMouseEvent> #include <QtDebug>#include <math.h> #include <QPainter> #include <QTimer>…

详解Vue3中的插槽(slot)

本文主要介绍Vue3中的插槽&#xff08;slot&#xff09;。 目录 一、在普通写法中使用插槽&#xff08;slot&#xff09;作用域插槽默认插槽 二、在setup写法中使用插槽&#xff1a;注意事项 在Vue3中&#xff0c;插槽&#xff08;slot&#xff09;是一种用于在父组件中向子组件…

Unity矩阵平移旋转缩放Matrix4x4

Unity矩阵平移旋转缩放Matrix4x4 Unity中的矩阵&#xff08;Matrix4x4&#xff09;创建自定义模型平移矩阵缩放矩阵旋转矩阵 Unity中的矩阵&#xff08;Matrix4x4&#xff09; 最近在研究帧同步定点数物理系统中需要自定义定点数矩阵&#xff0c;所以在这里分享下基础的矩阵案…

蓝牙物联网在智能家居中的应用前景

物联网智能家居系统是应用物联网技术&#xff0c;在传统家居环境下将各种零散无序的电器整合成统一整体&#xff0c;实现家电的全程自动控制&#xff0c;满足用户高效管理需求的一种新型家居模式。 其主要的子系统有家居感知系统、家庭网络系统、智能家居控制管理系统等&#x…

使用教程之【SkyWant.[2304]】路由器操作系统,破解移动【Netkeeper】校园网【小白篇】

许多高校目前饱受Netkeeper认证的痛苦&#xff0c;普通路由器无法使用&#xff0c; 教你利用SkyWant的Netkeeper认证软件来使你的SkyWant路由器顺利认证上网&#xff0c;全宿舍又可以合作共赢了&#xff01; 步骤一&#xff1a;正确连接网线&#xff0c;插电开机 正确连接网…

SQLITE如何同时查询出第一条和最后一条两条记录

一个时间记录表&#xff0c;需要同时得到整个表或一段时间内第一条和最后一条两条记录&#xff0c;按如下方法会提示错误&#xff1a;ORDER BY clause should come after UNION not before select * from sdayXX order by op_date asc limit 1 union select * from sday…

分布式Session使用步骤

目录 1. 为什么用分布式Session2. Spring-Session使用步骤2-1. 添加依赖2-2. yml配置 1. 为什么用分布式Session 将一个项目部署到多台服务器上时&#xff0c;多台服务器的Tomcat的Session不共享。那么就有可能造成Session数据不一致情况&#xff0c;所以此时就需要使用分布式…

Gateway API

Gateway API 目录 原文链接 https://onedayxyy.cn/docs/GatewayAPI 本节实战 实战名称&#x1f6a9; 实战&#xff1a;Gateway API在istio里的安装及测试-2023.12.23(测试失败) 前言 Gateway API 是由 SIG-NETWORK 社区管理的开源项目&#xff0c;项目地址&#xff1a;http…

Java设计模式-单例模式(Singleton)

Java中实现单例模式有几种不同的方式,每种方式都有其特点和适用场景。下面是两种常用的实现方式:懒汉式和饿汉式。 懒汉式(线程安全) 懒汉式单例是指在第一次被引用时才会创建实例。为了确保线程安全,可以使用同步方法或同步块。 public class SingletonLazy {private sta…

微信小程序生成一个天气查询的小程序

微信小程序生成一个天气查询的小程序 基本的页面结构和逻辑 页面结构&#xff1a;包括一个输入框和一个查询按钮。 页面逻辑&#xff1a;在用户输入城市名称后&#xff0c;点击查询按钮&#xff0c;跳转到天气详情页面&#xff0c;并将城市名称作为参数传递。 主要代码 index…

nodejs+vue+ElementUi洗衣店订单管理系统4691l

衣服但是找订单的时间太长&#xff0c;体验非常的差。而且对于店家这也很头疼&#xff0c;麻烦的查找订单的方式&#xff0c;让他总是重复着繁琐的步骤&#xff0c;记录的时候也很容易出问题&#xff0c;容易把衣服弄错&#xff0c;再然后就是对于收来的衣服也很麻烦&#xff0…

数据结构:线性表顺序存储结构———顺序表

目录 顺序表的定义 初始化线性表 销毁线性表 求线性表的长度 判断是否为空表 插入数据元素 逻辑序号与物理序号的区别 删除数据元素 输出线性表 按序号求线性表中的元素 按元素值查找 整体上创建顺序表 顺序表实验 线性表的顺序存储是把线性表中的所有元素按照其逻…

初识QT(上篇):What Qt

初识QT&#xff08;上篇&#xff09;&#xff1a;What Qt 前言 & 说明前言说明 初识QT1.1 QT的what1. 介绍2. 发展历程3. QT架构的主要内容4.QT的常用模块 1.2 QT的 why1. QT的核心机制 下篇笔记链接 前言 & 说明 前言 前言&#xff1a; 之前说要share的qt相关知识&am…

log4j rename方法

log4j日志切割 os.rename [rootzz test]# cat a2.py import os os.rename(a.txt,b.txt); [rootzz test]# cat a.txt 111111111111111111111 222222222222222222222 [rootzz test]# ls a1.py a2.py a.txt tst.log.1 tst.log.2 [rootzz test]# python ^C [rootzz test]# s…

【AI提示词人物篇】创新艺术未来,让科技改变想象空间

AI 绘画学习难度和练习技巧 学习绘画的技巧 学习能难度&#xff1a; 外貌特征&#xff1a;AI需要学习识别和理解各种外貌特征&#xff0c;如发型、肤色、眼睛颜色等。这可能需要大量的训练数据和复杂的模型架构。 镜头提示&#xff1a;AI需要学习理解不同镜头提示的含义&…

论文笔记--Learning Political Polarization on Social Media Using Neural Networks

论文笔记--Learning Political Polarization on Social Media Using Neural Networks 1. 文章简介2. 文章概括3. 相关工作4. 文章重点技术4.1 Collection of posts4.1.1 数据下载4.1.2 数据预处理4.1.3 统计显著性分析 4.2 Classification of Posts4.3 Polarization of users 5…

Microsoft Edge使用方法和心得

Microsoft Edge 是一款现代的网络浏览器&#xff0c;由微软开发&#xff0c;基于 Chromium 项目。Edge 提供了许多功能和工具&#xff0c;可以提高浏览体验。以下是使用 Microsoft Edge 的方法和一些心得&#xff1a; 基本使用方法 打开和关闭标签页: 点击窗口右上角的 “”…

5G边缘计算:解密边缘计算的魔力

引言 你是否曾想过&#xff0c;网络可以更贴心、更智能地为我们提供服务&#xff1f;5G边缘计算就像是网络的小助手&#xff0c;时刻待命在你身边&#xff0c;让数字生活变得更加便捷。 什么是5G边缘计算&#xff1f; 想象一下&#xff0c;边缘计算就像是在离你最近的一层“云…

SpringMVC:Ajax、拦截器、文件上传、文件下载

文章目录 SpringMVC - 06一、Ajax1. 概述2. Ajax 异步加载数据1. 单个数据2. 对象 3. 实践4. 总结 二、拦截器1. 概述2. 实现3. 实践4. 总结 三、文件上传&#xff1a;Upload1. 准备工作2. 步骤3. 效果 四、文件下载&#xff1a;Download1. 步骤2. 效果3. 总结 注意&#xff1a…