MFC第二十八天 WM_SIZE应用,CFrameWnd类LoadFrame的方法,PreCreateWindow窗口预处理,Frame-view窗口视图

news2024/11/23 13:05:30

文章目录

  • WM_SIZE应用
    • 通过WM_SIZE消息实现窗口布局管理
    • 通过控件属性实现窗口布局管理
  • CFrameWnd类
    • CFrameWnd类简介
    • OnCreate和OnCreateClient的方法
    • 注册时的要素与窗口设置
    • PreCreateWindow创建窗口的预处理函数
  • 附录
    • 预处理函数的结构体
    • CFrameWnd::LoadFrame与CreateFrame

WM_SIZE应用

通过WM_SIZE消息实现窗口布局管理

// CApp 消息处理程序
BOOL CAboutDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	CRect rect, rc;
	GetClientRect(rect);
	m_ok.GetWindowRect(rc); //这个取得屏幕 全屏的坐标
	ScreenToClient(rc); // 转化为同一坐标系
	m_cxMargin = rect.right - rc.right;
	m_cyMargin = rect.bottom - rc.bottom;
	
	return TRUE;  
}
void CAboutDlg::OnSize(UINT nType, int cx, int cy)
{
	CDialogEx::OnSize(nType, cx, cy);
	
	if (m_ok)
	{
		CRect rect;
		m_ok.GetWindowRect(rect);
		int x = cx - m_cxMargin - rect.Width();
		int y = cy - m_cyMargin - rect.Height();
		m_ok.SetWindowPos(NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
	}
}

通过控件属性实现窗口布局管理

点击相应控件的属性,对其进行动态布局的设置,选择两者,窗口再次进行拉伸就会进行改变。

在这里插入图片描述

CFrameWnd类

CFrameWnd类简介

a)CFrameWnd类偏爱WM_CREATE,因为所有的内部窗口都是代码创建的。
而不像对话框是拖入的。
b)CFrameWnd::rectDefault管理层叠
static const CRect rectDefault;
c)LoadFrame内部包含CreateFrame,同时执行注册以及加载快捷键等(参见附录)

class CFrameWnd : public CWnd
{
	DECLARE_DYNCREATE(CFrameWnd)

// Constructors
public:
	static AFX_DATA const CRect rectDefault;
	CFrameWnd();

	BOOL LoadAccelTable(LPCTSTR lpszResourceName);
//创建框架
	virtual BOOL Create(LPCTSTR lpszClassName,
				LPCTSTR lpszWindowName,
				DWORD dwStyle = WS_OVERLAPPEDWINDOW,
				const RECT& rect = rectDefault,
				CWnd* pParentWnd = NULL,        // != NULL for popups
				LPCTSTR lpszMenuName = NULL,
				DWORD dwExStyle = 0,
				CCreateContext* pContext = NULL);
// 加载框架 - load frame and associated resources
	virtual BOOL LoadFrame(UINT nIDResource,
				DWORD dwDefaultStyle = WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE,
				CWnd* pParentWnd = NULL,
				CCreateContext* pContext = NULL);

// 创建中央视图 helper for view creation
	CWnd* CreateView(CCreateContext* pContext, UINT nID = AFX_IDW_PANE_FIRST);

// 第十三章文档架构时获取激活文档
	virtual CDocument* GetActiveDocument();
//多文档架构获取激活视图 Active child view maintenance
	CView* GetActiveView() const;           // active view or NULL
	void SetActiveView(CView* pViewNew, BOOL bNotify = TRUE);
		// active view or NULL, bNotify == FALSE if focus should not be set

	// 多文档架构的让某个子框架激活,Active frame (for frames within frames -- MDI)
	virtual CFrameWnd* GetActiveFrame();

	// For customizing the default messages on the status bar
	virtual void GetMessageString(UINT nID, CString& rMessage) const;

	BOOL m_bAutoMenuEnable;
		// TRUE => menu items without handlers will be disabled

	BOOL IsTracking();
// Operations
	virtual void RecalcLayout(BOOL bNotify = TRUE); //核心排版
	virtual void ActivateFrame(int nCmdShow = -1);
	void InitialUpdateFrame(CDocument* pDoc, BOOL bMakeVisible);
	void SetTitle(LPCTSTR lpszTitle);
	CString GetTitle() const;
	
