Я знаю один метод предотвращения закрытия диалога MFC при нажатии клавиш Enter или Esc, но я хотел бы узнать больше деталей процесса и всех распространенных альтернативных методов для этого.
Заранее благодарим за помощь.
Я знаю один метод предотвращения закрытия диалога MFC при нажатии клавиш Enter или Esc, но я хотел бы узнать больше деталей процесса и всех распространенных альтернативных методов для этого.
Заранее благодарим за помощь.
Когда пользователь нажимает клавишу Enter в диалоговом окне, могут произойти две вещи:
CDialog::SetDefID()
). Затем в диалог отправляется WM_COMMAND с идентификатором этого элемента управления.При первом варианте может оказаться, что элемент управления по умолчанию имеет ID, равный IDOK. Тогда результаты будут такими же, что и во втором варианте.
По умолчанию класс CDialog
имеет обработчик для WM_COMMAND(IDOK)
, который должен вызвать CDialog::OnOk()
, то есть виртуальную функцию, и по умолчанию он вызывает EndDialog(IDOK)
, который закрывает диалог.
Итак, если вы хотите избежать закрытия диалогового окна, выполните одно из следующих действий.
IDOK
.WM_COMMAND(IDOK)
, который не вызывает EndDialog()
.CDialog::OnOk()
и не вызывать базовую реализацию.О IDCANCEL, это похоже, но нет эквивалента SetDefID()
, а клавиша ESC жестко запрограммирована. Чтобы избежать закрытия диалогового окна:
WM_COMMAND(IDCANCEL)
, который не вызывает EndDialog()
.CDialog::OnCancel()
и не вызывать базовую реализацию.Существует альтернатива предыдущему ответу, что полезно, если вы хотите иметь кнопку OK/Close. Если вы переопределите функцию PreTranslateMessage, вы можете поймать использование VK_ESCAPE/VK_RETURN следующим образом:
BOOL MyCtrl::PreTranslateMessage(MSG* pMsg)
{
if( pMsg->message == WM_KEYDOWN )
{
if(pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE)
{
return TRUE; // Do not process further
}
}
return CWnd::PreTranslateMessage(pMsg);
}