Proper Destroy semantics for MFC based modeless dialogs (Sorry, a bit Long) 
Author Message
 Proper Destroy semantics for MFC based modeless dialogs (Sorry, a bit Long)

Hi,

I need some help in determining how to destroy (and maybe properly locate
and initialize) modeless dialog windows.

First the problem symptoms, then I will describe my application structure,
and hopefully my newbie error will pop right out to somebody...

The error:
I am receiving the following message (many times) when I go to exit the
application (either through using the File|Exit command or the main window
close box) in the Dev Studio Debug window:
-----------
Warning: calling DestroyWindow in CWnd::~CWnd; OnDestroy or PostNcDestroy in
derived class will not be called.
Warning: calling DestroyWindow in CDialog::~CDialog --
 OnDestroy or PostNcDestroy in derived class will not be called.
------------

I have traced the occurrence to destroy window call in the following stock
MFC code:
void CDocument::OnCloseDocument()

// must close all views now (no prompting) - usually destroys this

{

    // destroy all frames viewing this document

    // the last destroy may destroy us

    BOOL bAutoDelete = m_bAutoDelete;

    m_bAutoDelete = FALSE; // don't destroy document while closing views

    while (!m_viewList.IsEmpty())

    {

        // get frame attached to the view

        CView* pView = (CView*)m_viewList.GetHead();

        ASSERT_VALID(pView);

        CFrameWnd* pFrame = pView->GetParentFrame();

        ASSERT_VALID(pFrame);

        // and close it

        PreCloseFrame(pFrame);

        pFrame->DestroyWindow();

        // will destroy the view as well

    }

    m_bAutoDelete = bAutoDelete;

    // clean up contents of document before destroying the document itself

    DeleteContents();

    // delete the document if necessary

    if (m_bAutoDelete)

    delete this;

Quote:
}

The first pass through the above while loop, my CMainFrame window and all
the modeless dialog child windows of my application close, but I get the
above mentioned warning.  Also, even though there is only 1 view, for some
reason it does not get removed from the document's view list, so a 2nd
interation of the list is made, which then hits the ASSERT_VALID(pFrame) and
exceptions.  I conjecture that I am either not locating my modeless dialog
child window classes in the right place, not providing a needed virtual
function message handler, or not calling a needed termination function, but
I can't figure out what....

Now on my apps construction, in case this gives the info needed to assess
the problem:
I have an SDI app with a doc class named CStatusDoc, and a view class named
CStatusView.  In my derived CWinApp object, I do the standard mantra:

CMyApp::InitInstance(...)
{
    ...
    CSingleDocTemplate* pDocTemplate;

    pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,

                                          RUNTIME_CLASS(CStatusDoc),

                                          RUNTIME_CLASS(CMainFrame),

                                          RUNTIME_CLASS(CStatusView) );

    AddDocTemplate(pDocTemplate);

    // Parse command line for standard shell commands, DDE, file open

    CCommandLineInfo cmdInfo;

    ParseCommandLine(cmdInfo);

    // Dispatch commands specified on the command line

    if (!ProcessShellCommand(cmdInfo))

        return FALSE;

    ...

Quote:
}

My CMainFrame class contains members, all derived from CDialog, for the
modeless dialogs which I wish to create.  There are several, but I will only
show the pruned down associated code for one of them (CShutterCtl) here:

class CMainFrame : public CFrameWnd

{

public:

    virtual ~CMainFrame();

protected:

    CMainFrame();

    DECLARE_DYNCREATE(CMainFrame)

// Overrides

    // ClassWizard generated virtual function overrides

    //{{AFX_VIRTUAL(CMainFrame)

public:

    virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

    //}}AFX_VIRTUAL

// Implementation

public:

void InitialShowWindow(UINT nCmdShow);

// Generated message map functions

protected:

    CShutterCtl m_shutterCtl;

    //{{AFX_MSG(CMainFrame)

    afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

    ...

    afx_msg void OnClose();

    //}}AFX_MSG

    ...

    DECLARE_MESSAGE_MAP()

Quote:
};

I create the windows window of the CShutterCtl in the CMainFrame::OnCreate()
handler:

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

{

    if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

        return -1;

    if (!m_wndStatusBar.Create(this) ||

        !m_wndStatusBar.SetIndicators(indicators,

        sizeof(indicators)/sizeof(UINT)))

    {

        TRACE0("Failed to create status bar\n");

        return -1; // fail to create

    }

    // Create and show the Shutter window...

    m_shutterCtl.Create(IDD_ShutterCtl);

    m_shutterCtl.InitialShowWindow(SW_SHOW);

    m_bShutterCtlVisible = true;

    ...

Quote:
}

I have an CMainFrame::OnClose() routine:

void CMainFrame::OnClose()

{

    // Close down the child windows...

    m_shutterCtl.SendMessage(WM_CLOSE);

    ...

    CFrameWnd::OnClose();

Quote:
}

Other than that, I don't think I have any overrides or handlers that have
been written by me related to the application close-down.

Thanks greatly for any help.  If you can CC any replies to me directly as
well, that would be great.

Mark Greenman

Space Dynamics Laboratory




Tue, 25 Mar 2003 03:00:00 GMT  
 
 [ 1 post ] 

 Relevant Pages 

1. Proper Destroy Semantics with MFC modeless dialogs

2. Modeless dialog based MFC app?

3. Destroy Dialog for Dialog based app

4. Modeless dialog in a dialog-based app

5. Destroy modeless dialog in InitDialog

6. Destroying a modeless dialog.

7. Timer destroys Tooltips in modeless Dialog!?

8. dialog based app making modeless dialogs

9. How do I destroy a modeless dialog?

10. Modeless Dialog Destroy Problem

11. Destroying multiple modeless dialogs.

12. Access violation in release version when destroying modeless dialog box

 

 
Powered by phpBB® Forum Software