Проблемы Unicode с Delphi 2009/2010 и вызовами Windows API - PullRequest
4 голосов
/ 14 сентября 2009

Привет Я использовал эту функцию в 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;

Что я должен сделать, чтобы это работало?

EDIT

Я получаю «нарушение прав доступа», когда ChangeFileExt называется

Ответы [ 4 ]

6 голосов
/ 14 сентября 2009

Windows.pas

function GetTempFileName(lpPathName, lpPrefixString: PWideChar;
  uUnique: UINT; lpTempFileName: PWideChar): UINT; stdcall;

function GetTempPath(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; stdcall;

SysUtils.Pas

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 соответственно.

Если вы используете какие-либо API-интерфейсы Windows, которые возвращают данные в буферы символов, эти буферы должны быть повторно объявлены как массивы байтов или массив AnsiChar.

Если вы вызываете эти API-интерфейсы Windows и отправляете в буферы, если вы использовали функцию sizeof, сообщая API, какова длина вашего буфера. Эти вызовы должны быть изменены на функцию Length, поскольку API-интерфейс widechar Windows требует количество символов, а не количество байтов .

Bye.

0 голосов
/ 07 июня 2012

Я бы порекомендовал всегда, и я действительно имею в виду всегда, просматривать документы о точных ожиданиях каждой функции API в отношении параметра dwSize и / или возвращаемого значения.

К сожалению, существует много разных случаев, поэтому просто сказать, что «все строковые функции нуждаются / возвращать число символов», не совсем правильно, и это может привести читателя к кошмару спорадических неверных указателей AV.

  • Большинство функций API ожидают / возвращают количество символов, но некоторые нет.
  • Некоторые считают завершающий нулевой символ, а некоторые нет.
  • Некоторые функции ведут себя по-разному, когда передается нулевой указатель, и когда указатель не ноль передается.
  • И есть также некоторые функции, которые вообще не предлагают никакого способа указания требуемого размера буфера.

Все эти вещи можно легко найти в документах, но их следует прочитать. В самом деле. Это может сэкономить вам часы.

0 голосов
/ 27 марта 2010

Используйте GetTempPathA и GetTempFileNameA, версии Ansi GetTempPath и GetTempFileName. Они по-прежнему доступны в Delphi 2009 и упоминаются в файле справки Delphi 2009, но не рекламируются.

0 голосов
/ 14 сентября 2009

В Delphi 2009 Char является символом Unicode. Для функции, вероятно, требуется массив AnsiChar.

Только что проверил. И GetTempFilename, и GetTempPath требуют PWideString.

Что такое сообщение об ошибке?

...