非模态对话框出错,非模态对话框

我先说一下我创建非模态对话框的思路,
资源视图中创建一个对话框并创建类Coption,在菜单中加入一个按键coption,
在CChildView类中创建一个Coption类对象指针,在CChildView类中用Coption类对象指针创建非模态对话框,并判断Coption类对象指针是否为null,如果不为null,则不创建,将焦点给非模态对话框就行,创建的时候,将CChildView类作为Coption类构造参数传入Coption类中,当非模态对话框点击取消时,销毁非模态对话框,并发送消息给CChildView类,让他将Coption类对象指针赋值为null,否则非模态对话框只能出来一次,但是现在发送消息会报错,
下面贴出四个文件代码:

Coption.h:
#pragma once


// Coption 对话框

class Coption : public CDialogEx
{
    DECLARE_DYNAMIC(Coption)

public:
    Coption(CWnd* pParent = nullptr);   // 标准构造函数
    Coption(CView* pview);   // 标准构造函数
    virtual ~Coption();

// 对话框数据
#ifdef AFX_DESIGN_TIME
    enum { IDD = IDD_DIALOG1 };
#endif

protected:
    virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

    DECLARE_MESSAGE_MAP()
public:
    afx_msg void OnBnClickedCancel();
    virtual void PostNcDestroy();
private:
    CView* p_view;
public:
    afx_msg void OnBnClickedOk();
};

Coption.cpp:
// Coption.cpp: 实现文件
//

#include "stdafx.h"
#include "MFCApplication5.h"
#include "Coption.h"
#include "afxdialogex.h"

// Coption 对话框

IMPLEMENT_DYNAMIC(Coption, CDialogEx)

Coption::Coption(CWnd* pParent /*=nullptr*/)
: CDialogEx(IDD_DIALOG1, pParent)
{

}

Coption::Coption(CView* pview /*=nullptr*/)
{
p_view = pview;
}

Coption::~Coption()
{

}

void Coption::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(Coption, CDialogEx)
ON_BN_CLICKED(IDCANCEL, &Coption::OnBnClickedCancel)
ON_BN_CLICKED(IDOK, &Coption::OnBnClickedOk)
END_MESSAGE_MAP()

// Coption 消息处理程序

void Coption::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码

//CDialogEx::OnCancel();
DestroyWindow();

}

void Coption::PostNcDestroy()
{
// TODO: 在此添加专用代码和/或调用基类
CDialogEx::PostNcDestroy();

p_view->SendMessage(WM_GOODBYE, 0,0);                //屏蔽这一行就不会报错 

}

void Coption::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
//CDialogEx::OnOK();
DestroyWindow();

}

CChildView.cpp:

// ChildView.cpp: CChildView 类的实现
//

#include "stdafx.h"
#include "MFCApplication5.h"
#include "ChildView.h"
#include "resource.h"       // 主符号

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChildView

CChildView::CChildView()
{
    m_option = NULL;
}


CChildView::~CChildView()
{
}


BEGIN_MESSAGE_MAP(CChildView, CWnd)
    ON_WM_PAINT()
    ON_COMMAND(ID_32771, &CChildView::On32771)
    ON_MESSAGE(WM_GOODBYE,ON_GOODBYE)
END_MESSAGE_MAP()

LRESULT  CChildView::ON_GOODBYE(WPARAM wparam, LPARAM lparam)
{
    /*delete m_option;*/
    m_option = NULL;

    return 0;
 }

// CChildView 消息处理程序

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs) 
{
    if (!CWnd::PreCreateWindow(cs))
        return FALSE;

    cs.dwExStyle |= WS_EX_CLIENTEDGE;
    cs.style &= ~WS_BORDER;
    cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS, 
        ::LoadCursor(nullptr, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), nullptr);

    return TRUE;
}

void CChildView::OnPaint() 
{
    CPaintDC dc(this); // 用于绘制的设备上下文

    // TODO: 在此处添加消息处理程序代码

    // 不要为绘制消息而调用 CWnd::OnPaint()
}



void CChildView::On32771()
{
    if (NULL==m_option)
    {
        /*SetFocus();
        MessageBox(_T("m_option不为空"));*/
        m_option = new Coption;
        m_option->Create(IDD_DIALOG1, this);
        MessageBox(_T("m_option为空"));
    }


    m_option->ShowWindow(SW_SHOW);


    // TODO: 在此添加命令处理程序代码
}


CChildView.h:

// ChildView.h: CChildView 类的接口
//

#pragma once
#include"Coption.h"

// CChildView 窗口

class CChildView : public CWnd
{
// 构造
public:
CChildView();

// 特性
public:

// 操作
public:

// 重写
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// 实现
public:
virtual ~CChildView();

// 生成的消息映射函数

protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
protected:
Coption* m_option;
public:
afx_msg void On32771();
afx_msg LRESULT ON_GOODBYE(WPARAM wparam, LPARAM lparam);
};

报错如下:
![图片说明](https://img-ask.csdn.net/upload/201908/15/1565872965_493989.png)

如果实在没人愿意回答,讲一下编写非模态对话框心得也行

1个回答

weixin_44826062
moon19961996 不清楚为什么,但是貌似不用发消息给CChildView类让指针为空,直接调用系统自带的取消就可以了
5 个月之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问