MFC+гоячие клавиши
Glad to greet!
Ситуация такова: написал заготовку класса наследуемого от CDialog и
захотелось добавить реакцию на нажатие клавиш. Поставил реакцию на
WM_CHAR, WM_KEYDOWN/UP - ни один из методов не вызывается (окно в
фокусе). Решил пойти через Accelerator, но обнаружил, что
LoadAccelTable есть только у CFrameWnd. Каким образом обрабатывать
нажатие клавиш и как их отлавливать? Заранее спасибо!
Alles Gute!
...In Code We Trust...
Здравствуйте !
Для WM_KEYDOWN/UP обычно делают в PreTranslateMessage:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
if(pMsg->message == WM_KEYDOWN)
{
if(((int) pMsg->wParam) == VK_DELETE)
{
MessageBox("VK_DELETE");
return TRUE;
}
}
return CDialog::PreTranslateMessage(pMsg);
}
Но ! Тут будут обрабатываться также все сообщения WM_KEYDOWN с кодом
виртуальной клавиши VK_DELETE дочерних окон диалога (кнопок, и.т.д.),
поэтому надо проверять pMsg->hwnd на соответствие дескриптору
конкретного окна.
С акселераторами немного больше сделать надо.
В самом классе объявить дескриптор акселераторов:
class CMyDlg : public CDialog
{
...
HACCEL m_hAccel;
В конструкторе инициализируем:
CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/) : CDialog(CMyDlg::IDD, pParent)
{
...
m_hAccel = NULL;
В OnCreate - загружаем, в OnDestroy - удаляем акселераторную таблицу:
int CMyDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
m_hAccel = ::LoadAccelerators(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDR_ACCELERATOR1));
#ifdef _DEBUG
if(m_hAccel == NULL)
TRACE("акселераторы не загружены\n");
#endif
return 0;
}
void CMyDlg::OnDestroy()
{
if(m_hAccel != NULL)
{
::DestroyAcceleratorTable(m_hAccel);
m_hAccel = NULL;
}
CDialog::OnDestroy();
}
Ну, а в PreTranslateMessage - обрабатываем:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
if( (WM_KEYFIRST <= pMsg->message) &&
(WM_KEYLAST >= pMsg->message))
{
if (m_hAccel &&
::TranslateAccelerator(GetSafeHwnd(), m_hAccel, pMsg))
return TRUE;
}
return CDialog::PreTranslateMessage(pMsg);
}
Я в таблицу акселераторов IDR_ACCELERATOR1 добавил один акселератор
на кнопку VK_DELETE с ID = ID_MY_DELETE. После этого ID_MY_DELETE становится
виден в класс визарде. Обычным путем добавляется обработчик в класс диалога.
Ну... и все работает :)
void CMyDlg::OnMyDelete()
{
MessageBox("OnMyDelete");
}
--
С уважением, Вахтуров Виктор.
Номер выпуска : 4371
Возраст листа : 574 (дней)
Количество подписчиков : 517
Адрес в архиве : http://subscribe.ru/archive/comp.soft.prog.prog/msg/352535
Получить правила : mailto:comp.soft.prog.prog-rules@subscribe.ru
Формат "дайджест" : mailto:comp.soft.prog.prog-digest@subscribe.ru
Формат "каждое письмо" : mailto:comp.soft.prog.prog-normal@subscribe.ru
Формат "читать с веба" : mailto:comp.soft.prog.prog-webonly@subscribe.ru