c00000fd
c00000fd

Reputation: 22255

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?

Upvotes: 4

Views: 2519

Answers (2)

frankcrc
frankcrc

Reputation: 31

  1. You can directly override OnCancel method and write nothing.
  2. add ON_WM_CLOSE() to message map so that you can quit app by click right top X button.
  3. add a method afx_msg void OnClose () in dialog class header.
  4. add code like following in dialog class cpp: afx_msg void CDialogXXX::OnClose () { PostQuitMessage (0) ; CDialog::OnClose () ; }

Upvotes: 0

Andy Brown
Andy Brown

Reputation: 12999

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();
}

Upvotes: 7

Related Questions