MFC 模式子对话框没有收到消息或覆盖

Posted

技术标签:

【中文标题】MFC 模式子对话框没有收到消息或覆盖【英文标题】:MFC modal sub-dialog not getting messages or overrides 【发布时间】:2017-04-11 16:11:54 【问题描述】:

使用 VC6 并使用 MFC AppWizard (exe) 创建了一个 MFC 对话框。插入第二个对话框并将以下内容添加到原始对话框中:

#include "PassInfoDlg.h"

并在一个函数中添加:

CDialog CPassInfoDlg(IDD_PASSINFO);

INT_PTR nRet = -1;
TRACE("Before CPassInfoDlg.DoModal\n"); 
nRet = CPassInfoDlg.DoModal();
TRACE("CPassInfoDlg.DoModal = %d\n", nRet); 

PassInfoDlg 有三个按钮,OK、Cancel 和 Delete,其中 Delete 设置为 IDC_DELETE。当按下 OK/Cancel 时 nRet = 1 或 2,但不会发生相应的覆盖。此外,永远不会调用删除消息函数。跟踪仅显示:

Before CPassInfoDlg.DoModal
CPassInfoDlg.DoModal = 1

即使在第二个对话框中有额外的痕迹。第二个对话框包括:

// PassInfoDlg.h

class CPassInfoDlg : public CDialog

// Construction
public:
    CPassInfoDlg(CWnd* pParent = NULL);   // standard constructor

// Dialog Data
    //AFX_DATA(CPassInfoDlg)
    enum  IDD = IDD_PASSINFO ;
    // NOTE: the ClassWizard will add data members here
//AFX_DATA

// Overrides
    // ClassWizard generated virtual function overrides
    //AFX_VIRTUAL(CPassInfoDlg)
    public:
    virtual int DoModal();
    //AFX_VIRTUAL

// Implementation
protected:

    // Generated message map functions
    //AFX_MSG(CPassInfoDlg)
    virtual void OnOK();
    virtual void OnCancel();
    afx_msg void OnDelete();
    //AFX_MSG
    DECLARE_MESSAGE_MAP()
;


// PassInfoDlg.cpp

CPassInfoDlg::CPassInfoDlg(CWnd* pParent /*=NULL*/)
    : CDialog(CPassInfoDlg::IDD, pParent)

    //AFX_DATA_INIT(CPassInfoDlg)
        // NOTE: the ClassWizard will add member initialization here
    //AFX_DATA_INIT


BEGIN_MESSAGE_MAP(CPassInfoDlg, CDialog)
    //AFX_MSG_MAP(CPassInfoDlg)
    ON_BN_CLICKED(IDC_DELETE, OnDelete)
    //AFX_MSG_MAP
END_MESSAGE_MAP()

// CPassInfoDlg message handlers

int CPassInfoDlg::DoModal() 

    TRACE("CPassInfoDlg::DoModal\n"); 
    return CDialog::DoModal();


void CPassInfoDlg::OnOK() 

    TRACE("CPassInfoDlg::OnOK\n"); 
    CDialog::OnOK();


void CPassInfoDlg::OnCancel() 

    TRACE("CPassInfoDlg::OnCancel\n"); 
    CDialog::OnCancel();


void CPassInfoDlg::OnDelete() 

    TRACE("CPassInfoDlg::OnDelete\n"); 
    EndDialog(IDC_DELETE);

没有调用任何覆盖或删除消息。我可以在三个按钮之间切换,然后单击或按下 OK 或 Cancel 工作,忽略不调用覆盖。按下删除按钮时没有响应。 MFC 向导似乎很简单,但我不确定我做错了什么。

【问题讨论】:

CDialog CPassInfoDlg(IDD_PASSINFO); 构造一个名为 CPassInfoDlg 的普通 CDialog 对象。它确实不会创建CPassInfoDlg 对象。最近的编译器可能会对此发出警告。 2017 年看起来是放弃 19 年历史的编译器/IDE 的好年头。 我同意升级,但很有可能我还需要更换硬件和操作系统。比我目前想要承诺的更大的项目。我在 MSDN 站点上看到过我使用的方法,所以我就是这样朝着那个方向前进的。它成功启动第二个对话框的事实给我的印象是我正在朝着正确的方向前进。 CDialog CPassInfoDlg(IDD_PASSINFO); 使用通过IDD_PASSINFO 标识的对话框资源来构造对话框,因此视觉效果看起来像您想要的对话框。但是,该对话框未附加到 CPassInfoDlg 对象,因此您的回调永远不会被命中。换句话说:视觉效果是对话资源定义的。该行为是标准 CDialog 对象的行为。 【参考方案1】:

数字,在发布之前和发布之后花了几个小时,我想出了自己的答案。对原始对话框的以下更改似乎有效:

    CPassInfoDlg dlg;

// Create and show the dialog box
    INT_PTR nRet = -1;
    TRACE("Before dlg.DoModal\n"); 
    nRet = dlg.DoModal();
    TRACE("dlg.DoModal = %d\n", nRet);

现在正在调用 DoModal 覆盖以及其他覆盖。可能有多种方法可以做到这一点,但至少我很好。

【讨论】:

以上是关于MFC 模式子对话框没有收到消息或覆盖的主要内容,如果未能解决你的问题,请参考以下文章

自动消失的自定义消息框

MFC ActiveX 击键

MFC如何在切换视图时关闭无模式对话框

MFC 中的“调整大小”对话框

MFC中怎么让子窗体大小随着父窗口的大小变化而改变?

如何在 MFC 中获得焦点消息?