MFC第十七天 CFont类与LOGFONT结构体、记事本文件打开和保存及是否保存的逻辑流程分析、PreTranslateMessage虚函数与快捷键

news2024/11/27 8:40:34

文章目录

  • CFont类与LOGFONT结构体
    • CFontDialog
    • 字体信息结构体与HFONT句柄的关系
  • 记事本文件拖入、打开和保存及是否保存的逻辑流程分析
  • PreTranslateMessage虚函数与快捷键
  • 附录

CFont类与LOGFONT结构体

CFontDialog

构造函数介绍

public:
//用于指定字体对话框的初始字体属性,可以是一个LOGFONT结构体指针。如果指定了这个参数,字体对话框将会显示该初始字体属性。 如果为NULL则使用默认字体样式
	CFontDialog(LPLOGFONT lplfInitial = NULL,
		DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
		CDC* pdcPrinter = NULL,
		CWnd* pParentWnd = NULL);
	CFontDialog(const CHARFORMAT& charformat,
		DWORD dwFlags = CF_SCREENFONTS,
		CDC* pdcPrinter = NULL,
		CWnd* pParentWnd = NULL);
//用于指定字体对话框的父窗口指针。如果指定了这个参数,字体对话框将作为该窗口的子窗口显示;如果为NULL,则字体对话框将作为顶级窗口显示。

CFontDialog是一个对话框类,用于显示字体选择对话框,并允许用户选择字体的样式。

class CFontDialog : public CCommonDialog{
	// Get the selected font (works during DoModal displayed or after)
	void GetCurrentFont(LPLOGFONT lplf);
	CString GetFaceName() const;  // return the face name of the font
	CString GetStyleName() const; // return the style name of the font
	int GetSize() const;          // return the pt size of the font
	COLORREF GetColor() const;    // return the color of the font
	int GetWeight() const;        // return the chosen font weight
	BOOL IsStrikeOut() const;     // return TRUE if strikeout
	BOOL IsUnderline() const;     // return TRUE if underline
	BOOL IsBold() const;          // return TRUE if bold font
	BOOL IsItalic() const;        // return TRUE if italic font
	void GetCharFormat(CHARFORMAT& cf) const;

	LOGFONT m_lf; // default LOGFONT to store the info
	DWORD FillInLogFont(const CHARFORMAT& cf);
};

字体信息结构体与HFONT句柄的关系

a)CFont类有两个重要的函数是关于两者的转换。
b)如果你有句柄就可以调用CWnd::SetFont设置字体。
c)如果你有字体信息结构体对象,调用CFont::CreateFontIndirect来在CFont对象中产生句柄。
(有点类似于struct tm{年月日时分秒}转为time_t句柄)
d)如果你有句柄,可以调用CFont::GetLogFont获取这个字体的信息(通过LOGFONT对象)

使用句柄生成详细信息
CFont* pFont = m_edit.GetFont();//获取了字体的详细信息
if (!pFont)
	return;
LOGFONT lf{};
pFont->GetLogFont(&lf);
使用信息结构体生成句柄
LOGFONT lf{21};
lf.lfWeight = 400;//700是粗体 400正常
lf.lfCharSet = GB2312_CHARSET;
_tcscpy_s(lf.lfFaceName, _countof(lf.lfFaceName), _T("楷体"));
m_font.DeleteObject();//摧毁句柄
m_font.CreateFontIndirect(&lf);
m_edit.SetFont(&m_font);
typedef struct tagLOGFONTW{
    LONG      lfHeight; 字体大小
    LONG      lfWidth; 拉宽(揪脸蛋子),默认用0代表自然高宽。
    LONG      lfEscapement;   LONG      lfOrientation;
    LONG      lfWeight; 粗体:700 正常:400 
    BYTE      lfItalic; 斜体    //那个年代没有bool型
    BYTE      lfUnderline; 下划线
    BYTE      lfStrikeOut; 删除线(横穿)
    BYTE      lfCharSet; 字符集(ANSI_CHARSET)
    BYTE      lfOutPrecision;
    BYTE      lfClipPrecision;
    BYTE      lfQuality;
    BYTE      lfPitchAndFamily;
    WCHAR     lfFaceName[LF_FACESIZE]; //字体名
} LOGFONTW, *PLOGFONTW, NEAR *NPLOGFONTW, FAR *LPLOGFONTW;

