加速鍵 (Accelerator)和 熱鍵(HotKey) [轉]
加速鍵 (Accelerator)和 熱鍵(HotKey)
加速鍵 和 熱鍵 是兩種不同的快捷鍵(我這裡暫且把它們都稱為快捷鍵,而其他人可能只把後者稱為快捷鍵。)應儘量避免衝突。
加速鍵 (Accelerator)
一種是直接與選單項關聯的加速鍵
另一種就是自定義的加速鍵.
第一種: (如果是基於對話方塊的工程,我們先新增選單和加速鍵資源,然後右擊主對話方塊屬性新增選單)
首先在資原始檔Accelerator中新增快捷鍵資源 ID選擇你要關聯選單項的名稱 然後再設定你的快捷鍵.什麼?下一步?在.h檔案中加入一個 HACCEL hAccel;變數 然後在OnInitDialog或初始化中加入hAccel=::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR1)); 後面的引數是加速鍵資原始檔名.
最後在PreTranslateMessage(MSG* pMsg) 中加入:
if(::TranslateAccelerator(GetSafeHwnd(),hAccel,pMsg))
return true;
這樣 以後只要在Accelerator資原始檔中新增快捷鍵就可以了
注意:新增快捷鍵的ID一定要與選單ID一樣 這樣才能響應.現在只需要在此選單項中加入OnCommand訊息的處理就可以了.
第二種: 還是在資原始檔Accelerator中新增快捷鍵資源 ID自己定義一個.然後再設定你的快捷鍵.下一步...就是在.h檔案中定義一個快捷鍵物件
HACCEL m_hAccel;
然後在.cpp檔案中初始
m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_ACCELERATOR1));
IDR_ACCELERATOR1為你的加速資源名稱.注意不是剛剛定義的加速鍵ID.
再新增PreTranslateMessage訊息處理 在裡面加入以下程式碼:
//儲存快捷鍵被啟用
if(m_hAccel != NULL)
{
if (TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return TRUE;
}
再新增OnCommand訊息處理 加入以下程式碼:
//響應加速鍵
switch(LOWORD(wParam))
{
case SHOW_DIAL0G: //加速鍵ID
//...新增處理語句
break;
case SHOW_DIALOG_02: //加速鍵ID
//...新增處理語句
break;
}
自己加的:在我看的程式碼中,它是利用對話方塊加選單的,當加了選單後,把選單掛到對話方塊,然後響應一個選單項.再在對話方塊類中加虛擬函式PreTranslateMessage,在些數裡的程式碼如下:
if( pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_F2)
this->PostMessage(WM_COMMAND,IDM_SHOW);//IDM_SHOW是響應的選單項ID
}
return CDialog::PreTranslateMessage(pMsg);
這樣我就可以響應F2的加速鍵了!!
熱鍵(hotkey)
熱鍵一般是有Ctrl+其他鍵位或Alt+其他鍵位或Ctrl+Alt+其他鍵位構成。關於如何建立自己的熱鍵,
下面就有詳細的說明:
1:要定義一個熱鍵(組合鍵)即必須先為熱鍵賦於一個自定義的ID,用來給系統標識該熱鍵。注意,
自定義的ID(int型)必須是唯一的,既不能與系統的其他ID相沖突。
2 運用函式RegisterHotKey
(
HWND hWnd, // 接收WM_HOTKEY的視窗控制代碼
int id, // hot key的ID號.
UINT fsModifiers, // 響應那個熱鍵.
UINT vk // 與熱鍵配合的鍵虛位碼
)
當配合建為a(A) —z(Z),
和 0 — 9時,伴隨建虛偽碼可以用諸如'a','0'的形式代替。hWnd 為接受熱鍵的視窗控制代碼,可以用
GetSafeHwnd()函式獲得。自定義熱鍵ID對於一個執行緒來講一般設在0x0000 到0xBFFF(49151)之間,對於一個
DLL來講其值一般設在0xC000(49152) 到0xBFFF(49151)之間。
fsModifiers可取如下值
MOD_ALT ;MOD_CONTROL ;MOD_SHIFT ;MOD_WIN 或他們的組合(中間用|連線)
3 定義熱鍵的同時一般也要自定義熱鍵相應的響應函式,其定義方法如下:
(1):先在某個類的標頭檔案的其他訊息響應函式的宣告處按照相應的格式加上如下語句
afx_msg long OnHotKey(WPARAM wParam,LPARAM lParam);//wParam一般為熱鍵訊息的ID
(2): 在相應類的.cpp檔案的訊息對映巨集BEGIN_MESSAGE_MAP 和END_MESSAGE_MAP之間加上同其他訊息
響應巨集宣告相同格式的自定義訊息響應巨集ON_MESSAGE(WM_HOTKEY,OnHotKey)
(3):然後就運用RegisterHotKey(...)函式定義快捷鍵。並在相應的訊息響應函式OnHotKey(...)中加
如相應的處理程式碼。注意訊息響應函式一定要有返回值,其可以使HRESULT,int ,long等資料類
型。
(4): 用完後不要忘了在OnDestory(...)函式或OnCancel(...)中解除函式登記,釋放系統資源。此時
要呼叫函式 bool UnregisterHotKey(hWnd,VK(ID));
4 相應的例子如:
[程式實現]
建立名為My的對話方塊工程.本例要用到RegisterHotKey()實現Alt+D的快捷鍵組合功能.在呼叫該函式後你的程序會在ALT+D按下時比系統先得到通知.你需要處理的訊息是WM_HOTKEY.
如下:
在MyDlg.h中:
class CMyDlg : public CDialog
{
// Construction
public:
int m_nHotKeyID;//為你自己定義的一個hot key的ID值,在整個程式唯一.
........
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CMyDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg LONG OnHotKey(WPARAM wParam,LPARAM lParam);//手動加入.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
在MyDlg.cpp中:
#define VK_D 68
..............
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
//{{AFX_MSG_MAP(CHotKey1Dlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOK, OnRegisterHotKey)
ON_BN_CLICKED(IDCANCEL, OnUnregisterHotKey)
ON_MESSAGE(WM_HOTKEY,OnHotKey) //手動加入.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CMyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
m_nHotKeyID=0;
BOOL m_isKeyRegistered = RegisterHotKey(GetSafeHwnd(),m_nHotKeyID,MOD_ALT,VK_D);
ASSERT(m_isKeyRegistered != FALSE);
return TRUE; // return TRUE unless you set the focus to a control
}
在取消按鈕的事件函式中加入:
void CMyDlg::OnCancel()
{
BOOL m_iskeyUnregistered = UnregisterHotKey(GetSafeHwnd(), m_nHotKeyID);
ASSERT(m_iskeyUnregistered != FALSE);
CDialog::OnCancel();
}
處理截到的組合鍵,並處理:
LONG CMyDlg::OnHotKey(WPARAM wParam,LPARAM lParam) //wParam一般為熱鍵訊息的ID
{
AfxMessageBox("你按下了組合鍵:Alt+D");
//加入相關程式碼.
return 0;
}
為了您的安全,請只打開來源可靠的網址