在BCB中把主菜單放到工具列裡後,實現自訂快速鍵的方法

來源:互聯網
上載者:User

    

      如果做過“把主菜單放到工具列裡”的兄弟們都會發現一個問題:那就是系統會自動給菜單選項加上熱鍵(如果你的菜單選項是英文,那麼會在第一個字母下加橫線,如果你的菜單選項是中文,那麼會在菜單選項的後面加上類似(Y)、(Z)的快速鍵),而使你自己定義的快速鍵失效!(註:我後來發現,如果自己加的是類似(H)的快速鍵時,就不會出現這樣的問題。而只有當我們加的是類似Ctrl+A,F1,Ctrl+Alt+D等的快速鍵時才會出現問題;另外當為TMainMenu設定了Images屬性後,也就是說給功能表項目加了圖片,英文菜單的問題會消失,但中文菜單的問題依然存在。這其中的原因,我也搞不清楚)。即使我們設定mainMenu的AutoHotkeys=maManual也解決不了。
 
   當初我在遇到這個問題後,一籌莫展,只好向高手們請教。後來在BCB_FANS和JSP兩位老大的協助下,才解決問題。因此,這篇文章實際上是整理的兩位老大的方法。

   首先,讓我們去掉系統自動加的熱鍵。

   當我們把菜單放到工具列裡後,我們在程式運行時看到的菜單其實不是我們在設計時加的TMainMenu,而是系統臨時new的一個TPopupMenu,而這個臨時的菜單的AutoHotkeys屬性預設為maAutomatic,所以就會給菜單自動加上熱鍵。這個問題是BCB_FANS發現的(我不可能有這麼厲害,呵呵),他的原話是這樣的:

    “實際上顯示菜單的時候,TToolBar並不是使用原來已經設計好的菜單了,而是重建立立一個臨時的TPopupMenu,並把原來的那個菜單的功能表項目添加到這個RpopupMenu當中,最後才顯示這個臨時的TPopupMenu。這個TPopupMenu的AutoHotkeys為maAutomatical,並且沒有任何方式可以控制這個臨時的TPopupMenu的屬性。所以顯示出來的菜單都會自動添加快捷字元。”

      然後BCB_FANS就自己做了一個TMenuBar,專門用來製作工具列裡的菜單(我現在用的就是它)。他在TMenuBar中的實現方法是用自己的TPopupMenu替換系統new的TPopupMenu,設定自己的TPopupMenu的AutoHotkeys=maManual:

    “既然沒有辦法控制那個臨時的TPopupMenu,自然而然就會想到使用自己的TPopupMenu去替換那個臨時的TPopupMenu,OK,這個好辦,只要設定TToolButton的DropdownMenu屬,而不是設定MenuItem屬性就可以了。然後再設定自己的TPopupMenu的AutoHotkeys為maManual,這樣就沒有快捷字元了。”

   當然,並不是每個人都象我這樣幸運,能得到BCB_FANS老大TMenuBar的,呵呵。所以我昨天就在TR老大的“不可能解決的問題”文章裡問了這個問題,結果讓JSP老大把我認為“不可能解決的問題”給解決了!

     JSP老大的實現方法和其實和BCB_FANS的是一樣的,也是用自己的TPopupMenu替換系統的臨時菜單。只是BCB_FANS老大的TMenuBar封裝了TToolBar,並且能自動產生ToolButton來和功能表項目關聯,而不需要我們手動設定;而JSP的代碼只是完成去掉自動產生的快速鍵而寫的,其他工作還得我們自己做。

    JSP老大的代碼如下(注釋是我自己加的):

__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
    TMenuItem* Item;
    TMenuItem* Item1;
    TPopupMenu* Menu;

    for(int n=0; n<ToolBar1->ButtonCount; n++)
   {
        TToolButton* Btn = ToolBar1->Buttons[n];
        if (Btn->DropdownMenu != NULL)
            Btn->MenuItem = NULL;            //去掉系統產生的捷徑功能表
        else if(Btn->MenuItem != NULL)
            {
              Item = Btn->MenuItem;
              Menu = new TPopupMenu(this);
              Menu->AutoHotkeys = maManual; //不自動產生熱鍵
              Btn->DropdownMenu = Menu;      //給ToolButton添加自己new的菜單
              if (Item->GetParentMenu())     //設定該捷徑功能表的設定與TMainMenu相同
             {
                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--)   //把菜單選項添加到自己new的TPopupMenu裡
             {
                Item1 = Item->Items[i];
                Item->Delete(i);
                Menu->Items->Insert(0, Item1);
             }
            }
     }
}

     有了JSP老大的這段代碼後,就可以去掉那些討厭的快速鍵了(實際上是替換了菜單,當然快速鍵也就沒有了)。但是現在問題還自解決了一半,也就是還只去掉了自動產生的快速鍵,而我們自己設定的快速鍵還沒有起作用!我要說明白的是,這時並不是所有我們設定的快速鍵都不起作用,類似(N)這種括弧裡的和字母下加橫線的快速鍵還是好用的。只有類似Ctrl+a,Ctrl+Alt+Z和F1這些類型的快速鍵不起作用。為什麼會這樣?我找不到原因。

    那我們下面就想辦法讓自己的快速鍵起作用!我是通過使用TActionList來實現這一功能的,其實也是借鑒了以前的文章,然後自己加以完善。

    我們知道TActionList可以定義許多Actions(方法:設計時雙擊TActionList控制項,出現設定對話方塊後,就可以自己定義Actions了),而每個Actions都可以使用快速鍵來觸發它們的OnExecute事件。說到這裡我想大家應該明白怎麼做了。如果我們把某個Actions的快速鍵和某個菜單選項的快速鍵設定為相同,例如把功能表項目“Redo”和一Actions的快速鍵都設定為Ctrl+R。然後再在該Actions的OnExecute事件觸發“Redo”功能表項目的OnClick事件(也就是在Actions的OnExecute事件裡加入代碼:RedoMenu->Click();//RedoMenu為“Redo”菜單選項的名稱),那麼當我們按下Ctrl+R時,就會觸發“Redo”的OnClick事件了,這樣看起來,我們給菜單設定的快速鍵(Ctrl+R)就起作用了!

   這樣,我們就可以去掉系統自動產生的熱鍵,而且可以自己定義各種合適的快速鍵了!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.