首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 其他相关 >

解决工作中碰到的一个"打开,保存"文件框的bug的过程

2013-11-02 
解决工作中遇到的一个打开,保存文件框的bug的过程工作中遇到的这个问题还是很有意思的。其中嵌套了很多奇

解决工作中遇到的一个"打开,保存"文件框的bug的过程
        工作中遇到的这个问题还是很有意思的。其中嵌套了很多奇葩性的问题。(转载请指明出于breaksoftware的csdn博客)

        我们来看下故事的发生过程,QA同学发现我们存在如下的bug

解决工作中碰到的一个"打开,保存"文件框的bug的过程

        看到如此多的串,可以认为这个是典型的溢出问题。后来我咨询解决该问题的同学,他说这个bug在debug模式下不会出现,只有在release下才会出现(这个意味着,该问题很有可能是内存问题引起的,因为debug和release的一个很大的区别就是内存初始化和布局)。解决方案就是在筛选器后面加个\0。


        此时我们选择的是jpeg格式,则显示了所有后缀为jpg的文件。如果我们选择png格式,则只显示后缀为png的文件。如下图

解决工作中碰到的一个"打开,保存"文件框的bug的过程

        而用我们的代码打开的是

解决工作中碰到的一个"打开,保存"文件框的bug的过程

        这可以见得,我们的筛选器失效了。这也意味着,我们的筛选器写法是有问题。找到这个问题,就离我们找到为什么lpstrFilter要以两个NULL结尾的问题不远了。
        其实我们仔细看下MSDN的说明。可以知道lpstrFilter保存的是若干个“字符串对”(A buffer containing pairs of null-terminated filter strings.)。这种设计思想,在windows上很多的,比如可以看http://blog.csdn.net/breaksoftware/article/details/3914358这篇文章中介绍的PendingFileRenameOperations注册表项,其记录的数据也是若干个“字符串对”。lpstrFilter中的每个“字符串对”,第一个字符串保存的是用于在框的“保存类型”中显示的文字,比如png;二个字符串保存的是“筛选规则”(不会显示出来,供窗口筛选用),比如*.png。而我们的窗口中显示的是png|*.png。此时似乎我们懂了点什么……这个就是我们写错了!我猜测这段代码的作者,也是希望做成有筛选功能的,否则也不用指定这个字段。但是他可能认为“|”是分隔符。于是便有了
            png                |             *.png
      (显示名)  (分隔符)  (筛选器)
        话说

解决工作中碰到的一个"打开,保存"文件框的bug的过程

        这样的显示也忒不协调了!
        正确的写法是png\0*.png\0。
        可以想象下windows对这个串的处理:

    Search第一个\0,找到“显示字符串” 从前一个\0开始搜索第一个\0,寻找到“匹配规则串” 从前一个\0开始搜索第一个\0,如果位置和前一个\0不相邻,则走到1;否则结束搜索
        这个流程就解释了为什么我们需要以两个连续的NULL结尾。
        这儿再多说两句,我们看下mspaint的保存框

解决工作中碰到的一个"打开,保存"文件框的bug的过程

        这种组合的正确写法是

m_ofn.lpstrFilter =  L"单色位图(*.bmp;*.dib)\0*.bmp;*.dib\0\t16色位图(*.bmp;*.dib)\0*.bmp;*.dib\0\r256色位图(*.bmp;*.dib)\0*.bmp;*.dib\0\r24位位图(*.bmp;*.dib)\0*.bmp;*.dib\0JPEG(*.jpg;*.jpeg;*.jpe;*.jfif)\0*.jpg;*.jpeg;*.jpe;*.jfif\0GIF(*.gif)\0*.gif\0TIFF(*.tif;*.tiff)\0*.tif;*.tiff\0PNG(*.png)\0*.png\0";

热点排行