	virtual UINT GetTrackingID() { return m_nIDTracking; }
	// set/get menu bar visibility style
	virtual void SetMenuBarVisibility(DWORD dwStyle);
	virtual DWORD GetMenuBarVisibility() const;
	// set/get menu bar visibility state
	virtual BOOL SetMenuBarState(DWORD dwState);
	virtual DWORD GetMenuBarState() const;
	BOOL GetMenuBarInfo(LONG idObject, LONG idItem, PMENUBARINFO pmbi) const;
protected:
	virtual BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);

	friend class CWinApp;
};

OnCreate和OnCreateClient的方法

为啥对话框CDialog类不偏爱WM_CREATE消息?
a)对话框类使用WM_INITDIALOG消息或者虚函数来初始化;
b)WM_CREATE消息对于对话框也是有效的,为什么对话框很少用这 个消息呢?
c)对话框程序需要初始化控件,WM_CREATE是主窗口刚刚创建好,控件还没有。
d)所以它偏爱OnInitDialog虚函数,控件都被创建好之后方便初始化那些控件。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	static CMenu menu;  //临时对象生命周期不够需要加static
	menu.LoadMenu(IDR_MAINFRAME);
	SetMenu(&menu);

	CCreateContext cc;
	cc.m_pNewViewClass = RUNTIME_CLASS(CMainView);
	CreateView(&cc);
}
#include "CTestBtn.h"
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
//创建客户区的主区视图
{
	CCreateContext cc;
//	cc.m_pNewViewClass = RUNTIME_CLASS(CTestBtn);
	cc.m_pNewViewClass = RUNTIME_CLASS(CMainView);
	m_pMainView = (CMainView*)CreateView(&cc, AFX_IDW_PANE_FIRST);
	 //AFX_IDW_PANE_FIRST在中间区域自动缩放
	return m_pMainView!=NULL;
}
int CTestBtn::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CButton::OnCreate(lpCreateStruct) == -1)
		return -1;

	SetWindowText(_T("按钮?"));
	return 0;
}

BOOL CTestBtn::PreCreateWindow(CREATESTRUCT& cs)  //视图就是CreateView
{
	cs.lpszClass = _T("BUTTON");

	return CButton::PreCreateWindow(cs);
}

注册时的要素与窗口设置

a)例如:注册时你指定灰色背景,窗口生成后可以在WM_ERASEBKGND消息中改成别的颜色。
b)其他包括图标(SetIcon),光标WM_SETCURSOR消息中改,以及菜单(SetMenu)。
c)例如:但凡Create一个Edit注册时的要素都会默认呈现,比如光标的形状,背景是白色。
d)但是后面都是可以改的,比如你想把某个edit改为绿底红字的。(WM_CTLCOLOR)

BOOL CMainFrame::OnEraseBkgnd(CDC* pDC)
{  
	CRect rect;
	GetClientRect(rect);
	pDC->FillSolidRect(rect, 0xffee00); //可指定其他的颜色 注册可以该 默认的实施  按照注册来实施
	
	return TRUE;
	//你注册的灰色是由return CFrameWnd::OnEraseBkgnd(pDC);来实施的
	//return CFrameWnd::OnEraseBkgnd(pdc)  改为return TRUE 则没有注册的颜色
}

PreCreateWindow创建窗口的预处理函数

创建窗口的预处理函数:virtual BOOL PreCreateWindow(CREATESTRUCT& cs);  

a)预处理核心的一个工作就是注册窗口规格,包括光标,图标以及背景颜色等;
b)预处理函数的结构体中包含,位置、高宽以及菜单,style和dwExStyle
c)为什么LoadFrame中使用注册,而CreateFrame根本没注册都好使?
那就是因为窗口预处理中执行注册,可以说即使从CWnd类派生你只要做预处理就不用RegisterClass

//预处理核心的一个工作就是注册窗口规格,包括光标,图标以及背景颜色等
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs){
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	//  CREATESTRUCT cs 来修改窗口类或样式
	/*cs.x = 100;
	cs.y = 100;
	cs.cx = 200;
	cs.cy = 300;*/ //没有这几行的代码的话 默认是重叠的 有了的话不会重叠
//	cs.style |= WS_THICKFRAME; //拖动大小开关
//	cs.hMenu = ::LoadMenu(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_MAINFRAME));
	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);
	return TRUE;
}

附录

预处理函数的结构体