示例代码:

void CMainDlg::OnFormatFont()
{
	CFontDialog dlg;
	if (dlg.DoModal() == IDCANCEL)
		return;
	LOGFONT lf;
	dlg.GetCurrentFont(&lf);
	m_font.DeleteObject();
	m_font.CreateFontIndirect(&lf);
	m_edit.SetFont(&m_font);
}	

记事本文件拖入、打开和保存及是否保存的逻辑流程分析

在这里插入图片描述

 void CMainDlg::OnDropFiles(HDROP hDrop)
{
	TCHAR s[MAX_PATH];
	int nCount = DragQueryFile(hDrop, 0, s, _countof(s));

	ReadText(s);
	DragFinish(hDrop);

	CDialog::OnDropFiles(hDrop);
}
BOOL CMainDlg::Prompt() {		//FALSE代表放弃
	if (m_edit.GetModify())	
	{
		CString str = m_sFile;
		if (str.IsEmpty())
			str = _T("无标题");
		int nRes = AfxMessageBox(_T("你想要更改保存文件") + str + _T(":吗?"), MB_YESNOCANCEL);
		if (nRes == IDCANCEL)
			return FALSE;
		if (nRes == IDYES)
			if (!SelectFile())
				return FALSE;
	}
	return TRUE;
}
void CMainDlg::UpdateTitle()
{
	CString str;
	int n = m_sFile.ReverseFind(_T('\\'));
	if (n > 0)
	{
		str = m_sFile.Mid(1 + n);
	}
	if (str.IsEmpty())
		str = _T("无标题");

	str += _T(" - 记事本");

	SetWindowText(str);
}
void CMainDlg::OnFileOpen()
{
	if (m_edit.GetModify())
		if (!Prompt())
			return;
	CFileDialog dlg(TRUE,_T("txt"),NULL,0,m_szFilter);
	if (IDCANCEL == dlg.DoModal())
		return;
	ReadText(dlg.GetPathName());
	UpdateTitle();
}
BOOL CMainDlg::SelectFile()
{
	if (m_sFile.IsEmpty())
	{
		CFileDialog dlg(FALSE, _T("txt"), NULL, OFN_OVERWRITEPROMPT,m_szFilter);
		if (IDCANCEL == dlg.DoModal())
			return FALSE;
		m_sFile = dlg.GetPathName();
		OnFileSave();
	}
	return TRUE;
}
void CMainDlg::OnFileSave(){
	if (!SelectFile())
		return;
	ASSERT(!m_sFile.IsEmpty());
	CFile file;
	if (!file.Open(m_sFile,CFile::modeCreate| CFile::modeWrite))	{
		AfxMessageBox(_T("保存文件失败!"));
		return;	}
	CString str;
	m_edit.GetWindowText(str);
	WORD w{ 0xFEFF };		file.Write(&w,sizeof(w));
	file.Write(str, sizeof(TCHAR) * str.GetLength());
	file.Close();
	UpdateTitle();
	m_edit.SetModify(FALSE);	}
void CMainDlg::OnFileSaveAs()
{
	CFileDialog dlg(FALSE,_T("txt"), NULL,OFN_OVERWRITEPROMPT);
	if (IDCANCEL == dlg.DoModal())
		return;
	m_sFile =dlg.GetPathName();

	OnFileSave();
}

PreTranslateMessage虚函数与快捷键

a)我们经常看到消息被控件拐走了,所以好多消息包括:WM_MOUSEMOVE和WM_KEYDOWN等在消息都在主窗口不能用;
b)当然如果你做控件的派生类再进行子类化,是可以到控件类中去截获这些消息。比如:CEyeCtrl类。
c)预先翻译消息是什么意思?所有的消息被分配到控件或者主窗口之前的入口检查。

PreTranslateMessage函数允许我们在消息到达窗口过程之前对消息进行预处理和转换。通过重写这个函数,我们可以实现对消息的拦截、修改和处理,从而实现一些高级的交互功能,比如处理键盘快捷键。

