MFC程序打开文件对话框出错的问题解决

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/anyisoft/article/details/47114383

前几天从网上下了个图像分析的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本身来说还是没问题的,由于安装多个开发环境造成的冲突是本问题出现的原因。


展开阅读全文

没有更多推荐了,返回首页