Visual studio 2010的MFC程序中要在主菜單項中使用快捷鍵有兩個動作要做,一是在菜單項的Caption中加入快捷鍵的提示,比如“輸入數據\tCtrl+G”,二是在和主菜單同名的加速表中加入這個菜單項命令ID的快捷鍵設置,這樣MFC會自動響應快捷鍵操作,注意如果第二步沒有做,在菜單項上是不會出現快捷鍵的提示的。如果有一個輸出的Dock窗口,這個Dock窗口有一個右鍵菜單:
那是否完成上面的兩個動作就可以了呢?測試發現這樣並不行,考慮一下這種情況,拿ID_EDIT_COPY復制命令來說,輸出窗口右鍵菜單中有這個菜單項,在主文檔視圖的菜單中也有這個菜單項,在激活輸出窗口的時候按下Ctrl+C,你會發現是主視圖中的考慮得到了響應,而不是輸出窗口的右鍵菜單,這其實是和MFC的消息處理路徑有關系的,那么怎樣才能使得我們設置在輸出窗口上的快捷鍵得到響應呢?
我們的Output窗口COutputView繼承自CRichEditCtrl,右鍵菜單名為IDR_OUTPUT_POPUP,同時創建一個同名的加速表,添加“復制”和“清除”兩個菜單項的快捷鍵到加速表中。先來看看如何彈出右鍵菜單:
void COutputView::OnContextMenu(CWnd* /*pWnd*/, CPoint point) { CMenu menu; menu.LoadMenu(IDR_OUTPUT_POPUP); CMenu* pSumMenu = menu.GetSubMenu(0); theApp.GetContextMenuManager()->ShowPopupMenu(pSumMenu->GetSafeHmenu(), point.x, point.y, this, true ); SetFocus(); }
接下來需要重載PreTranslateMessage(),在這個函數中手工翻譯快捷鍵,如果在右鍵菜單的加速表中找到了相應的快捷項,就返回TRUE,這條消息就不再做后續處理了:
BOOL COutputView::PreTranslateMessage(MSG* pMsg) { if (WM_KEYFIRST <= pMsg->message && pMsg->message <= WM_KEYLAST) { HACCEL hAccel = ::LoadAccelerators(AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_OUTPUT_POPUP)); if (hAccel && ::TranslateAccelerator(m_hWnd, hAccel, pMsg)) return TRUE; } return CRichEditCtrl::PreTranslateMessage(pMsg); }
如果發現彈出菜單項里面沒有快捷鍵的提示,到工具欄的自定義里面重置一下快捷鍵就可能出現了,為什么?我也不知道!