Как получить порядок сортировки в Delphi как в Windows Explorer? - PullRequest
17 голосов
/ 27 февраля 2011

Суммирование:

  1. Похоже, что я искал терминологию "естественной сортировки".
  2. Для поведения в операционных системах:

    • Для Windows (версия> = XP) проводник Windows использует естественную сортировку.
    • Для терминалов Linux: используйте «ls -v» вместо простых «ls», чтобы получить естественную сортировку.
  3. Для программирования в Delphi используйте Windows API StrCmpLogicalW для получения естественной сортировки.

  4. Для программирования в Delphi & Kylix & Lazarus используйте вручную созданные функции для получения естественной сортировки:

==========================

Следующие имена файлов будут упорядочены в проводнике 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

И для записи вышеупомянутые имена файлов будут упорядочены в терминале rxvt Cygwin или терминале xterm дистрибутивов Linux, таких как CentOS, как показано ниже:

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 Explorer?Любое предложение приветствуется!

PS: Мой языковой стандарт Windows установлен на китайский, но я думаю, что то же самое для английского языка.

Ответы [ 2 ]

21 голосов
/ 27 февраля 2011

StrCmpLogicalW может обрабатывать числа, другой альтернативой является CompareString

16 голосов
/ 27 февраля 2011

Спасибо Андерсу - ответ 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;
...