MFC程式開啟檔案對話框出錯的問題解決
前幾天從網上下了個影象分析的mfc小程式,是VC6的
用VC6在本地編譯生成都沒問題,執行起來彈出一個未處理的錯誤,程式崩潰退出。
想起來原來遇到過開啟檔案對話方塊方面的問題,當時專案時間緊張未能深究。
這次要好好看下這個問題。
具體做法就是深入細緻的跟蹤、跟蹤、跟蹤。。。
應用程式碼,跟進
MFC的程式碼,跟進
Alt+8調出反彙編,跟進。。。
反覆多次重複追蹤、縮小目標,確定問題是:在CFileDialog 的解構函式中,呼叫了CString 的解構函式,
恰恰是析構CSring 出錯了。
CFileDialog 的定義如下,就是析構這個 m_strFilter 出錯的。
class CFileDialog : public CCommonDialog
{
DECLARE_DYNAMIC(CFileDialog)
public:
// Attributes
OPENFILENAME m_ofn; // open file parameter block
// Constructors
CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL);
......省略n 多行
protected:
BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save
CString m_strFilter; // filter string
// separate fields with '|', terminate with '||\0'
TCHAR m_szFileTitle[64]; // contains file title after return
TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return
OPENFILENAME* m_pofnTemp;
virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
};
發現這裡面找的m_strFilter 的地址就不對
0012F7EC 是 CFileDialog 例項的地址
析構m_strFilter 找的是0012F8A8,再執行就會出錯,去這個地址瞄一眼,感覺就不對啊
於是在建構函式跟蹤時,發現m_strFilter 的地址是0012F89C
比較兩次合成ecx 中m_strFilter的this指標時,很明顯不同
add ecx 0b0h ;構造時
add ecx 0bch ;析構時
喔喔,算偏移嘛,怎麼會不一樣呢,這個,再花時間研究下吧。
嗐呀,說不定有人研究過啦。靈機一動,bing 下"add ecx 0b0h",果然,第一條就命中
原因講的很清楚了。
可是怎麼改呢,難道去動vs 的原始碼。
當然VS的原始碼也是可以改的,不過呢,通過定義追溯檔案發現到了
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include 下面
當初MFC4.2 的年代應該還沒有v7.1 的版本呀,去看下目錄設定吧
v7.1 的include 在最上面。
果斷移到最下,全部重新生成,沒問題啦,奧也。
自已是否動過這個設定記不清了,亦或是後來裝VS2010或DDK的時候影響了??
總之呢,我們可以認為,就VC6本身來說還是沒問題的,由於安裝多個開發環境造成的衝突是本問題出現的原因。