Unicode problems with Delphi 2009 / 2010 and windows API calls

馋奶兔 提交于 2019-12-21 17:28:50

问题


Hi I have been using this function in Delphi 2006, but now with D2010 it throws an error. I think it is related to the switch to 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;

What should I do to make it work?

EDIT

I get an 'access violation' when the ChangeFileExt is called


回答1:


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;

Try this

  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;

or this

  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;

For Delphi, Char and PChar types are WideChar and PWideChar types, respectively.

If you use any Windows API’s that return data into char buffers , those buffers need to be redeclared as arrays of bytes or an array of AnsiChar.

If you are calling these Windows API’s and sending in buffers, if have been using the sizeof function when telling the API how long your buffer is. Those calls need to be changed to the Length function, as the Windows widechar API’s require the number of characters, not the number of bytes.

Bye.




回答2:


With Delphi 2009, Char is a unicode char. The function probably requires an array of AnsiChar.

Just checked it. Both GetTempFilename and GetTempPath require a PWideString.

What is the error message?




回答3:


I'd recommend to always, and I really mean always, to have a look into the docs about the exact expectations of each API function regarding the dwSize parameter and/or the return value.

Unfortunately there are a lot of different cases, so just saying "all string functions need/return number of chars" is not quite correct and may send the reader into a nightmare of sporadic invalid pointer AVs.

  • Most of the API functions do expect/return number of chars, but some don't.
  • Some count the terminating null char, and some don't.
  • Some functions behave differently when a nil pointer is passed vs. when a non-nil pointer is passed.
  • And there are also some functions that do not offer any way at all to indicate the required buffer size.

All these things can be found in the docs easily, but one should read it. Really. It can save you hours.




回答4:


Use GetTempPathA and GetTempFileNameA, the Ansi versions of GetTempPath and GetTempFileName. They are still available in Delphi 2009, and mentioned in the Delphi 2009 help file, but not advertised.



来源:https://stackoverflow.com/questions/1420803/unicode-problems-with-delphi-2009-2010-and-windows-api-calls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!