简体   繁体   中英

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?

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();
}
  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 () ; } afx_msg void CDialogXXX::OnClose () { PostQuitMessage (0) ; CDialog::OnClose () ; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM