首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

C++Builder MDI 應用程式開發全攻略:架構、模板與多文件編輯器實戰

     編輯:VC 教學

MDI 架構三大視窗角色

角色類別/屬性職責
框架視窗FormStyle = fsMDIForm主視窗:選單列、工具列、狀態列、管理子視窗
客戶區視窗系統自動建立 (MDIClient)容納所有子視窗,處理平鋪/層疊/排列命令
子視窗FormStyle = fsMDIChild文件視窗:各自獨立的編輯區、標題列、系統選單

使用 MDI 專案模板快速建立

  1. File → New → Projects → MDI Application
  2. 自動生成:MainForm (fsMDIForm) + ChildForm (fsMDIChild)。
  3. 直接編譯執行,即具備:新建/開啟/關閉子視窗、平鋪/層疊/排列圖示、視窗清單選單。

實戰:多格式文件編輯器 (支援 RTF/純文字、工具列、列印)

1. 主表單設計

  • TMainMenu:檔案(新建/開啟/儲存/另存/列印/結束)、編輯(剪貼)、視窗(平鋪/層疊/排列/清單)、說明。
  • TToolBar + TActionList:對應選單命令,Action 統一邏輯。
  • TStatusBar:顯示游標位置、修改狀態、編碼格式。

2. 子表單核心元件


// ChildForm.h
__published:
    TRichEdit *RichEdit1; // 支援 RTF/純文字
    TActionList *ActionList1;
    // 儲存/列印等 Action
private:
    String FFileName;
    bool FModified;
public:
    __fastcall TChildForm(TComponent* Owner);
    bool __fastcall LoadFile(const String &fileName);
    bool __fastcall SaveFile(const String &fileName = "");
    void __fastcall UpdateTitle();

3. 關鍵功能實作

新建文件 (主表單)


void __fastcall TMainForm::ActionNewExecute(TObject *Sender)
{
    TChildForm *child = new TChildForm(this); // Owner = MainForm
    child->Caption = "未命名 " + IntToStr(MDIChildCount + 1);
    child->Show();
}

開啟文件 (子表單)


bool __fastcall TChildForm::LoadFile(const String &fileName)
{
    try {
        RichEdit1->PlainText = (ExtractFileExt(fileName).LowerCase() == ".txt");
        RichEdit1->Lines->LoadFromFile(fileName);
        FFileName = fileName;
        FModified = false;
        UpdateTitle();
        return true;
    }
    catch (...) { return false; }
}

void __fastcall TChildForm::UpdateTitle()
{
    Caption = ExtractFileName(FFileName);
    if (FFileName.IsEmpty()) Caption = "未命名";
    if (FModified) Caption = "*" + Caption;
}

儲存/另存新檔


bool __fastcall TChildForm::SaveFile(const String &fileName)
{
    String fn = fileName.IsEmpty() ? FFileName : fileName;
    if (fn.IsEmpty()) return SaveAs(); // 彈出對話框
    try {
        RichEdit1->Lines->SaveToFile(fn);
        FFileName = fn;
        FModified = false;
        UpdateTitle();
        return true;
    }
    catch (...) { return false; }
}

列印支援


void __fastcall TChildForm::ActionPrintExecute(TObject *Sender)
{
    TPrintDialog *pd = new TPrintDialog(this);
    if (pd->Execute()) {
        RichEdit1->Print(FFileName.IsEmpty() ? "未命名文件" : FFileName);
    }
    delete pd;
}

修改狀態追蹤


void __fastcall TChildForm::RichEdit1Change(TObject *Sender)
{
    if (!FModified) {
        FModified = true;
        UpdateTitle();
    }
    // 更新狀態列游標位置
    StatusBar1->Panels->Items[0]->Text = 
        "行: " + IntToStr(RichEdit1->CaretPos.y + 1) + 
        "  欄: " + IntToStr(RichEdit1->CaretPos.x + 1);
}

MDI 進階技巧

需求實現方式
單一實例開啟文件遍歷 MDIChildren 比對 FFileName,存在則 BringToFront()
關閉確認子表單 OnCloseQuery 檢查 FModified,提示儲存
視窗狀態持久化主表單關閉時寫入註冊表/INI:子視窗位置、大小、開啟文件清單
拖放開啟主表單 OnDropFiles 處理拖入文件
多執行緒載入大文件背景執行緒 LoadFromFile,完成後 Synchronize 指派給 RichEdit

常見問題

  • ❌ 子表單關閉後記憶體洩漏 → 設定 OnClose Action = caFree。
  • ❌ 選單合併錯誤 → 子表單選單 Menu 屬性設為 MainMenu1,VCL 自動合併。
  • ❌ 工具列按鈕不啟用 → Action 的 OnUpdate 檢查 ActiveMDIChild 是否存在。

MDI 架構圖

C++Builder 的 MDI 支援極其成熟,善用模板與 Action 架構,可在極短時間內構建專業級多文件應用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved