MFC 面经系列(一):类层次、绘图机制与框架对比
是的,这年头还有人在面MFC,问的我一问三不知,真的脚趾抠地太尬了,平时开发的时候还真没思考过这些问题,面完我反手记录面试问题整理答案,面试虽败,但是博文素材有啦,分享给需要的朋友们。
MFC面经系列:
MFC 面经系列(二):刷新机制、消息流程与控件使用-CSDN博客
在 Windows 桌面开发领域,MFC(Microsoft Foundation Classes)作为经典框架,始终是面试中的高频考点。本文整理了 4 个核心面试问题,涵盖 MFC 类层次结构、绘图机制差异及框架对比,帮助开发者深入理解 MFC 的设计思想与实践应用。
一、MFC 类层次结构
MFC 通过面向对象思想对 Win32 API 进行封装,形成了层次清晰的类体系,核心类及其关系如下:

-
根类:CObject
MFC 中绝大多数类的基类,提供了序列化、运行时类型信息(RTTI)、动态创建等基础功能。 -
应用程序类:CWinApp
派生自 CWinThread,代表整个应用程序,负责程序的初始化、消息循环管理和退出。核心函数InitInstance()是程序入口点。 -
窗口类:CWnd
封装了 Win32 窗口的核心功能(句柄、消息处理等),是所有窗口类的基类。派生类包括:CFrameWnd:框架窗口类(如主窗口);CDialog:对话框类;CView:视图类(负责数据显示)。
-
文档 / 视图类:CDocument 与 CView
遵循 MVC 模式,CDocument管理数据,CView负责数据可视化,二者通过文档模板(CDocTemplate)关联。 -
设备上下文类:CDC
封装了 GDI 绘图功能,派生类CPaintDC(用于WM_PAINT消息)、CClientDC(客户端区域绘图)等简化了绘图操作。
类层次简化示意图:
CObject → CCmdTarget → CWinThread → CWinApp
CObject → CCmdTarget → CWnd → CFrameWnd/CDialog/CView
二、OnPaint 与 OnDraw 的区别
MFC 中OnPaint和OnDraw是绘图相关的核心函数,二者分工明确但易混淆,关键区别如下:
| 维度 | OnPaint() | OnDraw() |
|---|---|---|
| 所属类 | CWnd及其派生类(窗口类) | CView及其派生类(视图类) |
| 功能 | 响应WM_PAINT消息的处理函数 | 实际执行绘图逻辑的虚函数 |
| 调用关系 | 主动调用OnDraw() | 被OnPaint()调用,无法直接响应消息 |
| 设备上下文 | 通过CPaintDC获取 DC | 接收CDC*参数直接操作 |
| 重载影响 | 若重载需手动调用OnDraw() | 直接重载即可实现自定义绘图 |
代码示例:
// CView派生类中的默认实现
void CMyView::OnPaint() {
CPaintDC dc(this); // 自动管理BeginPaint/EndPaint
OnDraw(&dc); // 委托OnDraw执行绘图
}
// 实际绘图逻辑
void CMyView::OnDraw(CDC* pDC) {
// 从文档获取数据并绘制
CMyDoc* pDoc = GetDocument();
pDC->TextOut(10, 10, pDoc->GetData()); // 绘制文本
}
关键点:
OnPaint是窗口级别的消息处理入口,负责准备绘图环境(如 DC);OnDraw是视图级别的绘图实现,专注于数据可视化;- 若手动重载
OnPaint而未调用OnDraw,会导致OnDraw失效。
三、OnDraw 的作用机制
OnDraw是 MFC 视图类绘图的核心函数,其工作流程与设计思想如下:
-
触发流程
窗口无效(如被遮挡、大小改变)→ 系统发送`WM_PAINT` → `OnPaint()`被调用 → 创建`CPaintDC` → 调用`OnDraw(CDC*)` → 完成绘图 -
设备上下文(DC)
OnDraw通过CDC*参数操作绘图接口(如TextOut、LineTo、BitBlt),无需关注 DC 的创建与释放(由CPaintDC自动管理)。 -
与文档的交互
遵循文档 - 视图分离原则,OnDraw通常从关联的CDocument对象获取数据并渲染,实现 “数据与显示分离”:void CMyView::OnDraw(CDC* pDC) { CMyDoc* pDoc = GetDocument(); // 获取关联文档 if (pDoc) { // 绘制文档中的数据 CString data = pDoc->m_strData; pDC->TextOut(0, 0, data); } } -
绘图优化
OnDraw仅需绘制无效区域(由CPaintDC自动限定),减少不必要的绘制操作,提升性能。
四、MFC 与 Duilib 的区别
MFC 和 Duilib 是 Windows 平台下两种不同设计理念的 UI 框架,核心差异如下:
| 维度 | MFC | Duilib |
|---|---|---|
| 技术原理 | 封装 Win32 API,基于句柄(HWND)控件 | 基于 DirectUI 理念,无句柄设计,统一绘制 |
| 界面布局 | 依赖.rc 资源文件,可视化设计弱 | 基于 XML 配置,支持标签式布局,逻辑与 UI 分离 |
| 自定义能力 | 受系统主题限制,重绘成本高 | 完全自定义,支持皮肤、动画、透明效果 |
| 资源消耗 | 较高(多窗口句柄) | 较低(无句柄开销) |
| 适用场景 | 系统工具、工业软件、遗留项目 | 客户端软件(如聊天工具、播放器)、高自定义 UI 场景 |
| 开发效率 | 需手动处理消息循环,代码繁琐 | 简化消息处理,XML 布局可实时预览 |
总结:
MFC 适合需深度集成系统功能、对界面要求不高的场景;Duilib 专注于高效开发精美、自定义程度高的 UI,更符合现代桌面应用的视觉需求。
结语
本文整理了 MFC 类层次、绘图机制及框架对比的核心知识点,后续将继续分享 Win32 刷新机制、MFC 消息响应全流程及控件使用等问题。掌握这些基础原理,不仅能应对面试,更能在实际开发中合理选择框架、优化程序性能。
MFC面经系列:
更多推荐
所有评论(0)