ShLwApi.StrFormatByteSize и Delphi 2010 Unicode - PullRequest
1 голос
/ 30 ноября 2009

Может кто-нибудь помочь мне исправить это:

{$IFDEF UNICODE}
function FormatStringByteSize( TheSize: Cardinal ): string;
{ Return a cardinal as a string formated similar to the statusbar of Explorer }
var
  Buff: string;
  Count: Integer;
begin
  Count := Length(Buff);
  FillChar(Buff, Count, 0);
  ShLwApi.StrFormatByteSize( TheSize, PWideChar(Buff), Length( Buff ) * SizeOf( WideChar ) );
  Result := Buff;
end;
{$ENDIF}

Ответы [ 2 ]

1 голос
/ 30 ноября 2009

Вам нужно сначала установить длину баффа. (Длина баффа = 0)

Тогда

  1. Измените TheSize на Int64 - это нужно в любом случае для размеров> 4 ГБ.
  2. Возможно, измените вызов на StrFormatByteSizeW («заголовки» Delphi должны были сделать это в D2009 +)
  3. Несмотря на имя, FillChar ожидает, что размер будет в байтах, а не в символах. Однако это не повлияет на результат.
function FormatStringByteSize( TheSize: int64 ): string;
// Return an Int64 as a string formatted similar to the status bar of Explorer 
var
  Buff: string;
begin
  SetLength(Buff, 20);
  ShLwApi.StrFormatByteSizeW( TheSize, PWideChar(Buff), Length(Buff));
  Result := PChar(Buff);
end;

Я не могу проверить это в D2009 / 10 в данный момент, так как еще не начал переход на Unicode (следующий проект!) Он работает в D2006 с WideString.

0 голосов
/ 30 ноября 2009

По крайней мере, в Delphi 2009 (не могу протестировать в версии 2010, поскольку у меня ее нет) функция StrFormatByteSize() является псевдонимом для версии Ansi (StrFormatByteSizeA()), а не для версии с широким символом (StrFormatByteSizeW()) как и для большинства других функций Windows API. Поэтому вы должны использовать версию с широким символом напрямую - также для более ранних версий Delphi, чтобы иметь возможность работать с файлами (системой) размером более 4 ГБ.

Нет необходимости в промежуточном буфере, и вы можете использовать тот факт, что StrFormatByteSizeW() возвращает указатель на преобразованный результат как PWideChar:

{$IFDEF UNICODE}
function FormatStringByteSize(ASize: int64): string;
{ Return a cardinal as a string formatted similar to the status bar of Explorer }
const
  BufLen = 20;
begin
  SetLength(Result, BufLen);
  Result := StrFormatByteSizeW(ASize, PChar(Result), BufLen);
end;
{$ENDIF}
...