MFC 应用程序退出代码始终为 20

问题描述 投票:0回答:1

采用基于默认 MFC 的单对话框应用程序,我试图防止 Escape 或 Enter 键将导致对话框关闭的默认行为。

然而,虽然我能够实现这一点,但我发现应用程序退出代码现在总是返回 20,无论我传递给 EndDialog 的值如何。

在下面的测试中我阻止了 Escape 键:

BEGIN_MESSAGE_MAP(CMFCApplication10Dlg, CDialogEx)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_BN_CLICKED(IDCANCEL, &CMFCApplication10Dlg::OnBnClickedCancel) // Triggers when Escape key pressed
    ON_WM_CLOSE() // Added WM_CLOSE to handle the close
END_MESSAGE_MAP()

OnBnClickedCancel 在按 Escape 时发生,因此为了防止应用程序关闭,我不调用 OnCancel

void CMFCApplication10Dlg::OnBnClickedCancel()
{
    //CDialogEx::OnCancel(); // Not calling OnCancel
}

我添加了 OnClose 以允许使用右上角的“关闭”按钮仍然可以关闭对话框

void CMFCApplication10Dlg::OnClose()
{
    CDialogEx::EndDialog(0); // Call the EndDialog with 0
}

如何禁用退出键并返回退出代码 0

预期: 退出代码 0

实际: 获得退出代码 20

c++ mfc visual-studio-2022
1个回答
0
投票

当您创建 MFC“对话框应用程序”时,您通常希望禁用 Enter[sc] 键处理,因为这是主应用程序窗口,同时仍然能够从系统菜单或标题栏上的关闭按钮。

对于 [Enter] 键,您可以覆盖对话框的

OnOK()
成员(默认实现关闭对话框):

void CMyDlg::OnOK()
{
    // CDialogEx::OnOK(); Don't Close
}

对于 [Esc] 键有多种技巧。一种是覆盖

OnCancel()
成员:

void CMyDlg::OnCancel()
{
    // Disable Closing on Esc press
    if ((GetKeyState(VK_ESCAPE) & 0x8000) == 0)
        CDialogEx::OnCancel(); // Close only if NOT caused by [Esc]
}

或者覆盖

OnCancel()
并向向导生成的
OnSysCommand()
成员添加几行:

void CMyDlg::OnCancel()
{
    //CDialogEx::OnCancel(); Don't Close
}

void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
        CAboutDlg dlgAbout;
        dlgAbout.DoModal();
    }
    else if (nID == SC_CLOSE) // Add these 2 lines
        CDialogEx::OnCancel();
    else CDialogEx::OnSysCommand(nID, lParam);
}

其他开发人员会覆盖

PreTranslateMessage()
成员。

至于退出代码,我认为它根本没有意义,正如我在评论中指出的那样。如果单击 [X] 按钮,应用程序将返回 0,但它还应该返回什么?在什么条件下?

无论如何,

CWinApp
派生自
CWinThread
,您可以尝试覆盖
Run()
,并在实现中调用父类(
CWinApp::Run()
CWinAppEx::Run()
)丢弃其返回值并始终返回0。向导-对于对话框应用程序,生成的
InitInstance()
覆盖返回
FALSE
,这意味着初始化失败,这就是为什么您可能会得到非零退出代码。

旁注,如果您的项目是新的,并且您想要的只是一个显示“主窗体”的 MFC 应用程序,例如 VB 或 C#,您可以尝试不使用“对话框应用程序”,而是使用没有文档/的 SDI 应用程序查看支持(取消选中该选项)。但它仍然包含一个视图对象。视图类型可以是

CFormView
,这是基于对话框资源的视图,应用程序表现更好,避免了应用程序中的问题,支持
ON_UPDATE_COMMAND_UI
处理程序和键盘加速器等功能,并提供了诸如工具栏、状态栏和可停靠窗格,全部由向导生成。也就是说,它是一个正确的应用程序,而不是一个重新用作应用程序窗口的对话框。

© www.soinside.com 2019 - 2024. All rights reserved.