如何防止 MFC 对话框在 Enter 和 Escape 键上关闭?

2022-01-12 00:00:00 c++ mfc

我知道一种防止 MFC 对话框在按下 EnterEsc 键时关闭的方法,但我想了解更多有关该过程的详细信息和这样做的所有常见替代方法.

I know one method of preventing an MFC dialog from closing when the Enter or Esc keys are pressed, but I'd like to know more details of the process and all the common alternative methods for doing so.

提前感谢您的帮助.

推荐答案

当用户在对话框中按下 Enter 键时,会发生两种情况:

When the user presses Enter key in a dialog two things can happen:

  1. 对话框有一个默认控件(参见CDialog::SetDefID()).然后将带有此控件 ID 的 WM_COMMAND 发送到对话框.
  2. 对话框没有默认控件.然后将 ID = IDOK 的 WM_COMMAND 发送到对话框.
  1. The dialog has a default control (see CDialog::SetDefID()). Then a WM_COMMAND with the ID of this control is sent to the dialog.
  2. The dialog does not have a default control. Then WM_COMMAND with ID = IDOK is sent to the dialog.

使用第一个选项,默认控件的 ID 可能等于 IDOK.那么结果将与第二个选项中的结果相同.

With the first option, it may happen that the default control has a ID equal to IDOK. Then the results will be the same that in the second option.

默认情况下,CDialog 类有一个 WM_COMMAND(IDOK) 的处理程序,用于调用 CDialog::OnOk(),这是一个虚函数,默认情况下它调用 EndDialog(IDOK) 来关闭对话框.

By default, class CDialog has a handler for the WM_COMMAND(IDOK) that is to call to CDialog::OnOk(), that is a virtual function, and by default it calls EndDialog(IDOK) that closes the dialog.

因此,如果您想避免关闭对话框,请执行以下操作之一.

So, if you want to avoid the dialog being closed, do one of the following.

  1. 将默认控件设置为 IDOK 以外的其他控件.
  2. 为不调用 EndDialog()WM_COMMAND(IDOK) 设置一个处理程序.
  3. 覆盖 CDialog::OnOk() 并且不调用基本实现.
  1. Set the default control to other than IDOK.
  2. Set a handler to the WM_COMMAND(IDOK) that does not call EndDialog().
  3. Override CDialog::OnOk() and do not call the base implementation.

关于 IDCANCEL,类似但没有等效的 SetDefID() 并且 ESC 键是硬编码的.所以为了避免对话框被关闭:

About IDCANCEL, it is similar but there is not equivalent SetDefID() and the ESC key is hardcoded. So to avoid the dialog being closed:

  1. 为不调用 EndDialog()WM_COMMAND(IDCANCEL) 设置一个处理程序.
  2. 重写 CDialog::OnCancel() 并且不调用基本实现.
  1. Set a handler to the WM_COMMAND(IDCANCEL) that does not call EndDialog().
  2. Override CDialog::OnCancel() and do not call the base implementation.

相关文章