mfc 简单使用

简介

MFC(Microsoft Foundation Class Library,微软基础类库)是微软推出的一个 C++ 类库,主要用于 Windows 平台下的应用程序开发。它封装了 Windows API(应用程序接口)的复杂细节,提供了一套面向对象的编程框架,简化了 Windows 应用程序的开发过程。

核心特点:

  • 面向对象封装:MFC 将 Windows API 中的结构体、函数等封装成类,例如窗口(CWnd)、对话框(CDialog)、按钮(CButton)等,开发者可以通过继承和多态等面向对象特性快速构建应用。

  • 消息映射机制:MFC 提供了消息映射(Message Mapping)机制,将 Windows 的消息(如鼠标点击、键盘输入)与类的成员函数关联,简化了消息处理流程,无需手动编写复杂的回调函数。

  • 文档 / 视图架构:MFC 的文档 / 视图(Document/View)结构是其核心设计之一,将数据管理(文档,CDocument)与数据显示(视图,CView)分离,适合开发需要处理复杂数据并进行多视图展示的应用(如文本编辑器、图像浏览器)。

  • 丰富的控件支持:内置了大量常用的 Windows 控件(按钮、文本框、列表框、树控件等)的封装类,同时支持自定义控件开发。
    与 Windows 系统深度集成:直接调用 Windows 底层功能,支持多线程、网络编程、数据库访问(通过 ODBC 或 OLE DB)、ActiveX 控件等 Windows 特性。

对话框

以 vs 2022 为例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

创建后的文件结构

在这里插入图片描述
framework.h

  • 包含了 MFC 框架中一些基础的头文件,定义了一些常用的宏、类型定义和基础类声明。它是 MFC 框架的基础包含文件,为整个项目提供了必要的基础定义和类型支持,使得项目能够正确使用 MFC 框架中的各种功能。

MFCApplication1.h

  • 这是应用程序类的头文件。应用程序类通常从CWinApp派生,在这个类中,会处理应用程序的初始化、运行和终止等操作,比如初始化全局资源、创建主窗口(在基于对话框的应用中就是创建对话框窗口)、处理消息循环等。

MFCApplication1Dlg.h

  • 定义了应用程序主对话框类,这个类通常从CDialogEx派生(CDialogEx是CDialog的扩展版本,提供了更多现代化的对话框特性)。在这个头文件中,会声明对话框上控件对应的成员变量(通过DDX_ 宏关联),以及对话框处理各种消息(如按钮点击、菜单选择等)的成员函数(通过ON_宏映射) 。

pch.h

  • 预编译头文件。它包含了项目中经常使用的头文件,比如 MFC 的核心头文件。Visual Studio 可以对这个头文件进行预编译,生成预编译头文件(.pch 文件),在编译其他源文件时,直接使用预编译头文件,从而加快编译速度。

Resource.h

  • 资源符号定义文件,用于定义项目中各种资源(如对话框、菜单、图标等)的 ID。当在 Visual Studio 的资源编辑器中创建或修改资源时,对应的资源 ID 会自动在这个文件中进行定义,方便在代码中引用这些资源。

targetver.h

  • 定义了目标 Windows 平台的版本信息,通过宏来指定要支持的 Windows 版本。它帮助编译器根据不同的 Windows 版本要求,进行相应的代码调整和编译设置,以确保应用程序在目标 Windows 系统上能够正确运行。

MFCApplication1.ico

  • 应用程序的图标文件,用于在 Windows 资源管理器、任务栏等位置显示应用程序的图标。当应用程序运行时,任务栏上的程序图标、窗口左上角的图标等,默认就是这个文件所指定的图标。

MFCApplication1.rc

  • 资源脚本文件,用于描述应用程序中所有资源的信息。它包含了对话框的布局、菜单的定义、图标、字符串表等资源的详细描述,是资源编辑器和编译器之间的桥梁。在编译过程中,编译器会根据这个文件来生成对应的二进制资源文件,以便应用程序在运行时能够加载和使用这些资源。

MFCApplication1.rc2

  • 辅助资源脚本文件,主要用于存放一些在 Visual Studio 的资源编辑器中无法编辑的资源,比如自定义的位图、光标等。一般情况下,它用于补充和扩展.rc文件中的资源定义。

修改标题

点击对话框,【属性】=》【描述文字】
在这里插入图片描述

插入对话框

在资源视图中选择对话框-右击选择插入

然后右击对话框,选择添加类
在这里插入图片描述

