1. 程式人生 > >MFC程式開啟檔案對話框出錯的問題解決

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本身來說還是沒問題的,由於安裝多個開發環境造成的衝突是本問題出現的原因。