crash after sendmessage to child dialog

hello.
i have a complex problem which lies deep in mfc and so i'm unable to find it myself.
i have an application were a part of the main window is used for other small windows which are shown as a control (only one at a time). all of these have the same baseclass CChildBaseDlg and are created at programstart and stored in an array of pointers to the baseclass.
[code]
m_pChildDlg[0] = new CBearbeitenDlg(&rc,this,&m_cDaten);
m_pChildDlg[1] = new CAutorQuelleDlg(&rc,this,&m_cDaten);
m_pChildDlg[2] = new CSuchenDlg(&rc,this,&m_cDaten);
m_pChildDlg[3] = new COptionenDlg(&rc,this,&m_cDaten);

m_pChildDlg[m_iAktWindow]->ShowWindow(SW_HIDE); // hide the old one
m_iAktWindow = newwindow;
m_pChildDlg[m_iAktWindow]->ShowWindow(SW_SHOW); // show the new window
[/code]
i have overwroted OnOK() in the mainwnd so that the function sends a userdefined message and the childwindow should react on it (for example create a new dataset).
[code]
#define WM_USER_ENTER WM_USER + 5
// main wnd
void CMainDlg::OnOK()
{
m_pChildDlg[m_iAktWindow]->SendMessage(WM_USER_ENTER);
}
// child window
BEGIN_MESSAGE_MAP(CBearbeitenDlg, CChildBaseDlg)
ON_MESSAGE(WM_USER_ENTER,OnNew)
//{{AFX_MSG_MAP(CBearbeitenDlg)
[/code]
the code works in debug mode, in but not in release mode.
the code crashes with all childwindows.
the function for the message is called and ready processed, and then the program crashes, but i don't know what is done after the funtion call. sendmessage waits until the message is processed, so it could be somthing in the main window.
here are the functions (top to down) shown in the debugger (the *-> is the pointer which the debugger shows), asmcode is not shown.
[code]
void* CMapPtrToPtr::GetValueAt(void* key) const
// find value (or return NULL -- NULL values not different as a result)
*->{
if (m_pHashTable == NULL)
return NULL;
-------------
void COleControlContainer::AttachControlSite(CWnd* pWnd)
{
ASSERT(this != NULL);
ASSERT(pWnd != NULL);

// If a matching control site exists, it's an OLE control
COleControlSite* pSite = (COleControlSite*)m_siteMap.GetValueAt(pWnd->m_hWnd);
*-> if (pSite != NULL)
{
-------------
CWnd* PASCAL CWnd::FromHandle(HWND hWnd)
{
CHandleMap* pMap = afxMapHWND(TRUE); //create map if not exist
ASSERT(pMap != NULL);
CWnd* pWnd = (CWnd*)pMap->FromHandle(hWnd);

#ifndef _AFX_NO_OCC_SUPPORT
pWnd->AttachControlSite(pMap);
#endif

ASSERT(pWnd == NULL || pWnd->m_hWnd == hWnd);
*-> return pWnd;
}
------------
BOOL CWinThread::PreTranslateMessage(MSG* pMsg)
{
ASSERT_VALID(this);

// if this is a thread-message, short-circuit this function
if (pMsg->hwnd == NULL && DispatchThreadMessageEx(pMsg))
return TRUE;

// walk from target to main window
CWnd* pMainWnd = AfxGetMainWnd();
if (CWnd::WalkPreTranslateTree(pMainWnd->GetSafeHwnd(), pMsg))
return TRUE;

// in case of modeless dialogs, last chance route through main
// window's accelerator table
if (pMainWnd != NULL)
{
CWnd* pWnd = CWnd::FromHandle(pMsg->hwnd);
*-> if (pWnd->GetTopLevelParent() != pMainWnd)
return pMainWnd->PreTranslateMessage(pMsg);
}
------------
BOOL CWinThread::PumpMessage()
{
ASSERT_VALID(this);

if (!::GetMessage(&m_msgCur, NULL, NULL, NULL))
{
#ifdef _DEBUG
if (afxTraceFlags & traceAppMsg)
TRACE0("CWinThread::PumpMessage - Received WM_QUIT.
");
m_nDisablePumpCount++; // application must die
// Note: prevents calling message loop things in 'ExitInstance'
// will never be decremented
#endif
return FALSE;
}
...
// process this message

*-> if (m_msgCur.message != WM_KICKIDLE && !PreTranslateMessage(&m_msgCur))
{
::TranslateMessage(&m_msgCur);
::DispatchMessage(&m_msgCur);
-------------
int CWnd::RunModalLoop(DWORD dwFlags)
{
ASSERT(::IsWindow(m_hWnd)); // window must be created
ASSERT(!(m_nFlags & WF_MODALLOOP)); // window must not already be in modal state

// for tracking the idle time state
BOOL bIdle = TRUE;
LONG lIdleCount = 0;
BOOL bShowIdle = (dwFlags & MLF_SHOWONIDLE) && !(GetStyle() & WS_VISIBLE);
HWND hWndParent = ::GetParent(m_hWnd);
m_nFlags |= (WF_MODALLOOP|WF_CONTINUEMODAL);
MSG* pMsg = &AfxGetThread()->m_msgCur;

// acquire and dispatch messages until the modal state is done
for (;;)
{
...
// phase2: pump messages while available
do
{
ASSERT(ContinueModal());

// pump message, but quit on WM_QUIT
*-> if (!AfxGetThread()->PumpMessage())
{
AfxPostQuitMessage(0);
return -1;
}
----------------
int CDialog::DoModal()
{
// create modeless dialog
AfxHookWindowCreate(this);
if (CreateDlgIndirect(lpDialogTemplate,
CWnd::FromHandle(hWndParent), hInst))
{
if (m_nFlags & WF_CONTINUEMODAL)
{
// enter modal loop
DWORD dwFlags = MLF_SHOWONIDLE;
if (GetStyle() & DS_NOIDLEMSG)
dwFlags |= MLF_NOIDLEMSG;
VERIFY(RunModalLoop(dwFlags) == m_nModalResult);
}

// hide the window before enabling the parent, etc.
*-> if (m_hWnd != NULL)
SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
}
}
[/code]
i don't understad why DoModal is called. in my opinion the child dlgs are modeless.
i hope somebody has an idea where the problem could be.
thank you very much and excuse the long code.
greetings. henry.

Comments

  • : [code]
    : m_pChildDlg[0] = new CBearbeitenDlg(&rc,this,&m_cDaten);
    : m_pChildDlg[1] = new CAutorQuelleDlg(&rc,this,&m_cDaten);
    : m_pChildDlg[2] = new CSuchenDlg(&rc,this,&m_cDaten);
    : m_pChildDlg[3] = new COptionenDlg(&rc,this,&m_cDaten);
    :
    : m_pChildDlg[m_iAktWindow]->ShowWindow(SW_HIDE); // hide the old one
    : m_iAktWindow = newwindow;
    : m_pChildDlg[m_iAktWindow]->ShowWindow(SW_SHOW); // show the new window
    : [/code]


    [blue]new just allocates the object and calls the class constructor. After that you have to call the class's Create() method to actually get it to create a valid window BEFORE calling ShowWindow().[/blue]

  • new just allocates the object and calls the class constructor. After that you have to call the class's Create() method to actually get it to create a valid window BEFORE calling ShowWindow().


    Create(CBearbeitenDlg::IDD,pParent) is called in the constructor of CBearbeitenDlg. and other operations with the windows work well. only the sendmessage in release mode makes problems, and the debugger shows the function MapPtrtoPtr as the reason. maybe it has soemthing to do with cleaning up the message from the queue or something. i hope you have another idea or a method how i can check the problem.
  • :
    : new just allocates the object and calls the class constructor. After that you have to call the class's Create() method to actually get it to create a valid window BEFORE calling ShowWindow().
    :
    :
    : Create(CBearbeitenDlg::IDD,pParent) is called in the constructor of CBearbeitenDlg. and other operations with the windows work well. only the sendmessage in release mode makes problems, and the debugger shows the function MapPtrtoPtr as the reason. maybe it has soemthing to do with cleaning up the message from the queue or something. i hope you have another idea or a method how i can check the problem.
    :


    One thing that has helped me find a release only bug like this in the past is to enable debug linking for the release build. Don't enable all the debugging stuff that makes it a debug build, just do it for the linker. Try running the debugger on the release build and it will say that it doesn't contain debugging info, so just enabling the linker debug option will allow you to debug a release build without all the other debug stuff like automatic variable initialization. It's worth a shot.


    [italic][blue]To understand recursive, first you need to understand recursive[/blue][/italic]

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories