zcxadsqew 发表于 2025-7-4 09:31:56

MFC 项目保存与加载

用MFC创建了应用程序。想实现的功能:与现在的一些软件一样,在点击保存项目时可以保存当前项目中所有数据,包括文本框中的输入的数据,以及计算的结果数据,下一次打开该项目,数据能自动加载。

FishC 发表于 2025-7-4 09:33:37

在 MFC 中实现项目保存与加载功能,推荐使用**文档-视图架构**(Document/View)。以下是简明实现步骤:

---

### 1. 在文档类存储数据
在 `CYourDoc.h` 中声明变量存储数据:
class CYourDoc : public CDocument {
public:
    CString m_strInput;   // 存储文本框数据
    doublem_dResult;    // 存储计算结果
    // ... 其他数据成员
};

---

### 2. 重写文档序列化函数
在 `CYourDoc.cpp` 中实现 `Serialize()`:
void CYourDoc::Serialize(CArchive& ar) {
    if (ar.IsStoring()) { // 保存数据
      ar << m_strInput;
      ar << m_dResult;
    } else { // 加载数据
      ar >> m_strInput;
      ar >> m_dResult;
    }
}

---

### 3. 视图类与文档交互
在视图类 `CYourView.cpp` 中:
#### (1) 初始化时加载数据
void CYourView::OnInitialUpdate() {
    CView::OnInitialUpdate();
    CYourDoc* pDoc = GetDocument();
   
    // 将文档数据加载到控件
    m_editInput.SetWindowText(pDoc->m_strInput);
   
    CString strResult;
    strResult.Format(_T("%.2f"), pDoc->m_dResult);
    m_editResult.SetWindowText(strResult);
}

#### (2) 用户输入时更新文档
void CYourView::OnEnChangeEditInput() {
    CYourDoc* pDoc = GetDocument();
   
    // 更新文档数据
    CString strInput;
    m_editInput.GetWindowText(strInput);
    pDoc->m_strInput = strInput;
   
    pDoc->SetModifiedFlag(TRUE); // 标记文档已修改
}

#### (3) 计算结果后保存到文档
void CYourView::OnBnClickedCalculate() {
    // ... 执行计算逻辑
    double result = CalculateSomething();
   
    // 更新文档
    CYourDoc* pDoc = GetDocument();
    pDoc->m_dResult = result;
    pDoc->SetModifiedFlag(TRUE);
}

---

### 4. 关键点说明
1. **自动保存提示**
   调用 `SetModifiedFlag(TRUE)` 后,关闭文档时 MFC 会自动弹出保存提示。

2. **文件操作**
   - 点击保存:自动调用 `Serialize()` 存储数据
   - 点击打开:自动调用 `Serialize()` 加载数据
   - 文件扩展名需在 `CYourApp::InitInstance()` 中注册

3. **控件变量**
   通过 ClassWizard 为编辑框添加控件变量(如 `m_editInput`)。

---

### 示例工作流程
1. 用户输入数据 → 实时更新到 `CYourDoc`
2. 用户点击保存 → MFC 自动触发 `Serialize()` 保存所有数据
3. 重新打开文件 → `Serialize()` 加载数据 → `OnInitialUpdate()` 初始化界面

---

通过此设计,MFC 会自动处理文件对话框、读写流程等底层操作,您只需专注数据存储与界面同步。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

行客 发表于 2025-7-5 16:01:01

下面我将为你介绍如何在 MFC 应用程序里达成项目数据的保存与加载功能。我会分步骤说明实现方法,并且给出关键代码片段。
1. 数据结构设计
首先要设计一个类,用来保存项目的所有数据。
class CMyProjectData
{
public:
    CString m_strText1;      // 文本框1的数据
    CString m_strText2;      // 文本框2的数据
    double m_dResult1;       // 计算结果1
    double m_dResult2;       // 计算结果2
    // 可以根据实际需求添加更多的数据成员

public:
    // 序列化函数 - 把数据保存到归档文件
    void Serialize(CArchive& ar);
};