定义句柄
	HACCEL m_hAccel;
初始化对话框时候加载
m_hAccel = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCEL));
BOOL CMainDlg::PreTranslateMessage(MSG* pMsg)  //消息预处理函数  皇军的岗楼  
{
	if (m_hAccel)
	{
		if (TranslateAccelerator(m_hWnd, m_hAccel, pMsg)) //快捷键的处理
			return TRUE;
	}
	return CDialog::PreTranslateMessage(pMsg);
}

在这里插入图片描述
在这里插入图片描述

附录

CFile类的share模式:

enum OpenFlags {
		modeRead =         (int) 0x00000,
		modeWrite =        (int) 0x00001,
		modeReadWrite =    (int) 0x00002,
		shareCompat =      (int) 0x00000,
		shareExclusive =   (int) 0x00010, 拒绝共享执行
		shareDenyWrite =   (int) 0x00020, 拒绝共享写
		shareDenyRead =    (int) 0x00030, 拒绝共享读
		shareDenyNone =    (int) 0x00040, 不拒绝(可以共享读写都行)
		modeNoInherit =    (int) 0x00080,
		}

比如:shareDenyWrite 拒绝共享写,那么就是CFile打开期间别的进程可以读。

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

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

相关文章

C# Modbus通信从入门到精通(4)——Modbus RTU(0x02功能码)

1、02(0x02)读线圈输入 使用该功能码能从远程地址中读取1到2000个输入线圈的状态,每个线圈的状态只能是0或者1,读取的线圈数量由主站读取时指定。 2、发送报文格式 更详细的格式如下: 从站地址+功能码+起始地址高位+起始地址低位+线圈数量高位+线圈数量低位+CRC,一共8个…

Linux进程理解【程序地址空间】

Linux进程理解【程序地址空间】 文章目录 Linux进程理解【程序地址空间】1. 话题引入2. 进程地址空间2.1 虚拟地址2.2 写时拷贝 3. 知识扩展 我们先来看看C/C程序地址空间的分布图 如此多区域的划分是为了更好的使用和管理空间,但是真实的内存空间也是按照图上的地址…

nginx的下载与安装

https://nginx.org/en/download.html 下载地址(我下载的是1.20.2) 1、首先保证可以连接外网 2、将包拖入opt/nginx 3、安装gcc环境 (如果出现问题可以参考https://www.cnblogs.com/lzxianren/p/4254059.html) yum -y install gc…

你还在手动对比代码差异?这些高质量工具太香了

B站|公众号:啥都会一点的研究生 我发现相当一部分初学者(甚至搬砖多年的老同志)在对比文件差异的时候居然还是 观察法 文本内容少还凑活能用,成百上千行的时候把眼睛累坏了不说,关键还容易漏信息 接触的人与事多了会…

volatile的可见性探讨

我跟volatile修饰对象和数组能保证其内部元素的可见性?一文的作者有类似的疑惑,按语义,volatile修饰数组时,只是保证其引用地址的可见性,可为什么给数组加了volatile之后,似乎单个数组元素也有了可见性&…

Android Glide同步阻塞方式submit获得Bitmap,kotlin

droid Glide同步阻塞方式submit获得Bitmap,kotlin 需要放入后台线程,不能在主线程。 Android Glide预加载preload ,kotlin_zhangphil的博客-CSDN博客【代码】Android Paging 3,kotlin(1)在实际的开发中,虽然Glide解决了…

AC+AP 旁挂式连接配置(华为)

AR1路由器配置 # interface GigabitEthernet0/0/0 ip address 10.1.30.1 255.255.255.0 ip route-static 10.1.20.0 255.255.255.0 10.1.30.2 # LSW1核心交换机 # dhcp enable vlan batch 10 20 30 interface Vlanif20 ip address 10.1.20.1 255.255.255.0 dhcp select in…

nacos启动多个集群

nacos启动多个集群,只需要改动集群的名称,然后再次实例服务即可。

Vue3正式发布那么久了,你认识Pinia了吗?

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步…

一个无经验的大学毕业生,可以转行做软件测试吗?

