[英]Access violation at destructor call from CMainFrame after end of mfc application
我正在為嵌入式Compact開發MFC應用程序。 目前,我嘗試添加一個對話框來關閉程序。 我的問題是我在CMainFrame的析構函數調用中遇到訪問沖突。 為了更清楚起見,首先提供了一段代碼。 這是我的應用程序的起點:
SWinApp.h
class SWinApp : public CWinApp
{
public:
SWinApp();
~SWinApp(){};
public:
virtual BOOL InitInstance();
protected:
DECLARE_MESSAGE_MAP()
};
SWinApp.cpp
SWinApp::SWinApp():CWinApp()
{
}
BOOL SWinApp::InitInstance()
{
CRuntimeClass* pRuntimeClass = RUNTIME_CLASS( SMainFrame );
CObject* pObject = pRuntimeClass->CreateObject();
ASSERT( pObject->IsKindOf( RUNTIME_CLASS( SMainFrame ) ) );
m_pMainWnd = (SMainFrame*)pObject;
m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);
return FALSE; // this is the next executed line after the access violation
}
BEGIN_MESSAGE_MAP(SWinApp, CWinApp)
END_MESSAGE_MAP()
SMainFrame.h
class SMainFrame : public CFrameWnd
{
DECLARE_DYNCREATE(SMainFrame)
protected:
SMainFrame();
~SMainFrame();
DECLARE_MESSAGE_MAP()
public:
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg BOOL OnEraseBkgnd(CDC* pDC);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
afx_msg LRESULT OnDialogReady(WPARAM wParam, LPARAM lParam);
afx_msg void OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized);
CurrentData* GetCurrentData(){return this->currentData;};
Configuration* GetConfiguration(){return this->configuration;};
private:
BOOL m_shown;
CurrentData* currentData;
Configuration* configuration;
std::map<UINT, CDialog*> views;
UINT currentID;
};
SMainFrame.cpp
IMPLEMENT_DYNCREATE(SMainFrame, CFrameWnd)
SMainFrame::SMainFrame()
{
CString appName;
appName.LoadStringW(IDS_APP_NAME);
Create(NULL, appName);
m_shown = FALSE;
this->configuration = new Configuration();
this->currentData = new CurrentData();
this->currentID = IDD_MAIN_MENU_DIALOG;
views.insert(std::make_pair(IDD_MAIN_MENU_DIALOG, new MainMenuDialog(this->configuration, this->currentData)));
// There are more dialogs but for tests one is enough
}
SMainFrame::~SMainFrame()
{
for(auto iterator:views)
{
delete iterator.second;
}
delete this->configuration;
delete this->currentData; //Is executed properly
} // After this line an access violation occurres...
BEGIN_MESSAGE_MAP(SMainFrame, CFrameWnd)
ON_MESSAGE(WM_USER_DIALOG_READY, &SMainFrame::OnDialogReady)
ON_WM_CREATE()
ON_WM_ACTIVATE()
END_MESSAGE_MAP()
// SMainFrame message handlers
int SMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ModifyStyle(WS_CAPTION, 0, SWP_DRAWFRAME | SWP_NOZORDER );
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
return 0;
}
afx_msg LRESULT SMainFrame::OnDialogReady(WPARAM wParam, LPARAM lParam)
{
DialogThreadParams* params = (DialogThreadParams*)lParam;
this->currentID = params->nextDialogID;
m_shown = FALSE;
this->ActivateFrame();
return 0;
}
BOOL SMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
if( !CFrameWnd::PreCreateWindow(cs) )
return FALSE;
cs.dwExStyle &= ~WS_EX_CLIENTEDGE | SWP_DRAWFRAME;
cs.style = WS_EX_CLIENTEDGE;
return TRUE;
}
void SMainFrame::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
{
if(m_shown == FALSE)
{
m_shown = TRUE;
if(IsWindow(views[currentID]->m_hWnd))
{
views[currentID]->SetFocus();
}
else
{
views[currentID]->DoModal();
}
}
CFrameWnd::OnActivate(nState, pWndOther, bMinimized);
}
MainMenuDialog是從StandardDialog繼承的類,該類是從CDialog繼承的。 我現在只發布部分代碼,因為這篇文章已經太長了(如果您需要更多信息,請告訴我哪一部分可能很有趣)...該對話框提供了關閉名為ShutdownDialog的應用程序的可能性(僅繼承自CDialog),並存儲為MainMenuDialog的私有變量:
ShutdownDialog* shutdownDialog;
在MainMenuDialog的構造函數中創建:
this->shutdownDialog = new ShutdownDialog();
我在單擊按鈕時顯示對話框:
void MainMenuDialog::OnClickedShutdownButton()
{
shutdownDialog->DoModal();
}
並在MainMenuDialog的析構函數中刪除:
MainMenuDialog::~MainMenuDialog()
{
delete shutdownDialog;
}
在ShutdowDialog中,我用以下代碼關閉應用程序:
AfxGetMainWnd()->PostMessage(WM_CLOSE);
EndDialog( 0 );
在此之前,一切正常。 該應用程序開始銷毀對象。 但是在完成對SMainFrame析構函數的調用后,我遇到了訪問沖突。 該程序不會停止,僅在“輸出”窗口中顯示一行。 它以語句“ return FALSE;”繼續。 在SWinApp InitInstance()中。
我知道兩次刪除對象或使用指針(其中依賴對象已被破壞)時都會發生訪問沖突,但是我無法弄清這里出了什么問題。 另外我不得不說SWinApp和SMainFrame是由一位同事創建的,我用SMainFrame中的對話框修改了零件。 我認為m_pMainWnd可能是問題,因為在對SMainFrame的析構函數調用之后,它必須是無效的指針。 所以我試着:
SMainFrame::~SMainFrame()
{
for(auto iterator:views)
{
delete iterator.second;
}
delete this->configuration;
delete this->currentData;
AfxGetApp()->m_pMainWnd = NULL;
}
但是違例仍然發生...我搜索了Callstack窗口,但在視圖選項卡下找不到它。 很抱歉這是否太具體...但是自從幾個小時以來我一直在掙扎,不知道我可以嘗試...歡迎任何幫助!
更改AfxGetMainWnd()->PostMessage(WM_CLOSE);
到::PostQuitMessage( 0 );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.