Проблемы с Юникодом в Delphi 2009 / 2010 и вызовами Windows API
-
07-07-2019 - |
Вопрос
Привет, я использовал эту функцию в Delphi 2006, но теперь с D2010 она выдает ошибку.Я думаю, это связано с переходом на Unicode.
Function TWinUtils.GetTempFile(Const Extension: STRING): STRING;
Var
Buffer: ARRAY [0 .. MAX_PATH] OF char;
Begin
Repeat
GetTempPath(SizeOf(Buffer) - 1, Buffer);
GetTempFileName(Buffer, '~~', 0, Buffer);
Result := ChangeFileExt(Buffer, Extension);
Until not FileExists(Result);
End;
Что я должен сделать, чтобы это сработало?
Редактировать
Я получаю сообщение "нарушение доступа" при вызове ChangeFileExt
Решение
Windows.Pas
function GetTempFileName(lpPathName, lpPrefixString: PWideChar;
uUnique: UINT; lpTempFileName: PWideChar): UINT; stdcall;
function GetTempPath(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; stdcall;
SysUtils.Па
function ChangeFileExt(const FileName, Extension: string): string;
Попробуй это
Function TWinUtils.GetTempFile(Const Extension: STRING): STRING;
Var
Buffer: ARRAY [0 .. MAX_PATH] OF WideChar;
Begin
Repeat
GetTempPath(Length(Buffer), Buffer);
GetTempFileName(Buffer, '~~', 0, Buffer);
Result := ChangeFileExt(Buffer, Extension);
Until not FileExists(Result);
End;
или это
Function GetTempFile(Const Extension: String): String;
Var
Buffer: String;
Begin
SetLength(Buffer,MAX_PATH);
Repeat
GetTempPath( MAX_PATH, PChar( Buffer) );
GetTempFileName(PChar( Buffer), '~~', 0, PChar( Buffer));
Result := ChangeFileExt(Buffer, Extension);
Until not FileExists(Result);
End;
Для Delphi типы Char и PChar являются типами WideChar и PWideChar соответственно.
Если вы используете какой-либо Windows API, который возвращает данные в буферы символов , эти буферы необходимо повторно объявить как массивы байтов или массив AnsiChar.
Если вы вызываете эти Windows API и отправляете буферы, если вы использовали функцию sizeof при сообщении API о длине вашего буфера.Эти вызовы необходимо изменить на функцию длины, так как API Windows widechar требует количества символов, а не количества байтов.
Пока.
Другие советы
В Delphi 2009 символ Char является символом юникода.Для функции, вероятно, требуется массив AnsiChar .
Только что проверил это.Как для GetTempFileName, так и для GetTempPath требуется PWideString .
Что это за сообщение об ошибке?
Я бы рекомендовал всегда, и я действительно имею в виду всегда, заглядывать в документы о точных ожиданиях каждой функции API относительно параметра dwSize и / или возвращаемого значения.
К сожалению, существует много разных случаев, поэтому просто сказать "всем строковым функциям требуется / возвращается количество символов" не совсем корректно и может отправить читателя в кошмар спорадических недопустимых AVS указателей.
- Большинство функций API ожидают / возвращают количество символов, но некоторые этого не делают.
- Некоторые считают завершающий символ null, а некоторые нет.
- Некоторые функции ведут себя по-разному при передаче нулевого указателя по сравнениюкогда передается указатель, отличный от нуля .
- И есть также некоторые функции, которые вообще не предлагают никакого способа указать требуемый размер буфера.
Все это можно легко найти в документации, но ее следует прочитать.Действительно.Это может сэкономить вам несколько часов.
Использование GetTempPathA
и GetTempFileNameA
, версии Ansi для GetTempPath
и GetTempFileName
.Они по-прежнему доступны в Delphi 2009 и упоминаются в файле справки Delphi 2009, но не рекламируются.