我正在開發嵌入式緊湊型mfc應用程序。目前我嘗試添加一個提供關閉程序的對話框。我的問題是,我從我的CMainFrame的析構函數調用得到訪問衝突。 首先讓它更清楚一段代碼。 這是我的應用程序的啓動點:在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的私有變量:在構造函數中創建MainMenuDialog的
ShutdownDialog* shutdownDialog;
:
this->shutdownDialog = new ShutdownDialog();
我展示一個按鈕單擊該對話框:
void MainMenuDialog::OnClickedShutdownButton()
{
shutdownDialog->DoModal();
}
而在MainMenuDialog的析構函數被刪除:
MainMenuDialog::~MainMenuDialog()
{
delete shutdownDialog;
}
在ShutdowDialog我關閉應用程序與這段代碼:
AfxGetMainWnd()->PostMessage(WM_CLOSE);
EndDialog(0);
直到這一切工作正常。應用程序開始銷燬對象。但是在完成對SMainFrame析構函數的調用之後,我得到一個訪問衝突。該程序不會停止,只是輸出窗口中的一行。它繼續聲明「返回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;
}
但仍然違反... occurres我 搜索調用堆棧窗口,但查看選項卡下無法找到它...... Sry基因爲這個長的帖子! 而且如果這太具體了......但是我幾個小時以來一直在掙扎,不知道我可以嘗試什麼......任何幫助都是值得歡迎的!
不做AfxGetApp() - > m_pMainWnd = NULL;該框架爲你做。 – 2015-03-25 11:08:51
你可以在調試模式下運行它,看看它崩潰的確切位置? – 2015-03-25 11:12:53
嘗試更改AfxGetMainWnd() - > PostMessage(WM_CLOSE);到:: PostQuitMessage(0); – 2015-03-25 11:19:02