ShLwApi.StrFormatByteSize и Юникод Delphi 2010
-
08-07-2019 - |
Вопрос
Кто-нибудь может помочь мне это исправить:
{$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}
Решение
По крайней мере в Delphi 2009 (не могу протестировать в версии 2010, поскольку у меня его нет) функция StrFormatByteSize ()
является псевдонимом версии Ansi ( StrFormatByteSizeA ()
), но не для широкой версии символа ( StrFormatByteSizeW ()
), как для большинства других функций Windows API. Поэтому вы должны использовать широкую версию char напрямую - также для более ранних версий 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}
Другие советы
Сначала вам нужно установить длину баффа.(Увеличение длины = 0)
Тогда
- Измените размер на Int64 - вам все равно это нужно для размеров > 4 ГБ.
- Возможно, измените вызов на StrFormatByteSizeW ("заголовки" Delphi должны были сделать это в D2009 +)
- Несмотря на название, 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.