【MFC应用创建后核心文件详解】项目名.cpp、项目名.h、项目名Dlg.cpp 和 项目名Dlg.h 的区别与作用

大家好,今天我们来聊聊MFC(Microsoft Foundation Classes)编程中的入门知识。作为一个初学者(小白),你可能刚用Visual Studio创建了一个MFC应用项目,看到生成的几个文件:比如项目名为"MyApp",那么就有 MyApp.cpp、MyApp.h、MyAppDlg.cpp 和 MyAppDlg.h。这些文件看起来很相似,但作用完全不同。今天我就用最简单的语言帮你搞清楚它们的区别和用途,让你能轻松读懂并上手修改代码。

这篇文章适合零基础的小白,如果你对C++有基本了解(比如知道什么是头文件和源文件),那就更好了。咱们一步步来,先从MFC是什么说起,然后逐个文件分析,最后总结区别。走起!

先了解MFC和项目创建

MFC是微软提供的一个C++类库,用来开发Windows图形界面程序(比如带按钮、文本框的软件)。用Visual Studio创建MFC应用时,选择"基于对话框"的模板(最常见的一种),它会自动生成几个核心文件。这些文件是项目的"骨架",负责启动程序、显示窗口等。

假设你的项目名叫"MyApp",生成的四个文件就是:

  • MyApp.cpp
  • MyApp.h
  • MyAppDlg.cpp
  • MyAppDlg.h

这些文件分成两组:一组是"应用类"(负责整个程序的运行),一组是"对话框类"(负责主窗口的显示和交互)。下面我们逐个拆解。

1. 项目名.cpp(例如 MyApp.cpp):程序的"主引擎"

作用

这个文件是整个MFC应用的入口点(程序启动的地方)。它定义了一个继承自CWinApp的类(比如CMyAppApp),负责初始化程序、处理消息循环(比如用户点击鼠标时怎么响应),以及退出程序。

简单说,它就像汽车的引擎:启动时点火,运行中保持转动,停车时熄火。没有这个文件,你的程序就跑不起来。

典型内容

  • 包含一个全局对象:CMyAppApp theApp;(这是程序的起点)。
  • InitInstance()函数:在这里初始化主窗口(通常是调用对话框类来显示窗口)。
  • 其他函数:如处理命令行参数等,但小白可以先忽略。

示例代码(简化版)

cpp 复制代码
// MyApp.cpp : 定义应用程序的类行为。
#include "stdafx.h"
#include "MyApp.h"
#include "MyAppDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMyAppApp
BEGIN_MESSAGE_MAP(CMyAppApp, CWinApp)
    ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()

CMyAppApp::CMyAppApp() {
    // TODO: 在此处添加构造代码
}

CMyAppApp theApp;  // 全局对象,程序入口

BOOL CMyAppApp::InitInstance() {
    // 创建主对话框
    CMyAppDlg dlg;
    m_pMainWnd = &dlg;
    INT_PTR nResponse = dlg.DoModal();
    if (nResponse == IDOK) {
        // 用户点击OK
    } else if (nResponse == IDCANCEL) {
        // 用户点击取消
    }
    return FALSE;  // 不需要继续消息循环
}

小白提示

  • 你很少需要改这个文件,除非要添加自定义初始化。
  • 读懂它:找InitInstance(),里面会调用对话框类来显示窗口。

2. 项目名.h(例如 MyApp.h):应用类的"蓝图"

作用

这是MyApp.cpp的头文件(header file),里面声明了应用类的结构(比如类名、成员函数)。它不包含实际代码实现,只告诉编译器"这个类长什么样"。

简单说,它就像建筑蓝图:描述引擎(MyApp.cpp)的设计,但不实际建造。

典型内容

  • 类声明:class CMyAppApp : public CWinApp
  • 消息映射宏:DECLARE_MESSAGE_MAP()
  • 可能有一些成员变量声明。

示例代码(简化版)

cpp 复制代码
// MyApp.h : MyApp 应用程序的主头文件
#pragma once

#ifndef __AFXWIN_H__
    #error "在包含此文件之前包含"stdafx.h"以生成 PCH 文件"
#endif

#include "resource.h"  // 主符号

class CMyAppApp : public CWinApp {
public:
    CMyAppApp();

// 重写
public:
    virtual BOOL InitInstance();

// 实现
    DECLARE_MESSAGE_MAP()
};

小白提示

  • 头文件通常用#pragma once防止重复包含。
  • 如果你在MyApp.cpp中添加新函数,这里要先声明它。

3. 项目名Dlg.cpp(例如 MyAppDlg.cpp):主窗口的"实现代码"

作用

这个文件实现主对话框(窗口)的逻辑。MFC的"基于对话框"应用,主窗口就是一个对话框(CDialog的子类,比如CMyAppDlg)。这里处理窗口的显示、按钮点击事件、数据处理等。

简单说,它就像汽车的仪表盘和座位:用户看到和互动的部分都在这里。

典型内容

  • 构造函数:初始化对话框。
  • OnInitDialog():窗口显示时执行的初始化。
  • 事件处理函数:比如按钮点击时调用OnBnClickedButton1()
  • 数据交换:DoDataExchange()用于绑定控件和变量。

