TMenuItem 動態建立 + OnClick 事件指派
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);
};
#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/FindClose | VCL 封裝的檔案搜尋 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) 且未手動釋放 → 記憶體洩漏。
動態選單是實現「最近開啟檔案」、「外掛功能選單」、「使用者自訂選單」等功能的基石。