慎用GetOpenFileName
这两天发现了一个小问题,经过一上午的排查终于找到了问题的原因——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的更多相关文章
- 慎用mutableCopy
因为逻辑需要,我在present到一个页面时,将一个存放uiimage的数组mutablecopy了过去(因为再返回的时候防止对数组做了改动),时间长了也忘了这事儿,后来发现添加多张图片上传时,app ...
- TODO:Golang UDP连接简单测试慎用Deadline
TODO:Golang UDP连接简单测试慎用Deadline UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interco ...
- Object.Destroy慎用
Object.Destory Destory(Object)并没有立刻,马上,及时的删除这个Object. 举例 在使用NGUI的Table或Grid进行布局时,就需要注意了:尽量不要使用Destro ...
- Effective_java之二:慎用重载函数
每周写一篇技术博客的愿望一直没实现, 从这周開始每周五晚10点是写博客的时间 OOP的一个重要特性就是多态,实现多态的目的有多种途径.比方:重载overload.重写overwite.面向接口编程等等 ...
- [改善Java代码]慎用动态编译
建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...
- php编译参数注解--不明白许多参数的作用 慎用 –with-curlwrappers参数
在Linux下安装PHP,源代码方式安装,总需要配置很多参数.这里列出常用配置参数,并详细用中文解释说明了.给大家一些参考 编译PHP的时候慎用 –with-curlwrappers参数 ./conf ...
- 慎用StringEscapeUtils.escapeHtml步骤
慎用StringEscapeUtils.escapeHtml方法[转] 推荐使用Apache commons-lang的StringUtils来增强Java字符串处理功能,也一直在项目中大量使用Str ...
- webapp 慎用setInterval、setTimeout
其实这片文章刚开始我啥也没写的,但也有20多的访问量,所以觉得大家还是比较关注这个问题,所以找机会写下. 问题的引出: 为什么我说的时webapp中慎用setInterval.setTimeout, ...
- C/C++中慎用宏(#define)
宏的定义在程序中是非常有用的,但是使用不当,就会给自身造成很大的困扰.通常这种困扰为:宏使用在计算方面. 本例子主要是在宏的计算方面,很多时候,大家都知道定义一个计算的宏,对于编译和编程是多么的有用. ...
随机推荐
- Android编译选项eng、user、userdebug的区别
eng:debug 版本 user: release 版本 userDebug版本:部分debug版本 LOCAL_MODULE_TAGS := user eng optional test这个样子. ...
- linux下的文件系统
转http://www.cnblogs.com/yyyyy5101/articles/1901842.html 谈谈个人对于文件系统的认识,其实这也体现了计算机操作系统的抽象:你不用管计算机中的文件如 ...
- 获取或者设置时,无后缀和A后缀和W后缀的区别
SetWindowTextW表示设置的字符串是WCHAR (双字节字符 )SetWindowTextA表示设置的字符串是CHAR (单字节字符 )SetWindowText表示设置的字符串是自动匹配当 ...
- PHP判断用户设备是否是移动设备
摘自http://www.oschina.net/code/snippet_1432190_46913 <?php function isMobile() { // 如果有HTTP_X_WA ...
- 新买了ipad,在ipad上面看见的一个效果,pc上应该也见过,但是还是ipad上面有印象,如果是弹性运动就最好了
新买了ipad,在ipad上面看见的一个效果,pc上应该也见过,但是还是ipad上面有印象,如果是弹性运动就最好了 <!DOCTYPE html> <html> <hea ...
- linux tar命令
tar命令打包还是压缩需要看所调用的命令参数....tar在使用时可以调用命令参数, 比如tar -xvf +文件名就是解包,但是不是解压...只有在使用了参数z等调用gzip等 压缩命令时才是压缩或 ...
- jquery append()详解
1 http://www.365mini.com/page/jquery-append.htm 2 http://blog.csdn.net/chaiyining007/article/details ...
- 折半查找&clock函数
#include <stdio.h>#include <time.h> #define CLOCKS_PER_SEC ((clock_t)1000) int binsearch ...
- servlet&jsp高级:第四部分
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- CSS笔记(四)文本
CSS 文本属性可定义文本的外观.通过文本属性,可以改变文本的颜色.字符间距,对齐文本,装饰文本和对文本进行缩进,等等. 参考:http://www.w3school.com.cn/css/css_t ...