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",果然。第一條就命中
http://blog.titilima.com/show-590-1.html。這裏已有答案。
感謝作者李馬先生 :-)
原因講的非常清楚了。
但是怎麽改呢,難道去動vs 的源代碼。
當然VS的源代碼也是能夠改的。只是呢,通過定義追溯文件發現到了
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include 以下
當初MFC4.2 的年代應該還沒有v7.1 的版本號呀,去看下文件夾設定吧
v7.1 的include 在最上面。
果斷移到最下。所有又一次生成,沒問題啦,奧也。
自已是否動過這個設定記不清了。亦或是後來裝VS2010或DDK的時候影響了??
總之呢,我們能夠覺得。就VC6本身來說還是沒問題的,因為安裝多個開發環境造成的沖突是本問題出現的原因。
??MFC程序打開文件對話框出錯的問題解決