模态对话框

  • 打开后,用户只能操作该对话框,其他窗口(包括父窗口)被阻塞
  • 对话框关闭后,对象通常被销毁(资源释放)
  • 需用户立即响应的操作(如 “确定 / 取消”“设置参数”)
  • 用 DoModal() 创建,关闭时自动销毁

示例

插入一个对话框,并创建类ModalDlg , 添加static text,内容为 “模态对话框”。 在主对话框中 添加一个按钮 “模态对话框”,并双击创建处理函数。

// 在MFCApplication1Dlg.cpp 中导入ModalDlg

#include "ModalDlg.h"
void CMFCApplication1Dlg::OnBnClickedButton2()
{
	// TODO: 在此添加控件通知处理程序代码
	ModalDlg dlg;
	dlg.DoModal();
}

在这里插入图片描述

非模态对话框

  • 打开后,用户可自由切换到其他窗口(包括父窗口)操作
  • 对话框关闭后,对象可保留(需手动销毁)
  • 长期存在的辅助窗口(如 “工具栏”“属性面板”)
  • 用 Create() 创建,需手动调用 DestroyWindow() 销毁

插入一个对话框,并创建类ModalessDlg, 添加static text,内容为 ”非模态对话框”。 在主对话框中 添加一个按钮 “非模态对话框”,并双击创建处理函数。

void CMFCApplication1Dlg::OnBnClickedButton3()
{
	// TODO: 在此添加控件通知处理程序代码
	ModalessDlg* dlg = new ModalessDlg(this);

	if (dlg->Create(IDD_DIALOG2, this))
	{
		// 显示对话框
		dlg->ShowWindow(SW_SHOW);
	}
	else
	{
		// 创建失败时清理
		delete dlg;
		dlg = NULL;
	}
}

在这里插入图片描述

控件

static text

在这里插入图片描述
从工具栏中找到static text ,拖动到对话框中,选中后修改内容,可直接输入修改,也可从属性栏中修改。

添加变量
默认是不能添加的,修改修改ID,将 ID 修改为 IDC_STATIC1。
右击选择添加变量。
在这里插入图片描述
在这里插入图片描述
在类别中有两个选项, 控件(变量类型为 CStatic)、值(变量类型为CString),
添加后,在MFCApplication1Dlg.h 生成 CString m_s1;,
在MFCApplication1.cpp 中添加 初始化和数据交换绑定

CMFCApplication1Dlg::CMFCApplication1Dlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_MFCAPPLICATION1_DIALOG, pParent)
	, m_s1(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CMFCApplication1Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_STATIC1, m_s1);
}

修改值

在OnInitDialog 中添加

BOOL CMFCApplication1Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	//...
	m_s1 = "hello mfc";
	UpdateData(FALSE);
	//...
	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

其中UpdateData(FALSE)表示将变量的内容传递给控件,TRUE则相反。

若添加的时CStatic 对象,则使用SetWindowTextW

m_s2.SetWindowTextW(_T("static control"));

button

拖动按钮到对话框即可添加

绑定处理事件

添加后双击,会自动生成

BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDialogEx)
	ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
END_MESSAGE_MAP()
void CMFCApplication1Dlg::OnBnClickedButton1()
{
	// TODO: 在此添加控件通知处理程序代码
}

或者右击使用类向导添加
在这里插入图片描述

_T

在 MFC 中,_T() 是一个宏,用于实现字符串的Unicode/ANSI 兼容性,是处理字符串时非常重要的宏定义。
作用说明

  • _T(“字符串”) 会根据项目的字符集设置,自动将字符串转换为对应的编码格式:
    • 当项目使用 Unicode 字符集(默认设置)时,_T(“abc”) 等价于 L"abc"(宽字符字符串,wchar_t 类型)。
    • 当项目使用 多字节字符集 时,_T(“abc”) 等价于 “abc”(窄字符字符串,char 类型)。

使用场景

  • 在 MFC 中,很多函数都有两个版本(如 CString 的构造、MessageBox 等):
    • Unicode 版本:函数名后缀带 W(如 MessageBoxW),接收宽字符字符串。
    • ANSI 版本:函数名后缀带 A(如 MessageBoxA),接收窄字符字符串。

使用 _T() 宏后,代码可以在两种字符集下兼容编译,无需手动修改字符串格式。

CString

