delphi - FindFirst、FindNext(Delphi Xe、Win7)排名不正确

标签 delphi delphi-xe rank findfirst

我的目录中有一些文件。我尝试使用 FindFirst 和 FindNext 获取这些文件,但在 Windows 7 上无法获取相同的顺序。

C:\Test
SampleFile.0.png
SampleFile.1.png
SampleFile.2.png
SampleFile.3.png
SampleFile.4.png
SampleFile.5.png
SampleFile.6.png
SampleFile.7.png
SampleFile.8.png
SampleFile.9.png
SampleFile.10.png
SampleFile.11.png
SampleFile.12.png
SampleFile.13.png
SampleFile.14.png
SampleFile.15.png
SampleFile.16.png
SampleFile.17.png
SampleFile.18.png
SampleFile.19.png
SampleFile.20.png
SampleFile.21.png
SampleFile.22.png

当我尝试使用我的代码时,我得到了

SampleFile.0.png
SampleFile.1.png
SampleFile.10.png
SampleFile.11.png
SampleFile.12.png
SampleFile.13.png
SampleFile.14.png
SampleFile.15.png
SampleFile.16.png
SampleFile.17.png
SampleFile.18.png
SampleFile.19.png
SampleFile.2.png
SampleFile.20.png
SampleFile.21.png
.
.
.

如何获取正确排名顺序的文件列表?

Procedure Test;
var
sr : TSearchRec;
i : integer;
ListFiles : TStringList;  
begin
ListFiles := TStringList.Create;
i := FindFirst('c:\test\*.png', faDirectory, sr);
while i = 0 do begin  
ListFiles.Add(ExtractFileName(sr.FindData.cFileName));
i := FindNext(sr); 
end;
FindClose(sr);
end;  

注意:如果我可以使用 ListFiles.Sorted = True,结果仍然是错误的

<小时/>

我想我有一个解决方案,创建了一个函数。

function SortFilesByName(List: TStringList; Index1, Index2: Integer): integer;
var
FileName1, FileName2: String;
i, FileNumber1, FileNumber2: Integer;
begin
  FileName1 := ChangeFileExt(ExtractFileName(List[Index1]), '');
  FileName2 := ChangeFileExt(ExtractFileName(List[Index2]), '');
  i := POS('.', FileName1)+1;
  FileNumber1 := StrToInt(Copy(FileName1, i, MaxInt));
  i := POS('.', FileName2)+1;
  FileNumber2 := StrToInt(Copy(FileName2, i, MaxInt));
  Result := (FileNumber1 - FileNumber2);
end;

我又添加了一行 ListFiles.CustomSort(SortFilesByName);//(ListFiles,1,2):整数); 前 FindClose(sr);

最佳答案

正如 jachguate 所说,排序是由 Explorer.exe 完成的,而不是文件系统。 FindFirst/FindNext 不保证任何特定的排序,包括基于纯 ASCII 的排序,因此您不应依赖它。但是,您不需要在 Delphi 中重新实现数字排序。 Windows 将其使用的一个公开为 StrCmpLogicalW ,位于 shlwapi.dll 中。导入看起来像这样:

function StrCmpLogicalW(psz1, psz2: PWideChar): Integer; stdcall;
  external 'shlwapi.dll'

可以在 Windows 中禁用该行为。如果你想遵循Windows使用的顺序,你需要调用SHRestrictedREST_NOSTRCMPLOGICAL 值。如果它返回 true,您应该使用 AnsiCompareStr。

const
  // Use default CompareString instead of StrCmpLogical
  REST_NOSTRCMPLOGICAL = $4000007E;

function SHRestricted(rest: DWORD): LongBool; stdcall; external 'shell32.dll';

所以你的最终排序函数应该是这样的:

function CompareFilenames(const AFilename1, AFilename2: string): Integer;
begin
  if SHRestricted(REST_NOSTRCMPLOGICAL) then
    Result := AnsiCompareStr(AFilename1, AFilename2)
  else
    Result := StrCmpLogicalW(PWideChar(AFilename1), PWideChar(AFilename2));
end;

您可以缓存 SHRestricted 调用的结果,但如果这样做,您需要监视 WM_SETTINGSCHANGE 广播消息,并在收到消息时重新读取它。

关于delphi - FindFirst、FindNext(Delphi Xe、Win7)排名不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14377934/

相关文章:

delphi - 进程名称在 Delphi XE 中不可见附加到进程对话框 - 无法调试

基于几个变量的排名

python - Delphi 和 Python - 一些简短的查询

delphi - 尽管正在使用 System.Generics.Defaults,但 TComparer.Construct 未声明标识符

delphi - 重复查询大表的最快方法

multithreading - 使用新线程进行FTP上传并等待上传完成

r - R中Zipf(频率与排名)图的命令是什么

solr - Solr/Lucene 有没有办法返回选定文档的排名而不是完整结果?

delphi - 保存打印机设置参数

delphi - Synapse Delphi HTTPS SSL GET 请求