在对话框中处理加速器
Handling accelerator in a dialog
我错过了哪一步?
我有加速器table:
我在我的应用程序中添加了一个成员变量class:
HACCEL m_hAccel;
我添加了以下覆盖:
BOOL CMeetingScheduleAssistantApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if (m_hAccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccel, lpMsg))
{
AfxMessageBox(_T("Found"));
return(TRUE);
}
}
return CWinAppEx::ProcessMessageFilter(code, lpMsg);
}
我只是使用弹出消息框进行调试,它确认正在检测到按键。
我的菜单资源设置正确:
所以我的菜单是用菜单处理程序操作的。我已经设置了加载加速器的程序table。例如,如果我按下 Ctrl+Shift+X 而它被加速器 table 为什么我的弹出对话框实际上没有处理它?
我应该指出,我的主应用程序对话框显示了两个编辑器之一。因此,当显示编辑器时,我会为该编辑器加载加速器 table。
我错过了哪一步?为什么对话框不处理加速器?
更新
我找到了这个答案 How to make child control handle accelerator command of parent CView。
我发现如果我直接在弹出对话框中添加 HACCEL
然后只使用 PreTranslateMessage
:
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}
有效。
对于对话框中的键盘加速器,我这样做:
在 OnInitDialog
BOOL CMyDlg::OnInitDialog()
{
...
m_hAccel = LoadAccelerators ( AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_DLGACCEL));
...
}
PreTranslateMessage
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
if (m_hAccel)
{
if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return(TRUE);
else
return CDialog::PreTranslateMessage(pMsg);
}
else
return CDialog::PreTranslateMessage(pMsg);
}
在OnDestroy
void CMyDlg::OnDestroy()
{
...
VERIFY(DestroyAcceleratorTable(m_hAccel)) ;
CDialog::OnDestroy();
}
留言图:
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
...
ON_COMMAND(IDC_SOMECOMMANDID, OnDoSomething)
ON_UPDATE_COMMAND_UI(IDC_SOMECOMMANDID, OnUpdateDoSomething)
...
END_MESSAGE_MAP()
命令处理程序
void CMyDlg::OnUpdateDoSomething(CCmdUI* pCmdUI)
{
...
pCmdUI->Enable(...) ;
}
void CMyDlg::OnDoSomething()
{
...
}
.rc 文件中的加速器 table
IDR_DLGACCEL ACCELERATORS
BEGIN
"A", IDC_SOMECOMMANDID, VIRTKEY, CONTROL, NOINVERT // Ctrl+A
...
END
就这些了。
我错过了哪一步?
我有加速器table:
我在我的应用程序中添加了一个成员变量class:
HACCEL m_hAccel;
我添加了以下覆盖:
BOOL CMeetingScheduleAssistantApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
if (m_hAccel)
{
if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccel, lpMsg))
{
AfxMessageBox(_T("Found"));
return(TRUE);
}
}
return CWinAppEx::ProcessMessageFilter(code, lpMsg);
}
我只是使用弹出消息框进行调试,它确认正在检测到按键。
我的菜单资源设置正确:
所以我的菜单是用菜单处理程序操作的。我已经设置了加载加速器的程序table。例如,如果我按下 Ctrl+Shift+X 而它被加速器 table 为什么我的弹出对话框实际上没有处理它?
我应该指出,我的主应用程序对话框显示了两个编辑器之一。因此,当显示编辑器时,我会为该编辑器加载加速器 table。
我错过了哪一步?为什么对话框不处理加速器?
更新
我找到了这个答案 How to make child control handle accelerator command of parent CView。
我发现如果我直接在弹出对话框中添加 HACCEL
然后只使用 PreTranslateMessage
:
if (m_hAccelTable)
{
if (::TranslateAccelerator(GetSafeHwnd(), m_hAccelTable, pMsg))
return TRUE;
}
有效。
对于对话框中的键盘加速器,我这样做:
在 OnInitDialog
BOOL CMyDlg::OnInitDialog()
{
...
m_hAccel = LoadAccelerators ( AfxGetResourceHandle(), MAKEINTRESOURCE(IDR_DLGACCEL));
...
}
PreTranslateMessage
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
if (m_hAccel)
{
if (::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
return(TRUE);
else
return CDialog::PreTranslateMessage(pMsg);
}
else
return CDialog::PreTranslateMessage(pMsg);
}
在OnDestroy
void CMyDlg::OnDestroy()
{
...
VERIFY(DestroyAcceleratorTable(m_hAccel)) ;
CDialog::OnDestroy();
}
留言图:
BEGIN_MESSAGE_MAP(CMyDlg, CDialog)
...
ON_COMMAND(IDC_SOMECOMMANDID, OnDoSomething)
ON_UPDATE_COMMAND_UI(IDC_SOMECOMMANDID, OnUpdateDoSomething)
...
END_MESSAGE_MAP()
命令处理程序
void CMyDlg::OnUpdateDoSomething(CCmdUI* pCmdUI)
{
...
pCmdUI->Enable(...) ;
}
void CMyDlg::OnDoSomething()
{
...
}
.rc 文件中的加速器 table
IDR_DLGACCEL ACCELERATORS
BEGIN
"A", IDC_SOMECOMMANDID, VIRTKEY, CONTROL, NOINVERT // Ctrl+A
...
END
就这些了。