CString 是 MFC 中最常用的字符串类,功能强大且易用,支持 Unicode 和 ANSI 字符集,是处理字符串的核心工具。

  • 依赖项目字符集设置,默认是 Unicode(CStringW,宽字符 wchar_t),也可配置为 ANSI(CStringA,单字节 char)。
  • 通常直接使用 CString,会根据宏自动映射为 CStringW 或 CStringA。
  • 无需手动分配 / 释放内存,析构时自动释放,避免内存泄漏。
  • 可与 const char*、const wchar_t* 互转,也支持与 std::string/std::wstring 转换。

初始化与赋值

// 初始化
CString str1 = _T("Hello");  // 使用 _T 宏兼容字符集
CString str2(_T("MFC"));
CString str3;
str3 = _T("String");  // 赋值

// 从 C 字符串转换
const char* cstr = "test";
CStringA strA(cstr);  // ANSI 版本
CStringW strW(L"宽字符");  // Unicode 版本

字符串拼接

CString str = _T("Hello");
str += _T(" World");  // 结果: "Hello World"
str = str + _T("!");  // 结果: "Hello World!"

// 格式化拼接(类似 sprintf)
int num = 100;
str.Format(_T("Number: %d, String: %s"), num, _T("test"));  // 结果: "Number: 100, String: test"

长度与判空

CString str = _T("Hello");
int len = str.GetLength();  // 长度: 5(字符数,非字节数)
BOOL isEmpty = str.IsEmpty();  // 是否为空: FALSE

str.Empty();  // 清空字符串
isEmpty = str.IsEmpty();  // TRUE

比较操作

CString str1 = _T("Apple");
CString str2 = _T("apple");

// 比较(返回 0 表示相等)
int cmp = str1.Compare(str2);  // 区分大小写: 结果非 0
cmp = str1.CompareNoCase(str2);  // 不区分大小写: 结果为 0

// 包含判断
BOOL contains = str1.Find(_T("pp")) != -1;  // 是否包含 "pp": TRUE

截取与替换

CString str = _T("Hello,World");

// 截取子串(从索引 7 开始,取 5 个字符)
CString sub = str.Mid(7, 5);  // 结果: "World"

// 替换
str.Replace(_T("World"), _T("MFC"));  // 结果: "Hello,MFC"

// 移除字符
str.Remove(_T(','));  // 结果: "HelloMFC"

与标准库转换

// CString -> std::string(ANSI)
CStringA strA(_T("test"));
std::string stdStr(strA.GetBuffer());
strA.ReleaseBuffer();  // 释放缓冲区

// CString -> std::wstring(Unicode)
CStringW strW(_T("宽字符"));
std::wstring stdWstr(strW.GetBuffer());
strW.ReleaseBuffer();

数值转换

// 字符串转数值
CString strNum = _T("123.45");
int n = _ttoi(strNum);  // 123(_ttoi 兼容 Unicode/ANSI)
double d = _tstof(strNum);  // 123.45

// 数值转字符串
int num = 678;
CString str;
str.Format(_T("%d"), num);  // "678"

CString , CStringA, CStringW

类型字符集底层字符类型适用场景
CStringWUnicode(宽字符)wchar_t处理宽字符字符串(如中文、日文等多字节字符)
CStringAANSI(窄字符)char处理单字节字符串(如英文字符)
CString自适应字符集取决于宏定义根据项目设置自动映射为 CStringWCStringA

CStringA 与 CStringW 互转

// ANSI -> Unicode
CStringA strA("ANSI字符串");
CStringW strW(strA);  // 直接构造转换(内部使用 MultiByteToWideChar)

// Unicode -> ANSI
CStringW strW(L"Unicode字符串");
CStringA strA(strW);  // 直接构造转换(内部使用 WideCharToMultiByte)

与 C 风格字符串互转

// CStringA <-> const char*
CStringA strA("test");
const char* cstrA = strA.GetBuffer();  // 获取 char* 指针
strA.ReleaseBuffer();  // 用完后释放

// CStringW <-> const wchar_t*
CStringW strW(L"测试");
const wchar_t* cstrW = strW.GetBuffer();  // 获取 wchar_t* 指针
strW.ReleaseBuffer();

与标准库字符串互转

// CStringA <-> std::string
CStringA strA("hello");
std::string stdStr(strA.GetBuffer());
strA.ReleaseBuffer();

// CStringW <-> std::wstring
CStringW strW(L"世界");
std::wstring stdWstr(strW.GetBuffer());
strW.ReleaseBuffer();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值