typedef struct tagCREATESTRUCTW {
    LPVOID      lpCreateParams;
    HINSTANCE   hInstance;
    HMENU       hMenu;
    HWND        hwndParent;
    int         cy;
    int         cx;
    int         y;
    int         x;
    LONG        style;
    LPCWSTR     lpszName;//标题
    LPCWSTR     lpszClass;//类型名
    DWORD       dwExStyle;//扩展风格
} CREATESTRUCTW, *LPCREATESTRUCTW;

CFrameWnd::LoadFrame与CreateFrame

BOOL CFrameWnd::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle,
	CWnd* pParentWnd, CCreateContext* pContext)
{

	CString strFullString;
	if (strFullString.LoadString(nIDResource))
		AfxExtractSubString(m_strTitle, strFullString, 0);    // first sub-string

	VERIFY(AfxDeferRegisterClass(AFX_WNDFRAMEORVIEW_REG));

	// attempt to create the window
	LPCTSTR lpszClass = GetIconWndClass(dwDefaultStyle, nIDResource);
	CString strTitle = m_strTitle;
	if (!Create(lpszClass, strTitle, dwDefaultStyle, rectDefault, 
	  pParentWnd, ATL_MAKEINTRESOURCE(nIDResource), 0L, pContext))
	{
		return FALSE;   // will self destruct on failure normally
	}

	// save the default menu handle
	ASSERT(m_hWnd != NULL);
	m_hMenuDefault = m_dwMenuBarState == AFX_MBS_VISIBLE ? ::GetMenu(m_hWnd) : m_hMenu;

	// load accelerator resource
	LoadAccelTable(ATL_MAKEINTRESOURCE(nIDResource));

	if (pContext == NULL)   // send initial update
		SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);

	return TRUE;
}

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

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

相关文章

K8S系列文章之 Traefik快速入门

traefik 与 nginx 一样,是一款优秀的反向代理工具,或者叫 Edge Router。至于使用它的原因则基于以下几点 无须重启即可更新配置自动的服务发现与负载均衡与 docker 的完美集成,基于 container label 的配置漂亮的 dashboard 界面metrics 的支…

周末在家值班,解决几个月前遗忘的Bug

问题: 周末被迫在家值班,无聊之际打开尘封已久的Bug清单,发现有Bug拖了几个月还没解决… 场景是这样子的,有个功能是拿Redis缓存热点数据进行展示,暂且称它为功能A,有个另外的功能B,它会去更新缓…

(文章复现)建筑集成光储系统规划运行综合优化方法matlab代码

参考文献: [1]陈柯蒙,肖曦,田培根等.一种建筑集成光储系统规划运行综合优化方法[J].中国电机工程学报,2023,43(13):5001-5012. 1.基本原理 本文建立的双层耦合模型内、外层分别对应求解容量配置与能量调度问题。外层模型设置光伏与储能容量备选集并将容量配置组合…

【基础类】—原型链系统性知识

一、创建对象有几种方法 字面量创建对象 1-1. 什么是字面量 字面量就是所见即所,指的是常量;用来为变量赋值时的常数量 代码例子:123;‘ABC’, {name: ‘张三’}, undefined , true 生活例子:门店的招牌&a…

Docker安装Mysql、Redis、nginx、nacos等环境

相关系列文章: 1、DockerHarbor私有仓库快速搭建 2、DockerJenkinsHarbor 1、服务器 Ip部署内容说明192.168.88.7Docker、Mysql、redis、nacosnode1192.168.88.8Docker、Mysql、redis、nacosnode2192.168.88.9Docker、redis、nacos、nginxnode3 2、安装PXC8.0 Mys…

【已解决】Java 中使用 ES 高级客户端库 RestHighLevelClient 清理百万级规模历史数据

🎉工作中遇到这样一个需求场景:由于ES数据库中历史数据过多,占用太多的磁盘空间,需要定期地进行清理,在一定程度上可以释放磁盘空间,减轻磁盘空间压力。 🎈在经过调研之后发现,某服务…

AI一键生成短视频

AI一键生成推文短视频 阅读时长:10分钟 本文内容: 结合开源AI,一键生成短视频发布到常见的某音,某手平台,狠狠赚一笔 前置知识: 1.基本的 python 编程知识 2.chatGPT 使用过 3.stable diffution 使用过 成果…

一键开启ChatGPT“危险发言”

