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

C++ Builder 工具列主選單自訂快捷鍵解決方案:禁用系統自動熱鍵並啟用 TActionList

     編輯:關於C++

將 MainMenu 放入 ToolBar 後,系統會自動為選單項加入熱鍵(英文首字母底線、中文後綴 (Y)(Z)),導致開發者自訂的快捷鍵 (如 Ctrl+A、F1) 失效。即使設定 AutoHotkeys=maManual 也無效。本文整理兩位專家的解決方案:以自建 TPopupMenu 替換系統臨時選單,並配合 TActionList 實現真正的自訂快捷鍵。

問題根因分析

運行時 TToolBar 並非直接使用設計時的 MainMenu,而是動態 new 一個 TPopupMenu,其 AutoHotkeys 預設為 maAutomatic,且無法從外部存取修改。此臨時選單會自動為項目添加熱鍵字元,覆蓋開發者設定的 ShortCut 屬性。

方案一:自建 TPopupMenu 替換系統選單 (JSP 大神版)

在表單建構函式中遍歷 ToolBar 按鈕,將 MenuItem 移至自建的 TPopupMenu 並設為 DropdownMenu:

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
    for (int n = 0; n < ToolBar1->ButtonCount; n++) {
        TToolButton *Btn = ToolBar1->Buttons[n];
        if (Btn->DropdownMenu != NULL) {
            Btn->MenuItem = NULL; // 已有 DropdownMenu,清除 MenuItem
        } else if (Btn->MenuItem != NULL) {
            TMenuItem *Item = Btn->MenuItem;
            TPopupMenu *Menu = new TPopupMenu(this);
            Menu->AutoHotkeys = maManual; // 關鍵:禁用自動熱鍵
            Btn->DropdownMenu = Menu;     // 替換為自建選單

            // 同步原 MainMenu 的外觀屬性
            if (Item->GetParentMenu()) {
                Menu->BiDiMode = Item->GetParentMenu()->BiDiMode;
                Menu->Images = Item->GetParentMenu()->Images;
            }
            Menu->HelpContext = Item->HelpContext;
            Menu->TrackButton = tbLeftButton;

            // 將原選單項目移至新選單 (逆序插入保持順序)
            for (int i = Item->Count - 1; i >= 0; i--) {
                TMenuItem *Item1 = Item->Items[i];
                Item->Delete(i);
                Menu->Items->Insert(0, Item1);
            }
        }
    }
}

此法徹底移除系統自動熱鍵,但僅解決「不顯示多餘熱鍵」,原設定的 ShortCut 仍不生效(Ctrl+字母、F鍵 類型)。

方案二:TActionList 實現真正的自訂快捷鍵

TActionList 的 Action 可定義 ShortCut 並觸發 OnExecute。將選單項的 OnClick 邏輯轉移至對應 Action 的 OnExecute,並設定相同快捷鍵:

  1. 設計時雙擊 ActionList1,新增 Action (如 ActRedo)。
  2. 設定 ActRedo->ShortCut = Ctrl+R。
  3. 設定選單項 RedoMenu->ShortCut = Ctrl+R (僅為顯示提示)。
  4. 在 ActRedo->OnExecute 中呼叫 RedoMenu->Click();。
void __fastcall TForm1::ActRedoExecute(TObject *Sender) {
    RedoMenu->Click(); // 觸發原選單項邏輯
}

完整工作流程

  1. 在 FormCreate 或建構函式執行方案一程式碼,移除系統自動熱鍵。
  2. 為每個需快捷鍵的功能建立 Action,設定 ShortCut 並實作 OnExecute 呼叫對應選單項 Click()。
  3. 選單項保留 ShortCut 顯示 (給使用者看),實際觸發由 Action 接管。

關鍵優勢

  • 全局生效:Action 快捷鍵在表單焦點時全局響應,不受選單可見性影響。
  • 類型無限制:支援 Ctrl+字母、Shift+字母、F1-F12、Ctrl+Alt+字母 等任意組合。
  • 邏輯集中:命令邏輯集中在 Action,選單項、工具列按鈕、快捷鍵共享同一實作。
  • 設計時可視化:ActionList 編輯器直觀管理所有命令與快捷鍵。

注意事項

  • 若專案已大量使用選單項 OnClick,可逐步遷移至 Action,新功能直接用 Action 開發。
  • Action 的 ShortCut 優先級高於選單項,無衝突風險。
  • 此方案同樣適用於非 ToolBar 場景的主選單快捷鍵管理。

結合「自建 TPopupMenu 禁用自動熱鍵」與「TActionList 接管快捷鍵觸發」,徹底解決工具列主選單自訂快捷鍵失效問題,賦予開發者完整的快捷鍵控制權。

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