创建了一个MDI的非Doc/View应用程序, 以下是四个文件, 两个类CChildFrame CForm// ChildFrm.h : CChildFrame 类的接口
//
#pragma once#include "Form.h"class CChildFrame : public CMDIChildWnd
{
DECLARE_DYNCREATE(CChildFrame)
public:
CChildFrame();
virtual ~CChildFrame();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif// 生成的消息映射函数
protected:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
DECLARE_MESSAGE_MAP()private:
CForm m_form;
};
// ChildFrm.cpp : CChildFrame 类的实现
//
#include "stdafx.h"
#include "FormViewTest.h"#include "ChildFrm.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CChildFrame
IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd)BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd)
ON_WM_CREATE()
END_MESSAGE_MAP()// CChildFrame 构造/析构
CChildFrame::CChildFrame()
{
}CChildFrame::~CChildFrame()
{
}// CChildFrame 诊断
#ifdef _DEBUG
void CChildFrame::AssertValid() const
{
CMDIChildWnd::AssertValid();
}void CChildFrame::Dump(CDumpContext& dc) const
{
CMDIChildWnd::Dump(dc);
}
#endif //_DEBUG
int CChildFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
if (CMDIChildWnd::OnCreate(lpCreateStruct) == -1)
return -1;

// 创建一个视图以占用框架的工作区
if (!m_form.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, 
CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
{
TRACE0("未能创建视图窗口\n");
return -1;
}
return 0;
}// Form .h : CForm 类的接口
//#pragma onceclass CForm : public CFormView
{
DECLARE_DYNCREATE(CForm)public:
CForm();           // 动态创建所使用的受保护的构造函数
virtual ~CForm();public:
enum { IDD = IDD_FORM };
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endifprotected:
virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持 DECLARE_MESSAGE_MAP()
public:
virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
public:
virtual void OnInitialUpdate();// Form.cpp : 实现文件
//
#include "stdafx.h"
#include "FormViewTest.h"
#include "Form.h"
#include ".\form.h"// CForm
IMPLEMENT_DYNCREATE(CForm, CFormView)CForm::CForm()
: CFormView(CForm::IDD)
{
}CForm::~CForm()
{
}void CForm::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CForm, CFormView)
END_MESSAGE_MAP()// CForm 诊断#ifdef _DEBUG
void CForm::AssertValid() const
{
CFormView::AssertValid();
}void CForm::Dump(CDumpContext& dc) const
{
CFormView::Dump(dc);
}
#endif //_DEBUG
// CForm 消息处理程序BOOL CForm::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext)
{
return CFormView::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}void CForm::OnInitialUpdate()
{ CFormView::OnInitialUpdate();
// CMDIChildWnd 缺省显示为缺省大小
GetParentFrame()->RecalcLayout();
ResizeParentToFit();
// TODO: 在此添加专用代码和/或调用基类
}
//////////////////////////////////
将其中的m_form, 换成指针有没有问题了. 请问窗口关闭时其窗口类中的成员变量和成员指针变量的销毁是如何处理的, 原则是什么?

解决方案 »

  1.   

    窗口销毁的时候判断一下m_form的窗口是否建立了。若是的话先销毁m_form
      

  2.   

    如你所说, 我加了
    BOOL CChildFrame::DestroyWindow()
    {
    // TODO: 在此添加专用代码和/或调用基类

    if( m_form.IsWindowVisible() )
    {
    m_form.DestroyWindow();
    }
    return CMDIChildWnd::DestroyWindow();
    }执行时在m_form.DestroyWindow();出错!
      

  3.   

    if(m_form.IsWindow())
    {
      m_form.DestroyWindow();
    }
      

  4.   

    m_form.IsWindow()这个是ATL中函数. MFC中没有吧
      

  5.   

    如何这样的话, 也出错
    BOOL CChildFrame::DestroyWindow()
    {
    // TODO: 在此添加专用代码和/或调用基类

    m_form.DestroyWindow();

    return CMDIChildWnd::DestroyWindow();
    }错误信息为:
    Debug Assertion Failed!
    Program:d:\test\cpp\formviewtest\formviewtest\debug\FormViewTest.exe
    File: dbgheap.c
    Line: 1132Expression: _CrtIsValidHeapPointer(pUserData)....
      

  6.   

    在m_from构造的时候将成员清0,在消毁的时候判断IsWindow(m_form.m_hWnd)则时行消毁.还有注意不要多次消毁,检查一下m_form中的析构函数.    /*
             * If this ASSERT fails, a bad pointer has been passed in. It may be
             * totally bogus, or it may have been allocated from another heap.
             * The pointer MUST come from the 'local' heap.
             */
            _ASSERTE(_CrtIsValidHeapPointer(pUserData));
      

  7.   

    ??你的意思是?
    CForm::CForm()
    : CFormView(CForm::IDD)
    {
    m_hWnd = 0;
    }BOOL CChildFrame::DestroyWindow()
    {
    if( IsWindow(m_form.m_hWnd) )
    m_form.DestroyWindow();

    return CMDIChildWnd::DestroyWindow();
    }CForm 和CChildFrame 析构中无代码
    结果一样.请给些代码, 多谢!!!
      

  8.   

    BOOL CChildFrame::DestroyWindow()
    {
    if( m_form.m_hWnd || IsWindow(m_form.m_hWnd) )
    m_form.DestroyWindow();

    return CMDIChildWnd::DestroyWindow();
    }
      

  9.   

    还是一样, 出现错误. 在m_form.DestroyWindow().如果将CForm 改成CView的子类, 就没有问题.如果将CChildFrame中的m_form改成指针*m_pForm, 也没有问题.
      

  10.   

    按道里来说CForm类不由你自已来管理的,应该由文档模板来管理的
      

  11.   

    没有文档模板.是一个MDI的非Doc/View应用程序
      

  12.   

    CView objects delete themselves when the windows they are attached to are destroyed by overriding PostNcDestroy and executing a delete this statement. Override again to prevent his behavior if you plan to use it as a stack variable.
      

  13.   

    CView objects delete themselves when the windows they are attached to are destroyed by overriding PostNcDestroy and executing a delete this statement. Override again to prevent his behavior if you plan to use it as a stack variable.
    ------------------------------------------------------------------------
    That is point.Thanks!
      

  14.   

    留意是否内存释放干净,其实m_form不需要在PostNcDestory()中删除自己,另外一个需要