‍ ‍ 大数据文摘授权转载自学术头条 作者:Hazel Yan 编辑:佩奇 随着大模型技术的普及,AI 聊天机器人已成为社交娱乐、客户服务和教育辅助的常见工具之一。 然而,不安全的 AI 聊天机器人可能会被部分人用于传播虚假信息、操纵舆…

冠达管理:稳增长政策密集加码 顺周期板块有望持续表现

上星期A股商场回暖显着,首要宽基指数大都震荡收涨;日均成交额上升至约9600亿元;北向资金延续净买入,周净买入A股124.7亿元。职业层面,方针预期催化下,顺周期方向的金融、房地产等职业领涨。 机构以为&#…

方法区内存溢出及常量池

22 方法区-定义 是所有线程共享的一块区域。 存储了和类结构相关信息。运行时常量池, 方法区在虚拟机启动时被创建,逻辑上是堆的组成部分。方法区内存不足,也会导致oom异常。 是一个概念上的东西, 1.6使用永久代作为方法区&#…

Mybatis引出的一系列问题-spring多数据源配置

在日常开发中我们都是以单个数据库进行开发,在小型项目中是完全能够满足需求的。但是,当我们牵扯到像淘宝、京东这样的大型项目的时候,单个数据库就难以承受用户的CRUD操作。那么此时,我们就需要使用多个数据源进行读写分离的操作…

在Linux服务器上搭建Git

环境 服务器:Ubuntu 客户端:Win11 1、在服务器上安装Git(服务器中处理) 在服务器上执行git --version 如果出现: 则,已经安装Git,跳过此步骤。 如果没有,则: 执行…

前端个人年度工作述职报告(二十篇)

前端个人年度工作述职报告篇1 尊敬的各位领导、各位同仁: 大家好!按照20__年度我公司就职人员工作评估的安排和要求,我认真剖析、总结了自己的工作情况,现将本人工作开展情况向各位领导、同仁做以汇报,有不妥之处,希…

ElasticSearch详细操作

ElasticSearch搜索引擎详细操作以及概念 文章目录 ElasticSearch搜索引擎详细操作以及概念 1、_cat节点操作1.1、GET/_cat/nodes:查看所有节点1.2、GET/_cat/health:查看es健康状况1.3_、_GET/_cat/master:查看主节点1.4、GET/_cat/indices&a…

内存快照:宕机后,Redis如何实现快速恢复?RDB

AOF的回顾 回顾Redis 的AOF的持久化机制。 Redis 避免数据丢失的 AOF 方法。这个方法的好处,是每次执行只需要记录操作命令,需要持久化的数据量不大。一般而言,只要你采用的不是 always 的持久化策略,就不会对性能造成太大影响。 …

OpenAI因担心隐私问题而阻止GPT-4图像功能的发展

据《纽约时报》报道,GPT-4的图像能力可以识别某些个人。 OpenAI一直在测试其支持图像识别的多模态GPT-4版本,以便计划中的广泛发布。然而,据周二《纽约时报》报道,出于对其可能识别特定个体的担忧,公众访问被限制了。…

(2023国赛必看)零基础挑战一周拿下数学建模国奖

1、 数学建模国赛介绍 1.1 数学建模国赛是什么?如何评奖 全国大学生数学建模竞赛是全国高校规模最大的课外科技活动之一。该竞赛每年9月(一般在上旬某个周末的星期五至下周星期一共3天,72小时)举行,竞赛面向全国大专院…

使用vscode远程登录以及本地使用的配置(插件推荐)

1、远程登陆ssh 1.1打开vscode插件商店,安装remote-ssh插件 远程ssh添加第三方插件:vscode下链接远程服务器安装插件失败、速度慢等解决方法_vscode远程安装不上扩展_Emphatic的博客-CSDN博客 转到定义,选中代码->鼠标右键->转到定义…

Linux:在使用UEFI固件的计算机上内核是如何被启动的

前言 启动计算机通常不是一件难事:按下电源键,稍等片刻,你就能看到一个登录界面,再输入正确的密码,就可以开启一天的网上冲浪之旅了。 但偶尔这件事没那么顺利,有时候迎接你的不是熟悉的登录界面&#xf…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)--功能实现[五]

文章目录 SSM--功能实现实现功能09-带条件查询分页显示列表需求分析/图解思路分析代码实现测试分页条件查询带条件分页查询显示效果 实现功能10-添加家居表单前端校验需求分析/图解思路分析代码实现完成测试测试页面效果 实现功能11-添加家居表单后端校验需求分析/图解思路分析…