程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 工具欄中的主菜單實現自定義快捷鍵的方法

工具欄中的主菜單實現自定義快捷鍵的方法

編輯:關於C++

如果做過“把主菜單放到工具欄裡”的兄弟們都會發現一個問題:那就是系統會自動給菜單選項加上熱鍵(如果你的菜單選項是英文,那麼會在第一個字母下加橫線,如果你的菜單選項是中文,那麼會在菜單選項的後面加上類似(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,並把原來的那個菜單的菜單項添加到這個TPopupMenu當中,最後才顯示這個臨時的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)就起作用了!

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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved