慎用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)
宏的定义在程序中是非常有用的,但是使用不当,就会给自身造成很大的困扰.通常这种困扰为:宏使用在计算方面. 本例子主要是在宏的计算方面,很多时候,大家都知道定义一个计算的宏,对于编译和编程是多么的有用. ...
随机推荐
- 华东交通大学2016年ACM“双基”程序设计竞赛 1001
Problem Description 输入一个非负的int型整数,是奇数的话输出"ECJTU",是偶数则输出"ACM". Input 多组数据,每组数据输入一 ...
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2016)网络赛 A Simple Job
描述 Institute of Computational Linguistics (ICL), Peking University is an interdisciplinary institute ...
- 2016 ACM/ICPC Asia Regional Qingdao Online HDU5878
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5878 解法:先保存,再二分查询~具体http://blog.csdn.net/coder_xia/arti ...
- jQueryEasyUI Messager基本使用
二.jQueryEasyUI Messager基本使用 1.$.messager.alert(title, msg, icon, fn)1>.基本用法 代码: 1 2 3 4 5 6 7 8 9 ...
- java-cmd-命令行编译和运行java文件
一.使用的工具 1.javac 2.java 二.命令 项目目录只这样的 D:/project/src/com/example/Child.java D:/project/src/com/exampl ...
- Json 入门例子【2】
<script> var json1 = { "id": 1, "tagName": "apple" }; $("#f ...
- C语言第4天循环,流程控制。
C语言第四天 :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { borde ...
- java中为什么byte的取值范围是-128到+127
概念:java中用补码表示二进制数,补码的最高位是符号位,最高位为“0”表示正数,最高位为“1”表示负数.正数补码为其本身:负数补码为其绝对值各位取反加1:例如:+21,其二进制表示形式是000101 ...
- #使用while循环输入1 2 3 4 5 6 8 9 10
#!/usr/bin/env python #使用while循环输入1 2 3 4 5 6 8 9 10 import time start = 1 while True: if start == 7 ...
- MyBatis环境搭建
什么是MyBatis: MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架(O object R relatoin M mapping 框架),MyBatis 避免了几 乎所 ...