void CMyProjectData::Serialize(CArchive& ar)
{
    if (ar.IsStoring())
    {
      // 保存数据
      ar << m_strText1;
      ar << m_strText2;
      ar << m_dResult1;
      ar << m_dResult2;
    }
    else
    {
      // 加载数据
      ar >> m_strText1;
      ar >> m_strText2;
      ar >> m_dResult1;
      ar >> m_dResult2;
    }
}
2. 在文档类中添加项目数据成员
要在应用程序的文档类(继承自CDocument)里添加CMyProjectData对象。
class CMyProjectDoc : public CDocument
{
protected:
    CMyProjectData m_projectData;

public:
    // 访问项目数据的接口
    CMyProjectData& GetProjectData() { return m_projectData; }
    const CMyProjectData& GetProjectData() const { return m_projectData; }

    // 重写序列化函数
    virtual void Serialize(CArchive& ar);
};

void CMyProjectDoc::Serialize(CArchive& ar)
{
    // 调用项目数据的序列化函数
    m_projectData.Serialize(ar);
}
3. 实现保存和加载功能
保存项目
在视图类或者对话框类中,可以借助文档对象来保存项目。
void CMyProjectView::OnFileSave()
{
    // 获取文档对象
    CMyProjectDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    // 更新文档中的数据
    CString strText1, strText2;
    GetDlgItemText(IDC_EDIT1, strText1);
    GetDlgItemText(IDC_EDIT2, strText2);
   
    pDoc->GetProjectData().m_strText1 = strText1;
    pDoc->GetProjectData().m_strText2 = strText2;
   
    // 触发文档的保存操作
    pDoc->OnSaveDocument(NULL);
}
加载项目
在视图类或者对话框类中,可以通过文档对象加载项目。
void CMyProjectView::OnInitialUpdate()
{
    CView::OnInitialUpdate();
   
    // 加载文档数据
    LoadDocumentData();
}

void CMyProjectView::LoadDocumentData()
{
    // 获取文档对象
    CMyProjectDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    // 从文档中获取数据
    const CMyProjectData& data = pDoc->GetProjectData();

    // 更新界面
    SetDlgItemText(IDC_EDIT1, data.m_strText1);
    SetDlgItemText(IDC_EDIT2, data.m_strText2);
   
    // 显示计算结果
    CString strResult;
    strResult.Format(_T("%.2f"), data.m_dResult1);
    SetDlgItemText(IDC_STATIC_RESULT1, strResult);
   
    strResult.Format(_T("%.2f"), data.m_dResult2);
    SetDlgItemText(IDC_STATIC_RESULT2, strResult);
}
4. 更新计算结果
在计算完成之后,要更新文档中的数据。
void CMyProjectView::CalculateResults()
{
    // 获取输入数据
    CString strText1, strText2;
    GetDlgItemText(IDC_EDIT1, strText1);
    GetDlgItemText(IDC_EDIT2, strText2);

    // 进行计算
    double dValue1 = _tstof(strText1);
    double dValue2 = _tstof(strText2);
    double dResult1 = dValue1 + dValue2;
    double dResult2 = dValue1 * dValue2;

    // 更新文档中的数据
    CMyProjectDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
   
    pDoc->GetProjectData().m_dResult1 = dResult1;
    pDoc->GetProjectData().m_dResult2 = dResult2;
   
    // 标记文档为已修改
    pDoc->SetModifiedFlag();

    // 显示计算结果
    CString strResult;
    strResult.Format(_T("%.2f"), dResult1);
    SetDlgItemText(IDC_STATIC_RESULT1, strResult);
   
    strResult.Format(_T("%.2f"), dResult2);
    SetDlgItemText(IDC_STATIC_RESULT2, strResult);
}




5. 添加菜单和工具栏支持
你可以在资源编辑器里添加 "保存项目" 和 "打开项目" 菜单项,并且关联到标准的 MFC 命令(ID_FILE_SAVE和ID_FILE_OPEN)。MFC 会自动处理这些命令,调用文档类的OnSaveDocument和OnOpenDocument函数。
实现要点
数据结构:CMyProjectData类负责保存项目的所有数据,并且实现Serialize函数。
文档序列化:文档类重写Serialize函数,调用项目数据的序列化函数。
数据同步:在保存项目前,要把界面数据同步到文档;加载项目后,要把文档数据同步到界面。
修改标记:数据发生变化时,调用SetModifiedFlag(),这样 MFC 就能提示用户保存修改。
通过上述步骤,你的 MFC 应用程序就能实现项目数据的保存和加载功能了。
页: [1]
查看完整版本: MFC 项目保存与加载