zoukankan      html  css  js  c++  java
  • 慎用GetOpenFileName

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

    请参考下面的MFC代码:

    CFileDialog dlg(TRUE);

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

    dlg.DoModal();

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

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

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

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

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

    TCHAR                szFile[MAX_PATH] = {''};

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

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

  • 相关阅读:
    C programming course
    关于时间管理的培训心得
    吴老师,一路好走!
    自己实现Int32Collection(.Net 1.1),以及效率问题的体会
    《C陷阱与缺陷》和《C专家编程》两本书又翻印了
    暂时闲一会,写一点点面试体会吧
    人类没有一件事是值得烦恼的
    EP0N系统中简便可行的光纤保护方法
    越来越不想写代码了
    [转]PON关键技术-通用成帧协议研究
  • 原文地址:https://www.cnblogs.com/hanford/p/6164507.html
Copyright © 2011-2022 走看看