这两天发现了一个小问题,经过一上午的排查终于找到了问题的原因——Windows 7的API函数GetOpenFileName竟然有BUG!

请参考下面的MFC代码:

CFileDialog dlg(TRUE);

dlg.m_ofn.lpstrInitialDir = _T("c:\\");

dlg.DoModal();

这段代码的含义是通过"文件选择对话框"选择一个文件,并且"文件选择对话框"的初始目录是C:\。

使用VC++2010编译上面的代码,在64位Windows 7上的运行结果一切正常——"文件选择对话框"的初始目录一定是C:\

使用VC++6.0编译上面的代码,在64位Windows 7上的运行结果为:"文件选择对话框"的初始目录并不一定是C:\,而是上次选择文件的目录!

查看MFC代码,就知道问题的所在了:VC++6.0的CFileDialog会调用GetOpenFileName或GetSaveFileName打开"文件选择对话框";而VC++2010会判断Windows的版本。如果是Vista以下(不含Vista)版本则会调用GetOpenFileName或GetSaveFileName;如果是Vista以上(含Vista)版本则会通过COM接口IFileOpenDialog或IFileSaveDialog打开"文件选择对话框"。

为了验证GetOpenFileName函数的正确性,特编写了如下代码:

TCHAR                szFile[MAX_PATH] = {'\0'};

OPENFILENAME    ofn;

memset(&ofn,0,sizeof(ofn));

ofn.lStructSize        =    sizeof(ofn);

ofn.lpstrFile        =    szFile;

ofn.nMaxFile        =    MAX_PATH;

ofn.lpstrInitialDir    =    _T("c:\\");

ofn.Flags        =    OFN_HIDEREADONLY | OFN_EXPLORER

|    OFN_ENABLESIZING;

GetOpenFileName(&ofn);

使用VC++2010编译上面的代码,执行结果也不正常了:"文件选择对话框"的初始目录并不一定是C:\,而是上次选择文件的目录!这说明:在Windows 7操作系统下,GetOpenFileName函数未能识别参数ofn.lpstrInitialDir,这应该是一个BUG。

结论:VC++6.0的MFC类CFileDialog通过GetOpenFileName或GetSaveFileName显示"文件选择对话框"。但是这两个函数在Windows 7的实现有BUG,导致初始目录不是设定的值。解决这个问题有两个办法:一是舍弃VC++6.0,改用VC++2010。这样处理最简单,美中不足就是程序只能运行在Windows XP及其以上版本的Windows下,无法在Windows 98/Me/2000上运行;二是改进VC++2010的CFileDialog代码,使得VC++6.0能够编译、使用。

另一个BUG:在Windows 7上使用GetOpenFileName选择一个文件后,该文件所在目录即被锁定。目录被锁定就无法被删除了,退出整个程序后目录锁定才会被解除。

慎用GetOpenFileName的更多相关文章

  1. 慎用mutableCopy

    因为逻辑需要,我在present到一个页面时,将一个存放uiimage的数组mutablecopy了过去(因为再返回的时候防止对数组做了改动),时间长了也忘了这事儿,后来发现添加多张图片上传时,app ...

  2. TODO:Golang UDP连接简单测试慎用Deadline

    TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...

  3. Object.Destroy慎用

    Object.Destory Destory(Object)并没有立刻,马上,及时的删除这个Object. 举例 在使用NGUI的Table或Grid进行布局时,就需要注意了:尽量不要使用Destro ...

  4. Effective_java之二:慎用重载函数

    每周写一篇技术博客的愿望一直没实现, 从这周開始每周五晚10点是写博客的时间 OOP的一个重要特性就是多态,实现多态的目的有多种途径.比方:重载overload.重写overwite.面向接口编程等等 ...

  5. [改善Java代码]慎用动态编译

    建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...

  6. php编译参数注解--不明白许多参数的作用 慎用 –with-curlwrappers参数

    在Linux下安装PHP,源代码方式安装,总需要配置很多参数.这里列出常用配置参数,并详细用中文解释说明了.给大家一些参考 编译PHP的时候慎用 –with-curlwrappers参数 ./conf ...

  7. 慎用StringEscapeUtils.escapeHtml步骤

    慎用StringEscapeUtils.escapeHtml方法[转] 推荐使用Apache commons-lang的StringUtils来增强Java字符串处理功能,也一直在项目中大量使用Str ...

  8. webapp 慎用setInterval、setTimeout

    其实这片文章刚开始我啥也没写的,但也有20多的访问量,所以觉得大家还是比较关注这个问题,所以找机会写下. 问题的引出: 为什么我说的时webapp中慎用setInterval.setTimeout, ...

  9. C/C++中慎用宏(#define)

    宏的定义在程序中是非常有用的,但是使用不当,就会给自身造成很大的困扰.通常这种困扰为:宏使用在计算方面. 本例子主要是在宏的计算方面,很多时候,大家都知道定义一个计算的宏,对于编译和编程是多么的有用. ...

随机推荐

  1. Codeforces Round #260 (Div. 2) C

    Description Alex doesn't like boredom. That's why whenever he gets bored, he comes up with games. On ...

  2. AutoIt实现selenium上传文件

    1,安装autoIt 2,工程中建文件夹,例如:script,将autoit 复制到该文件夹,并且编辑视频所在的文件夹的路径,编辑"au3"格式的文件 3,编辑完成后生成EXE文件 ...

  3. Eclipse启动提示Failed to load the JNI shared library JVM.dll

    一.出现了上述问题解决办法 1.查看eclipse.ini文件 看看eclipse环境架构需要的是什么. plugins/org.eclipse.equinox.launcher.win32.win3 ...

  4. Spring源码之SimpleAliasRegistry解读(一)

    Spring源码之SimpleAliasRegistry解读(一) 阅读spring源码中org.springframework.core.SimpleAliasRegistry类时发现该类主要是使用 ...

  5. SQL将金额转换为汉子

    -- ============================================= -- Author: 苟安廷 -- Create date: 2008-8-13 -- Descrip ...

  6. 【原文】前端程序员必须知道的高性能Javascript知识

    原文:前端程序员必须知道的高性能Javascript知识 想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影. 本文会分享一些高效的JavaScript的最佳 ...

  7. Download file using libcurl in C/C++

    http://stackoverflow.com/questions/1636333/download-file-using-libcurl-in-c-c #include <stdio.h&g ...

  8. Servlet技术

    Java Applet和Java Servlet都有一个共同特点: 它们都不是独立的应用程序,都没有main( )方法: 它们都不是由用户或者程序员直接调用,而是生存在容器中,由容器管理,Applet ...

  9. [Effective Java]第十章 并发

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  10. FJNU 1156 Fat Brother’s Gorehowl(胖哥的血吼)

    FJNU 1156 Fat Brother’s Gorehowl(胖哥的血吼) Time Limit: 1000MS   Memory Limit: 257792K [Description] [题目 ...