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

news/2024/7/3 4:27:51

文章目录

  • 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.niftyadmin.cn/n/4827492.html

相关文章

任务调度中心 (优化版)【原】

任务调度中心 主要依赖quartz.jar相关类 判断cron表达式 , 在下次即将执行的时间在指定时间内时, 从线程池中取线程进行调度 (优化版) 为什么要有调度中心 因为在集群环境,多server都会在同一时间执行相同定时任务,那么此时定时任务的并发会造成大量数据重复或其它不可预知的业…

Python3内置函数(51-60)

# 51.delattr() # 用于删除属性。 class A(object):x 12y 23delattr(A, x)# 52.format() # Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能。 # 基本语法是通过 {} 和 : 来代替以前的 % 。 # format 函数可以接…

JS 笔记 0330

1. 复习 <!-- 一, 对象的基本介绍对象也是数据的集合是通过属性和属性值来定义数据属性的作用就类似于,数组的索引下标对象是没有length属性的一般从数据库获取的数据形式 [{},{},{},]数组,forEach循环 , for , for...in对象,只能使用 for...in 循环对象的基本操作方法基…

第一篇,就写今天看的东西

一被别人问&#xff1a;你是学什么方向的 我默默回答一句&#xff1a;数据挖掘 别人意味深长の回答一句&#xff1a;哦....... 想必看出了我只是个小白。 既然清楚自己是个小白&#xff0c;开这个博客也只是为了让自己更好的做笔记&#xff0c;并且渴望得到大神的指点&#xff…

Python3内置函数(61-69)

# 61.max() # 返回给定参数的最大值&#xff0c;参数可以为序列。 lst1 (1, 2, 45, 6, 7, 64, 32, 14) print(max(lst1))# 62.memoryview() # 返回给定参数的内存查看对象 v memoryview(bytearray(qwerty, utf-8)) print(v[1]) print(v[-1])# 63.repr() # 将对象转化为供解释…

JS 事件 0331

1.复习 DOM操作,内容的设定 写入 标签对象.innerHTML ‘内容’ 支持解析标签 标签对象.innerText ‘内容’ 不支持,不解析标签 获取 var 变量 标签对象.innerHTML 获取标签的所有内容,包括标签 var 变量 标签对象.innerText 获取标签的所有文本内容,没有标签 事件 鼠标事件…

JS 秒表

<body><div>00:00:00:00</div><button>开始</button><button disabled>暂停</button><button disabled>继续</button><button disabled>重置</button><script>// 秒表功能分析// 核心思路:// 定义一…

Python3的configparser模块的使用

import configparserconfig configparser.ConfigParser()# 字典模式生成配置文件 # 第一个section config[DEFAULT] {A: abc,B: 123, # 数字也要写成string类型C: hello}# 第二个section config[Head] {H1: 100, H2: 200, H3: 300}# 第三个section config[www] {W1: 199, …