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

C++Builder 動態建立選單與事件綁定:從檔案系統載入選單項

     編輯:VC 教學

核心技術:TMenuItem 動態建立 + OnClick 事件指派

完整實作代碼

標頭檔 (Unit1.h)


class TForm1 : public TForm
{
__published:
    TButton *Button1;
    TPopupMenu *PopupMenu1;
    TRichEdit *RichEdit1;
    void __fastcall Button1Click(TObject *Sender);
    void __fastcall FormCreate(TObject *Sender);
private:
    TPoint MousePos;      // 滑鼠位置
    int PopCount;         // 當前選單項數
    void __fastcall MyClick(TObject *Sender); // 統一事件處理器
public:
    __fastcall TForm1(TComponent* Owner);
};

實作檔 (Unit1.cpp)


#include 
#pragma hdrstop
#include "Unit1.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
    // 1. 清除舊選單項
    for (int i = PopCount - 1; i >= 0; i--)
        PopupMenu1->Items->Delete(i);

    // 2. 掃描目錄建立選單
    TSearchRec Sr;
    TMenuItem *NewItem;
    GetCursorPos(&MousePos); // 記錄彈出位置

    if (FindFirst("C:\\Program Files\\3LTyping\\data\\*.txt", 0, Sr) == 0) {
        do {
            NewItem = new TMenuItem(PopupMenu1); // Owner = PopupMenu1 自動釋放
            String name = Sr.Name;
            name.SetLength(name.Length() - 4); // 移除 ".txt"
            NewItem->Caption = name;
            NewItem->OnClick = MyClick; // 關鍵:指派統一處理器
            PopupMenu1->Items->Add(NewItem);
        } while (FindNext(Sr) == 0);
        FindClose(Sr);
    }

    PopCount = PopupMenu1->Items->Count;
    PopupMenu1->Popup(MousePos.x, MousePos.y); // 在滑鼠位置彈出
}

void __fastcall TForm1::MyClick(TObject *Sender)
{
    TMenuItem *item = dynamic_cast(Sender);
    if (!item) return;

    // 載入對應文件到 RichEdit
    Caption = item->Caption;
    RichEdit1->PlainText = true;
    RichEdit1->Lines->LoadFromFile(
        "C:\\Program Files\\3LTyping\\data\\" + item->Caption + ".txt");
}

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    PopCount = 0;
}

關鍵技術點解析

技術點說明
new TMenuItem(PopupMenu1)Owner 機制:PopupMenu1 銷毀時自動釋放所有子選單項,無需手動 delete。
OnClick = MyClick事件指派:將統一處理器指派給每個動態項,Sender 參數識別來源。
FindFirst/FindNext/FindCloseVCL 封裝的檔案搜尋 API,支援萬用字元。
PopupMenu->Popup(x, y)在指定螢幕座標顯示彈出選單。

擴展:主選單 (TMainMenu) 動態建立


void __fastcall TForm1::BuildMainMenu()
{
    // 清除現有頂層項
    while (MainMenu1->Items->Count > 0)
        MainMenu1->Items->Delete(0);

    // 新增「檔案」主項
    TMenuItem *fileMenu = new TMenuItem(MainMenu1);
    fileMenu->Caption = "檔案(&F)";
    MainMenu1->Items->Add(fileMenu);

    // 子項:開啟
    TMenuItem *openItem = new TMenuItem(fileMenu);
    openItem->Caption = "開啟(&O)...";
    openItem->ShortCut = TextToShortCut("Ctrl+O");
    openItem->OnClick = FileOpenClick;
    fileMenu->Add(openItem);

    // 子項:退出
    TMenuItem *exitItem = new TMenuItem(fileMenu);
    exitItem->Caption = "退出(&X)";
    exitItem->OnClick = FileExitClick;
    fileMenu->Add(exitItem);
}

進階:動態選單項圖示、啟用/停用、勾選狀態


NewItem->ImageIndex = 0;           // 關聯 TImageList
NewItem->Enabled = CanOpenFile();  // 動態啟用
NewItem->Checked = IsCurrentFile(); // 勾選狀態
NewItem->RadioItem = true;         // 單選組
NewItem->GroupIndex = 1;           // 單選組索引

記憶體管理提醒

  • ✅ 以容器 (TPopupMenu, TMainMenu, TMenuItem) 為 Owner,自動生命週期管理。
  • ❌ 避免 new TMenuItem(NULL) 且未手動釋放 → 記憶體洩漏。
  • ⚠️ 大量動態項目 (數百+) 可能影響選單彈出速度,考慮虛擬化或分頁。

動態選單建立流程圖

動態選單是實現「最近開啟檔案」、「外掛功能選單」、「使用者自訂選單」等功能的基石。

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