Re: Crash bug in CDialog::DoModal
http://blogs.msdn.com/oldnewthing/archive/2005/02/23/378866.aspx
http://blogs.msdn.com/oldnewthing/archive/2005/03/04/385100.aspx
--
Sheng Jiang
Microsoft MVP in VC++
"Srivatsan Vat Raghavan" <SrivatsanVatRaghavan@discussions.microsoft.com>
wrote in message news:839D9A11-F4F4-4234-885C-D38D493AE2F1@microsoft.com...
Hi all,
this is related to a post i made last week.
To summarize i have a internal network monitoring app that we're currently
adding support for ups devices. So i have a popup modal message box
(using this class from codeproject ->
http://www.codeproject.com/dialog/MessageBoxDialog.asp) which tells the
user
they have X seconds to shut everything down or the server will do it for
them.
This has a timeout and the [OK=X] button that gets updated via OnTimer.
the server can send a "all clear" packet and in that case i want to kill
the
existing messagebox, and popup a new messagebox saying "all clear" with a
10second timeout.
This mostly works, but about 1/3 of the time i get a crash in DoModal
after
the 2nd dialog box hits it timeout and disappears and i get a crash in
DoModal from the FIRST dialog box which causes my app to crash.
the code is below, while tryign to debug it i have this horrible feeling
it's cause it appears runmodalloop runs in seperate thread and my thread
is
trying to delete the cdialog ptr from under mfc's feet.
void CFMainUIDlg::OnReportUPSDeviceAlert( const Socket1Packet &packet)
{
BIT_ICD::STRUCT_REPORT_UPS_ALERT status;
int length = sizeof(BIT_ICD::STRUCT_REPORT_UPS_ALERT);
const char* body = packet.m_PacketBody.c_str();
memcpy( &status, body, length);
if( m_bKillMessageBox )
{
if(m_pDlgMessageBox)
{
Sleep(500);
delete m_pDlgMessageBox;
m_pDlgMessageBox = 0;
m_bKillMessageBox = false;
}
}
UI::ConnInfoIterator i = m_connections.find( status.IP );
if ( i == m_connections.end() )
return;
BIT_ICD::UPSInfo ups;
ups.eStatus = i->second->s.eUPSStatus;
strncpy( ups.IP, i->first.c_str(), i->first.length() );
strncpy( ups.sDeviceName, i->second->sPrettyName.c_str(),
i->second->sPrettyName.length() );
UpdateTreeItem( ups );
if ( !m_pDlgMessageBox )
{
if ( status.eStatus == BIT_ICD::UPS_POWER_LOSS )
{
CString upsName = i->second->sPrettyName.c_str();
CString strTitle;
strTitle.Format(UI::sUPSStatusMessagePowerLossAlertTitle.c_str(),
upsName.GetBuffer() );
CString strMessage(UI::sUPSStatusMessagePowerLossAlertMessage.c_str());
// Create a message box dialog.
m_pDlgMessageBox = new CMessageBoxDialog(this, strMessage, strTitle,
MB_OK | MB_ICONEXCLAMATION);
// Set the timeout for the message box.
m_pDlgMessageBox->SetTimeout(status.iWaitingTime, false);
// Display the dialog.
INT_PTR nresult = m_pDlgMessageBox->DoModal();
delete m_pDlgMessageBox;
m_pDlgMessageBox = NULL;
}
}
else
{
//dialog box exists, and we got an updated ups status. so we kill the box.
if( ( status.eStatus == BIT_ICD::UPS_NORMAL) || (status.eStatus ==
BIT_ICD::UPS_CHARGING ) )
{
Sleep(500);
//m_pDlgMessageBox->EndDialog( IDOK);
m_bKillMessageBox = true;
CMessageBoxDialog d(this,
UI::sUPSStatusMessagePowerRestoreMessage.c_str(),
UI::sUPSStatusMessagePowerRestoreTitle.c_str(), MB_OK |
MB_ICONEXCLAMATION );
d.SetTimeout( 10, false);
int nResult = (int) d.DoModal();
}
}
}