Hi
From a MainDlg I dynamically create a SubDlg for showing sort of a work progress. At the end the user can close the SubDlg.
In OnClose I post/send a message to the MainDlg to indicate that the SubDlg closes. The MainDlg does some clean-up work then and the SubDlg closes and deletes itself.

Problem: this all workes well compiled as Debug Version, but crashes when compiled as Release (no matter whether MFC used statically or dynamically).
Where is the crash: When posting/sending the message from the SubDlg to the Parent (MainDlg, the MainDlg exeutes the clean-up work (OnMessageCleanUp), but if the execution returns to where the message was sent/posted and wants to continue, it crashes before the next line in the SubDlg is executed.
When I do not send/post a message and call the appropriate function (declared as public) directly from within SubDlg and its parent member, there's no problem.

The code looks as follows:

#if !defined(AFX_MAINDLG_H__27D8CA5A_A1E7_4549_9735_C4DD57694768__INCLUDED_)
#define AFX_MAINDLG_H__27D8CA5A_A1E7_4549_9735_C4DD57694768__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// MainDlg.h : header file
//

// Include for the udownloader interfaces

#include "SubDlg.h"

/////////////////////////////////////////////////////////////////////////////
// CMainDlg dialog

class CMainDlg : public CDialog
{
// Construction
public:
// CMutex m_mutexCloseProgressDlg;
void AbortDownload(BOOL bAbort = TRUE) { m_bAbortDownload = bAbort; }
CMainDlg(CWnd* pParent = NULL); // standard constructor

virtual ~CMainDlg();

// Dialog Data
//{{AFX_DATA(CMainDlg)
enum { IDD = IDD_CFGMGR_DIALOG };
//}}AFX_DATA

// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMainDlg)
//}}AFX_VIRTUAL

// Implementation
protected:
HICON m_hIcon;

// Generated message map functions
//{{AFX_MSG(CMainDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnClose();
afx_msg void OnDestroy();
afx_msg void OnBtnDownload();
//}}AFX_MSG
afx_msg void EndDownloadThread();
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnCloseSubDlg();

private:
BOOL m_bAbortDownload;
CSubDlg* m_pProgressDlg;
HANDLE m_hDownloadThread;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAINDLG_H__27D8CA5A_A1E7_4549_9735_C4DD57694768__INCLUDED_)



// MainDlg.cpp : implementation file
//

#include "StdAfx.h"
#include "Main.h"
#include "MainDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CMainDlg Download Thread

DWORD WINAPI DownloadThread(LPVOID pVoid)
{
CMainDlg* pParent = reinterpret_cast<CMainDlg*>(pVoid);

// pParent->MessageBox(_T("Start Download"));
Sleep(1000);
// pParent->MessageBox(_T("End Download"));

pParent->PostMessage(EV_END_DOWNLOAD_THREAD);

return 0;
} // DownloadThread(LPVOID pVoid)

/////////////////////////////////////////////////////////////////////////////
// CMainDlg dialog

CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMainDlg::IDD, pParent),
m_pProgressDlg(NULL), m_hDownloadThread(NULL), m_bAbortDownload(FALSE)
{
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
} // CMainDlg::CMainDlg(CWnd* pParent /*=NULL*/)

CMainDlg::~CMainDlg()
{
} // CMainDlg::~CMainDlg()

BEGIN_MESSAGE_MAP(CMainDlg, CDialog)
//{{AFX_MSG_MAP(CMainDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BTN_CLOSE, OnClose)
ON_WM_DESTROY()
ON_BN_CLICKED(IDC_BTN_DOWNLOAD, OnBtnDownload)
//}}AFX_MSG_MAP
ON_MESSAGE(EV_CLOSE_PROGRESS_DIALOG, OnCloseSubDlg)
ON_MESSAGE(EV_END_DOWNLOAD_THREAD, EndDownloadThread)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMainDlg message handlers

BOOL CMainDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

SIZE sizeDisplay;
sizeDisplay.cx = GetSystemMetrics(SM_CXFULLSCREEN)/2;
sizeDisplay.cy = GetSystemMetrics(SM_CYFULLSCREEN)/2;

// Because LoadData() uses SetRedraw function, the taskbar icon is not displayed
// This is fixed with the call of ShowWindow(SW_HIDE).
ShowWindow(SW_HIDE);

CRect rc;
GetWindowRect(&rc);
long lWidth = rc.Width();
long lHeight = rc.Height();
rc.left = sizeDisplay.cx - (lWidth / 2);
rc.top = sizeDisplay.cy - (lHeight / 2);
SetWindowPos(&wndTop, rc.left, rc.top, lWidth, lHeight, NULL);

return TRUE; // return TRUE unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CMainDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
CDialog::OnPaint();
} // CMainDlg::OnPaint()

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CMainDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CMainDlg::OnClose()
{
if (NULL != m_pProgressDlg)
{
// m_pProgressDlg->DestroyWindow();
// delete m_pProgressDlg;
m_pProgressDlg = NULL;
} // if (NULL != m_pProgressDlg)
OnOK();
} // CMainDlg::OnClose

void CMainDlg::OnDestroy()
{
CDialog::OnDestroy();
} // CMainDlg::OnDestroy()

void CMainDlg::OnBtnDownload()
{
// Check at the very beginning of Download, if the DownloadThread is still running
if (NULL != m_hDownloadThread)
{
EndDownloadThread();
} // if (NULL != m_hDownloadThread)

// Now that it's sure that the thread doesn't run, create the dialog and start the thread
m_pProgressDlg = new CSubDlg;
if (!m_pProgressDlg->Create(IDD_PROGRESS_DIALOG, this))
m_pProgressDlg = NULL;

EnableWindow(FALSE);
m_pProgressDlg->ShowWindow(SW_SHOW);

m_hDownloadThread = CreateThread(NULL, 0, &DownloadThread, (LPVOID)this, CREATE_SUSPENDED, NULL);

if (NULL == m_hDownloadThread)
{
CString str;
str.Format(_T("Error #%d: Could not initiate Download"), GetLastError());
MessageBox(str, _T("Error"), MB_ICONSTOP);

CloseHandle(m_hDownloadThread);
m_hDownloadThread = NULL;

m_pProgressDlg->DestroyWindow();
delete m_pProgressDlg;
m_pProgressDlg = NULL;

EnableWindow(TRUE);

return;
} // if

ResumeThread(m_hDownloadThread);
} // CMainDlg::OnBtnDownload()

void CMainDlg::OnCloseSubDlg()
{
MessageBox(_T("OnCloseSubDlg"));
// The SubDlg destroys and deletes itself.
// m_pProgressDlg->DestroyWindow();
// delete m_pProgressDlg;
MessageBox(_T("ProgressDlg = NULL"));
m_pProgressDlg = NULL;
EnableWindow(TRUE);
MessageBox(_T("Window enabled"));
} // CMainDlg::OnCloseSubDlg()

void CMainDlg::EndDownloadThread()
{
WaitForSingleObject(m_hDownloadThread, INFINITE);
CloseHandle(m_hDownloadThread);
m_hDownloadThread = NULL;
if (NULL != m_pProgressDlg)
m_pProgressDlg->SetAbortToClose();
} // CMainDlg::EndDownloadThread()



#if !defined(AFX_SUBDLG_H__30FDA0CE_7240_4C42_A779_7B593F2CC756__INCLUDED_)
#define AFX_SUBDLG_H__30FDA0CE_7240_4C42_A779_7B593F2CC756__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// SubDlg.h : header file
//

/////////////////////////////////////////////////////////////////////////////
// CSubDlg dialog

class CSubDlg : public CDialog
{
// Construction
public:
void SetAbortToClose();
CSubDlg(CWnd* pParent = NULL); // standard constructor

// Dialog Data
//{{AFX_DATA(CSubDlg)
enum { IDD = IDD_PROGRESS_DIALOG };
//}}AFX_DATA

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSubDlg)
protected:
virtual void PostNcDestroy();
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{{AFX_MSG(CSubDlg)
virtual void OnCancel();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

private:
BOOL m_bCloseNextTime;
BOOL m_bIsClosed;
};

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_SUBDLG_H__30FDA0CE_7240_4C42_A779_7B593F2CC756__INCLUDED_)



// SubDlg.cpp : implementation file
//

#include "StdAfx.h"
#include "Main.h"

#include "MainDlg.h"

#include "SubDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CSubDlg dialog

CSubDlg::CSubDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSubDlg::IDD, pParent), m_bCloseNextTime(FALSE), m_bIsClosed(FALSE)
{}

BEGIN_MESSAGE_MAP(CSubDlg, CDialog)
//{{AFX_MSG_MAP(CSubDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSubDlg message handlers

void CSubDlg::OnCancel()
{
if (!m_bCloseNextTime)
{
AfxGetApp()->LoadStandardCursor(IDC_WAIT);
((CMainDlg*)GetParent())->AbortDownload(TRUE);
} // if (m_bCloseNextTime)
else
{
m_bIsClosed = TRUE;
ShowWindow(SW_HIDE);
MessageBox(_T("Posting Message"));
// Send message doesn't work in Release Version (Debug okay)
((CMainDlg*)GetParent())->SendMessage(EV_CLOSE_PROGRESS_DIALOG);
// Direct call works in both versions (Debug and Release)
// ((CMainDlg*)GetParent())->OnCloseSubDlg();
MessageBox(_T("Message Posted"));
DestroyWindow();
} // else
} // CSubDlg::OnCancel()

void CSubDlg::SetAbortToClose()
{
MessageBeep(MB_OK);
m_bCloseNextTime = TRUE;
m_bIsClosed = FALSE;
GetDlgItem(IDCANCEL)->SetWindowText(_T("&Close"));
AfxGetApp()->LoadStandardCursor(IDC_ARROW);
} // CSubDlg::SetAbortToClose()

BOOL CSubDlg::OnInitDialog()
{
CDialog::OnInitDialog();

CRect rc;
GetWindowRect(&rc);
long lWidth = rc.Width();
long lHeight = rc.Height();

CRect rcParent;
((CMainDlg*)GetParent())->GetWindowRect(&rcParent);
long lParentWidth = rcParent.Width();
long lParentHeight = rcParent.Height();

rc.left = rcParent.left + ((lParentWidth - lWidth) / 2);
rc.top = rcParent.top + ((lParentHeight - lHeight) / 2);
SetWindowPos(NULL, rc.left, rc.top, lWidth, lHeight, NULL);

return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
} // CSubDlg::OnInitDialog()

void CSubDlg::PostNcDestroy()
{
delete this;
} // CSubDlg::PostNcDestroy()




Any suggestions, why the Send-/Post-Message doesn't work here? Is this a bug?
Many thanks for helping to solve this problem.
(previous/related thread: http://www.codeguru.com/cgi-bin/bbs/...sb=5&category=)