先说答案,一个无经验的大学毕业生,可以转行做软件测试。 首先什么人会提出这个问题?应该是个大学生,而且肯定不是计算机系毕业的,甚至都不可能是一个工科生。因为哪怕是工科毕业的学生,大学期间最少也学习过C语言编程…

数据结构(王道)——栈的应用

一、括号匹配检查 思路: 算法结构: 代码实现: 算法思路总结: 二、表达式求值 中缀、后缀、前缀表达式: 中缀转后缀表达式 三、栈在递归当中的应用 递归在斐阶乘的应用 缺陷:递归层数过多的话可能会导致栈溢…

小程序MobX创建store并实现全局数据共享

查看小程序根目录中是否存在package.json文件 在项目根目录运行cmd 没有package.json文件输入npm init -y初始化一下,初始化一个包管理 安装MobX npm install --save mobx-miniprogram4.13.2 mobx-miniprogram-bindings1.2.1 小程序菜单栏工具–构建npm 根目录创建store文…

单目相机标定、图像校正、单目位姿估计、差值法检测移动物体、稠密光流法跟踪移动物体

目录 1、单目相机标定 2、图像校正 3、单目位姿估计 4、差值法检测移动物体 5、稠密光流法跟踪移动物体 1、单目相机标定 //单目相机标定 int test1() {//读取所有图像vector<Mat> imgs;string imageName;ifstream fin("F:/testMap/calibdate.txt");while(…

AtCoder Regular Contest 159

B - GCD Subtraction 题意&#xff1a; 给定两个正整数 A , B A,B A,B&#xff0c;给定一个操作&#xff1a;令 g g c d ( A , B ) ggcd(A, B) ggcd(A,B)&#xff0c;令 A A − g , B B − g AA-g, BB-g AA−g,BB−g。问最少经过多少次操作之后其中一个数变为0. 思路&…

APPScan介绍以及安装方式【附带链接】

AppScan介绍和安装 请务必下载绑定的链接&#xff0c;避免环境错误 1.简介 Appscan 10中文版是是全新网络安全漏洞扫描软件&#xff0c;软件可以直接可以对OS命令、SSRF和XXE攻击等漏洞进行检测&#xff0c;使得漏洞检测更加容易&#xff0c;提高漏洞的扫描效率。软件同时支…

[LeetCode周赛复盘] 第 354 场周赛20230716

[LeetCode周赛复盘] 第 354 场周赛20230716 一、本周周赛总结6889. 特殊元素平方和1. 题目描述2. 思路分析3. 代码实现 6929. 数组的最大美丽值1. 题目描述2. 思路分析3. 代码实现 6927. 合法分割的最小下标1. 题目描述2. 思路分析3. 代码实现 6924. 最长合法子字符串的长度1.…

Go语言之重要数组类型map(映射)类型

通过切片&#xff0c;我们可以动态灵活存储管理学生姓名、年龄等信息&#xff0c;比如 names : []string{"张三","李四","王五"} ages : []int{23,24,25} fmt.Println(names) fmt.Println(ages)但是如果我想获取张三的年龄&#xff0c;这是一个…

概率论的学习和整理17:EXCEL的各种期望,方差的公式

目录 1 总结 1.1 本文目标总结方法 1.2 总结一些中间关键函数 2 均值和期望 2.1 求均值的公式 2.2 求随机变量期望的公式 2.3 求随机变量期望的朴素公式 3 方差 3.1 确定数的方差 3.2 统计数的方差公式 3.3 随机变量的方差公式 3.4 EXCEL提供的直接计算方差的公式 …

Ant Design Vue组件,a-select标签

a-select标签是组件里的选择框&#xff0c;具体使用可以查看官网&#xff0c;这里记录一下在使用中遇到的问题。 最近在做项目的时候有一个需求在 a-modal 标签中加入 a-select 标签&#xff0c;a-modal 是模态对话框&#xff0c;意思就是在模态对话框里面添加选择框&#xff0…

Cglib 动态代理实现

每天看看新东西,心情也要好上许多 问题 cglib是如何实现动态代理的cglib如何支持类的代理cglib和jdk的动态代理有什么区别 使用方式 cglib不属于jdk的一部分,因此要使用需要先引入相应的包,maven依赖如下 <dependency><groupId>cglib</groupId><artif…