Проблемы с Юникодом в Delphi 2009 / 2010 и вызовами Windows API

StackOverflow https://stackoverflow.com/questions/1420803

  •  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, но не рекламируются.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top