Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent my MFC dialog-based app from closing after ESC key, but allow other controls to process it?

I can't seem to find a working solution how to block my dialog-based MFC app from closing after a user hits ESC on the keyboard. I keep finding code where people simply override PreTranslateMessage notifications and block all WM_KEYDOWN messages for VK_ESCAPE, but that doesn't work for me because this approach blocks all ESC keystrokes in the app. So for instance, when a user opens a drop-down list and wants to close it with ESC key, it will be also blocked. Or, the same would happen if someone opens a popup menu or a date-time/calendar control and tries to dismiss it with the ESC keystroke, etc.

So my question, how to prevent only my dialog from closing after ESC keystroke?

like image 717
c00000fd Avatar asked Mar 16 '23 10:03

c00000fd


1 Answers

Esc gets automatically routed to your dialog through WM_COMMAND with an id of IDCANCEL. In dlgcore.cpp there is a default handler that will terminate your dialog (and hence the application in your case) like this:

void CDialog::OnCancel()
{
    EndDialog(IDCANCEL);
}

To stop that happening, simply add an IDCANCEL handler yourself. For example, in your dialog header add the method signature:

afx_msg void OnCancelOverride();

In your dialogs message map, add routing for IDCANCEL:

ON_COMMAND(IDCANCEL,OnCancelOverride)

And finally add the OnCancelOverride implementation. This sample implementation doesn't exit if Esc is down but does allow exit from the system menu 'Close' option.

void CMyDlg::OnCancelOverride() 
{
  // call base implementation if escape is not down

  if((GetKeyState(VK_ESCAPE) & 0x8000)==0)
    OnCancel();
}
like image 98
Andy Brown Avatar answered Apr 25 '23 15:04

Andy Brown