Bug 重现:
1. 建立目录 C:\test
2. 进入 C:\test, 建立四个文本文件,分别命名为 test.log; test.log1; test.txt; test.txt1
3. 在 Form 上画一 FileListBox 控件(File1),将 Pattern 设为 *.log;*.txt
4. 执行时将 File1.Path 设为 "C:\test"预期的结果应该是 test.log 及 test.txt,但实际结果是 4 个文件都显示了(只设单个 Pattern,问题同样存在)。实际的需求是我的 Pattern 很长(甚至超过 255,需要用数组来循环过滤),这种情况,只有用 FileListBox 能最快且最方便地过滤文件。
VB6 的补丁打完了,这个 Bug 仍然存在,国内外网站找了一下类似第三方控件,似乎没有(因为 FileListBox 简单好用)。哪位达达给指点一下,多谢。QQ:915956208

解决方案 »

  1.   

    在命令行中用 dir /x,你会发现 .log1 的短文件名是 .log,这是操作系统的文件命名规则。
    改文件后缀吧。
      

  2.   

    文件的后缀名一般规定为3个英文字符,log1不规范
      

  3.   

    对,发觉 Pattern 跟 Dir() 函数结果一样,也就是它们都使用 8.3 短名。
    改名是不合理的,我的目的是把指定的文件找出来,目标文件在用户的电脑上。其实 FLB 有三个问题:
    1、Pattern 不能超过 255 字符。
    2、带 ? 之 Pattern 不能与其他 Patterns 连用,如 *.jpg;*.?ie 无效。
    3、8.3 问题。解决:
    1'、使用字串数组(psFilters),超过 255 就 Redim 出新元素。
    2'、带 ? 之 Pattern 单作 psFilters 一元素。3'、想了一个方法:按后缀位数归类,For Next 时判断一下实际后缀与 Pattern 后缀位数是否相等,但这样仍有问题,有些后缀带 *(且可能不止一个),如果弄得太复杂,还不如不用 FLB,直接 For Next 所有文件。该问题仍须讨论...
      

  4.   

    现在超过 3 个的很多, 比如: BT 种子, Office 2007 的文档......
      

  5.   

    重要的是我们不能让客户运行软件时得到不正确的结果.比如: 有种叫 .tor 的文件, 是垃圾文件, 但客户运行时却看到 .torrent 也是垃圾文件, 这样的软件还有人用吗.
      

  6.   

    用 ListView 控件,自己写代码来显示文件。
      

  7.   

    用dir获得文件列表,然后手工处理显示出来。可以写个加强版的filelistbox放这跟我们分享哈
      

  8.   

    FileListBox 设计的时代只有短文件名,长文件名要自己匹配:
    Option Explicit
    Option Compare TextSub Main()
        Dim aPatterns() As String
        Dim sFileName As String
        Dim i As Long
        
        aPatterns = Split("*.txt;*.log", ";")
        sFileName = Dir("C:\*.*")
        While LenB(sFileName) <> 0
            For i = 0 To UBound(aPatterns)
                If sFileName Like aPatterns(i) Then
                    Debug.Print sFileName
                    Exit For
                End If
            Next
        
            sFileName = Dir()
        Wend
    End Sub
      

  9.   

    前面说的三个问题,其实只有两个,昨晚再次测试总结了一下,整理如下(摘自我们的VB TDN(VB Technology Documents & Notes)):◆ FileListBox 的两个重大不便之处 (历史遗留问题)
       1. Pattern 只能接受最多 255 个字符.
       2. Pattern 之各过滤器 (以 ; (实际使用时前后均无空白字元)分隔)只支持 8.3 档案格式, 即 ???????.log 等价于 ?????????.log, *.txt 可过滤出 a.txt, b.txt1.
       所以对过滤结果应使用 Like 运算符再次判断, 如 "b.txt1" Like "*.txt" 传回 False.对应此总结,折衷处理了实现逻辑,代码大致如下:
    其实楼上几位的看法都很好,特别是赵虎同志的思路与我基本一致。
    只是我的要求并不是显示,而是怎样花尽可能少的时间将目标文件列出来给用户(因为我要扫描所有本地磁盘驱动器),所以思路是先应用 flb.Pattern,使循环次数尽可能少。   ...
       Public psTrashyFilters$()           ' 垃圾档过滤器 (格式: typeA;typeB;typeC;..., 可直接用于 FileListBox.Pattern).
                                           ' 注: 由于 FileListBox.Pattern 只能接受 255 个字符故声明为阵列.
       Public psTrashyTypes$()             ' 垃圾档类型, 格式: Description|Pattern|Flag (D/U), D = Default; U = User Defined.
       ...
       '' 添加垃圾档案 (垃圾档案不用遍历所有档案, 使用 flb 物件单独处理, 故不放到以下 For Each 回圈中),
       ...
       Dim iCycO%  ' 外回圈变数.
       Dim iCntO%  ' 外回圈总数.
       Dim iCycI%  ' 内回圈变数.
       Dim iCntI%  ' 内回圈总数.
       Dim iCycT%  ' 第三层回圈变数.
       Dim iCntT%  ' 第三层总数.
       Dim fil As File
       Dim fod As Folder
       Dim fodCyc As Folder
       Dim lsi As ListItem
       ...   If InStr(asTypes, "|Trashy Files|") > 0 Then
          iCntO = UBound(psTrashyFilters)
          iCntT = UBound(psTrashyTypes)
          With frmPubMain.flb
             .Path = fod.Path
             For iCycO = 0 To iCntO
                .Pattern = psTrashyFilters(iCycO)
                iCntI = .ListCount - 1
                For iCycI = 0 To iCntI
                   For iCycT = 0 To iCntT
                      If LCase(.List(iCycI)) Like Split(psTrashyTypes(iCycT), "|")(1) Then  ' 由于 FLB 只支持 8.3 格式, 故作二次验证.
                         Set fil = pfso.GetFile(fod.Path & "\" & .List(iCycI))
                         Set lsi = frmPubMain.lsvResult.ListItems.Add(, , "Trashy File")
                         lsi.Checked = True
                         lsi.SubItems(1) = fil.Name
                         lsi.SubItems(2) = Format(Round(fil.Size / 1024, 2), "#,0.#")
                         lsi.SubItems(3) = fod.Path
                         Exit For
                      End If
                   Next
                Next
             Next
          End With
       End If
       ''
       ...
    谢谢各位牛牛,结贴,给分。
      

  10.   

    每一个文件,都有长文件名和短文件名之分,长文件名都可以转换成8.3格式的短文件名:
    Option Explicit
    Private Declare Function GetShortPathName Lib "kernel32.dll" Alias "GetShortPathNameA" (ByVal lpszLongPath As String, ByVal lpszShortPath As String, ByVal cchBuffer As Long) As LongPrivate Sub Command1_Click()
            Dim fName As String, S As String
            fName = "c:\IEPageSetup.html" '长文件名
            S = String(LenB(fName), Chr(0))
            GetShortPathName fName, S, Len(S)
            S = Left(S, InStr(S, Chr(0)) - 1) '转换成短文件名c:\IEPAGE~1.HTM
            Debug.Print S '即c:\IEPAGE~1.HTM
    End Sub
      

  11.   

    你虽然作了过滤,但系统会自动按照短文件名处理。
    比如:上面的网页文件IEPageSetup.html,系统会自动按照8.3格式的短文件名IEPAGE~1.HTM过滤。还有一种样式文件叫做skin????.style,实际上是:skin????.sty,这两个文件是一样的。从Windows 95以来,允许长文件名,目的是为显示直观,方便好看,但在windows内部是要通过API转换按照8.3格式管理。
      

  12.   


    Pattern 的确只能保存255个字符,FileListBox控件也只能列出符合这255个字符条件的文件。要想将目标文件列出来给用户,可这样考虑:将FileListBox隐藏起来,将每一次符合Pattern条件的文件添加到列表框控件ListBox中,循环也不多,比如有800个这样的文件扩展名字符,那也只有4次循环。 
      

  13.   


     .torrent 不是什么垃圾文件,而是BT的种子文件。