如何像在 Windows 资源管理器中一样在 Delphi 中获取排序顺序?
Posted
技术标签:
【中文标题】如何像在 Windows 资源管理器中一样在 Delphi 中获取排序顺序?【英文标题】:How to get the sort order in Delphi as in Windows Explorer? 【发布时间】:2011-07-05 07:37:19 【问题描述】:总结:
-
我使用过的术语
寻找似乎是“自然的
排序”。
对于操作系统中的行为:
对于 Windows(版本 >= XP),Windows 资源管理器利用自然 排序。 对于 Linux 终端:使用“ls -v”而不是普通的“ls”来获得自然 排序。对于在 Delphi 中编程,使用 StrCmpLogicalW Windows API 来获得自然排序。
对于在 Delphi & Kylix & Lazarus 中编程,使用手工制作的函数来获取 自然排序: (1) Martin Pool 用于自然顺序字符串比较的 Delphi 包装器。http://irsoft.de/web/strnatcmp-and-natsort-for-delphi (2) 来自davekeolle网站的其他语言的字母排序算法代码。http://www.davekoelle.com/alphanum.html (3) 其他知识页面:http://www.codinghorror.com/blog/2007/12/sorting-for-humans-natural-sort-order.htmlhttp://objectmix.com/delphi/722211-natural-sorting-optimizing-working-solution.htmlhttp://groups.google.com/group/borland.public.delphi.language.delphi.general/browse_thread/thread/1141d49f8bbba577http://objectmix.com/delphi/401713-alphanumeric-sort-routine-delphi.html===========================
以下文件名将在 Windows 资源管理器中按如下顺序排列:
test_1_test.txt
test_2_test.txt
test_11_test.txt
test_12_test.txt
test_21_test.txt
test_22_test.txt
例如,如果我把它们放在一个 TStringList 实例中并调用 Sort,排序顺序如下:
test_1_test.txt
test_11_test.txt
test_12_test.txt
test_2_test.txt
test_21_test.txt
test_22_test.txt
为了记录,上述文件名将在Cygwin的rxvt终端或Linux发行版如CentOS的xterm终端中排序,如下所示:
test_11_test.txt
test_12_test.txt
test_1_test.txt
test_21_test.txt
test_22_test.txt
test_2_test.txt
您能帮忙评论一下如何理解排序行为的这种差异吗?此外,是否可以获得与 Windows 资源管理器中相同的顺序?任何建议表示赞赏!
PS:我的 Windows 区域设置为中文,但我认为英文区域设置相同。
【问题讨论】:
见***.com/questions/2175066/… 我之前注意到了这一点。 AFAICS,较新的 Windows 版本识别文件名中的数字,并将数字排序为数字而不是文本。 @ax:非常感谢您提供的信息!我现在就读! 名称中包含数字的文件和文件夹的排序顺序:support.microsoft.com/kb/319827 @Jørn E. Angeltveit:谢谢,但这是猜测还是来自官方消息? 【参考方案1】:StrCmpLogicalW 可以处理数字,另一种选择是CompareString
【讨论】:
非常感谢您的建议! 您能否帮忙评论一下在 Kylix(Kylix 编译的应用程序在 Linux 中运行)中实现相同功能的最佳实践是什么? @Xichen Li:如果linux/posix没有类似的功能你就得自己写了... 我明白了!谢谢你的建议!【参考方案2】:感谢 Anders - 答案是 StrCmpLogicalW;我在 Delphi 2009 源代码中没有找到它的声明,所以我在下面的测试中自己声明了它:
type
TMyStringList = class(TStringList)
protected
function CompareStrings(const S1, S2: string): Integer; override;
end;
function StrCmpLogicalW(P1, P2: PWideChar): Integer; stdcall; external 'Shlwapi.dll';
function TMyStringList.CompareStrings(const S1, S2: string): Integer;
begin
Result:= StrCmpLogicalW(PChar(S1), PChar(S2));
end;
procedure TForm11.Button2Click(Sender: TObject);
var
SL: TMyStringList;
begin
SL:= TMyStringList.Create;
try
SL.Add('test_1_test.txt');
SL.Add('test_11_test.txt');
SL.Add('test_12_test.txt');
SL.Add('test_2_test.txt');
SL.Add('test_21_test.txt');
SL.Add('test_22_test.txt');
SL.Sort;
Memo1.Lines:= SL;
finally
SL.Free;
end;
end;
【讨论】:
非常感谢您的宝贵时间和热心帮助!您的示例代码很有帮助! [错误] Test.pas(264):不兼容的类型:“Char”和“WideChar”。如何修复 (D7)? @NGLN 由于不存在StrCmpLogicalA
版本,您应该在调用StrCmpLogicalW
之前将字符串转换为unicode,如果您有国家字符,可能使用MultiByteToWideChar
函数-msdn.microsoft.com/en-us/library/windows/desktop/…以上是关于如何像在 Windows 资源管理器中一样在 Delphi 中获取排序顺序?的主要内容,如果未能解决你的问题,请参考以下文章
如何获得完整的 unicode 支持,包括 VCL 控件中的中文字符或 XP 上的 Windows 通用控件,就像在 Win7 中一样
如何在 Windows 资源管理器中添加“在此处打开 git-bash ...”上下文菜单?
如何在 Windows 11 的 Windows 资源管理器中添加“Git Bash Here”上下文菜单选项?