程序设计中,派生出自己的按钮窗口,并且使用new 和creat函数创建了几个按钮,然后单击按钮弹出,一个模式对话框。
按钮中有自己的定时函数,当定时条件满足时,调用关闭并清除这个按钮窗口,在PostNcDestroy() 
中delete this;删除按钮,但是此时不能关闭模式对话框,会出现
access violation 错误提示,错误定位到
LRESULT CWnd::Default()
{
// call DefWindowProc with the last message
_AFX_THREAD_STATE* pThreadState = _afxThreadState.GetData();
return DefWindowProc(pThreadState->m_lastSentMsg.message,
pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam);
}CWnd::Default() line 257 + 29 bytes
按钮的清除是这样实现的
void CRoundButton::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
TRACE1("timer%d",nIDEvent);
//find overtime destroy this button
//time is equal to DELAYTIME Micro at the start of file
//不能在这里关闭对话框,否则在按钮清除的过程中会出错,
//因为按钮清除时会向模式对话框发出消息,而此时对话框已经清除
//消息无法处理导致出错
HWND hWnd=::FindWindow(NULL,"数据显示");
if (hWnd!=NULL)
{
::SendMessage(hWnd,WM_CLOSE,NULL,NULL);
}
DestroyWindow();
}
void CRoundButton::PostNcDestroy() 
{
// TODO: Add your specialized code here and/or call the base class

CControlButton::PostNcDestroy();
delete this;
}
请各位老手帮忙看看解决,是什么愿因造成的,谢谢

解决方案 »

  1.   

    Create创建的非模态的吧?!
    你可以用GetSafeWnd()判断是否已经创建,如果创建了,直接ShowWindow(1)就可以了
    if(dlg.GetSafeWnd() == NULL)
      dlg.Create(...);
    dlg.ShowWindow(1);
      

  2.   

    模态窗口下应该后创建的窗口先销毁。另外WM_TIMER里面调用Destory之前应该设置一个标志变量,后续的WM_TIMER检查这个标志变量以避免重复进入销毁过程。
      

  3.   

    我是在每个按钮类的成员函数内设定定时器的,定时器消息的处理函数也是按钮类的成员函数,我觉得销毁按钮自身之后,它对应的定时器就不会再处理消息了,所以在destory之前设置标志似乎没必要。现在的问题问题仅出现在我打开模式对话框后,又定时销毁按钮时,如果我不单击按钮(在按钮鼠标按下消息中)打开模式对话框,到时间后销毁按钮程序是没有问题的,我也想在按钮销毁前先关闭模式对话框,但是当我打开对话框之后,定时时间到了,在定时器消息处理函数中销毁按钮时,尽管我在destroywindow()之前已经向模式对话框发wm_close消息或者通过enddialog()函数关闭对话框,但是在程序自动关闭对话框之后,在我退出整个程序时(退出一个sdi程序),程序会出现access violation,0x0000005的错误提示,错误定位到LRESULT CWnd::Default(),如果跟踪进去实际问题出在DefWindowProc(pThreadState->m_lastSentMsg.message,
    pThreadState->m_lastSentMsg.wParam, pThreadState->m_lastSentMsg.lParam);里面的谋些汇编语言中,此时堆栈里面 pThreadState->m_lastSentMsg的值是0x00000000202这样的值。
      

  4.   

    在CRoundButton::OnTimer里这样: HWND hDlg = ::FindWindowW(NULL,_T("Dialog"));
    if(hDlg)
    {
    if(::SendMessageW(hDlg,WM_COMMAND,MAKEWORD(IDOK,BN_CLICKED),(LPARAM)this->GetSafeHwnd()))
    {
    KillTimer(1);//设置Timer的IDEvent为1;
    DestroyWindow();
    } } //CButton::OnTimer(nIDEvent);
      

  5.   

    HWND hDlg = ::FindWindowW(NULL,_T("Dialog"));
    这里_T("Dialog")是弹出模态对话框的标题。我已经试过,可以的。