示例代码(简化版)

cpp 复制代码
// MyAppDlg.cpp : 实现文件
#include "stdafx.h"
#include "MyApp.h"
#include "MyAppDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(CMyAppDlg, CDialogEx)

CMyAppDlg::CMyAppDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_MYAPP_DIALOG, pParent) {
    // 初始化成员变量
}

CMyAppDlg::~CMyAppDlg() {}

void CMyAppDlg::DoDataExchange(CDataExchange* pDX) {
    CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CMyAppDlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
END_MESSAGE_MAP()

BOOL CMyAppDlg::OnInitDialog() {
    CDialogEx::OnInitDialog();
    // 添加初始化代码,比如设置窗口标题
    SetWindowText(_T("我的MFC应用"));
    return TRUE;
}

小白提示

  • 这里是你最常修改的地方:添加按钮事件、处理用户输入。
  • 用资源编辑器添加控件后,这里会自动生成相应代码。

4. 项目名Dlg.h(例如 MyAppDlg.h):对话框类的"蓝图"

作用

这是MyAppDlg.cpp的头文件,声明对话框类的结构、成员变量和函数。同样,只声明不实现。

简单说,它是仪表盘的蓝图,描述MyAppDlg.cpp的框架。

典型内容

  • 类声明:class CMyAppDlg : public CDialogEx
  • 成员变量:比如控件变量CButton m_Button;
  • 函数声明:如事件处理函数。

示例代码(简化版)

cpp 复制代码
// MyAppDlg.h : 头文件
#pragma once

class CMyAppDlg : public CDialogEx {
    // 构造
public:
    CMyAppDlg(CWnd* pParent = NULL);  // 标准构造函数
    virtual ~CMyAppDlg();

    // 对话框数据
    enum { IDD = IDD_MYAPP_DIALOG };

protected:
    virtual void DoDataExchange(CDataExchange* pDX);  // DDX/DDV 支持

    // 生成的消息映射函数
    virtual BOOL OnInitDialog();
    afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
    afx_msg void OnPaint();
    afx_msg HCURSOR OnQueryDragIcon();
    DECLARE_MESSAGE_MAP()
};

小白提示

  • 添加新控件或事件时,先在这里声明变量或函数,然后在.cpp中实现。

这些文件的区别总结

  • 项目名.cpp 和 项目名.h:焦点在"应用整体"。.cpp是实现(引擎启动),.h是声明(蓝图)。它们管理程序的生命周期,不直接处理用户界面。
  • 项目名Dlg.cpp 和 项目名Dlg.h:焦点在"主窗口"。.cpp是实现(窗口逻辑和事件),.h是声明(窗口结构)。它们处理用户交互,是你开发时最常碰的文件。
  • 总体区别
    • .cpp 文件:包含实际代码(函数体),负责"做事"。
    • .h 文件:只包含声明(类、函数签名),负责"描述"。
    • 应用类(不带Dlg) vs. 对话框类(带Dlg):前者管程序运行,后者管窗口显示。
  • 为什么分开:这是C++的规范,便于代码组织和复用。头文件可以被多个.cpp包含,而不重复代码。

小白如何读懂和上手

  1. 先编译运行:创建项目后,直接F5运行,看看默认窗口是什么样。
  2. 修改实验 :在MyAppDlg.cpp的OnInitDialog()里加一句MessageBox(_T("Hello MFC!"));,运行看效果。
  3. 用工具:Visual Studio的类视图(Class View)可以帮你快速导航这些文件。
  4. 常见错误:忘了包含头文件?编译会报错。事件没映射?按钮点击没反应。
  5. 进阶:学学MFC的消息映射(BEGIN_MESSAGE_MAP),这是核心机制。

MFC虽然老派,但适合学习Windows编程基础。实践是王道,多改代码多调试,你很快就上手了!如果有问题,欢迎评论区留言。

参考资料:MSDN MFC文档、Visual Studio帮助。

点赞、收藏、关注一波,谢谢支持!下期见~

相关推荐
listhi5206 小时前
C# 操作 Excel
c#·excel·mfc
风和先行6 小时前
MFC应用防止多开
c++·mfc
hansang_IR6 小时前
【题解 | 两种做法】洛谷 P4208 [JSOI2008] 最小生成树计数 [矩阵树/枚举]
c++·算法·dfs·题解·枚举·最小生成树·矩阵树定理
要做朋鱼燕6 小时前
【C++ 】string类:深拷贝与浅拷贝解析
java·开发语言·c++·职场和发展
一只鱼^_8 小时前
365. 水壶问题(详解)
java·javascript·c++·leetcode·线性回归
Dream it possible!8 小时前
LeetCode 面试经典 150_滑动窗口_串联所有单词的子串(32_30_C++_困难)(滑动窗口:控制起点和滑动距离)
c++·leetcode·面试·滑动窗口
Q741_1478 小时前
C++ 面试高频考点 力扣 35. 搜索插入位置 二分查找 左右端点查找 题解 每日一题
c++·算法·leetcode·面试·二分查找
saddhu.8 小时前
C++ 快速复习指南(上半部分)
java·c++·算法