Delphi 2009 / 2010 和 Windows API 调用的 Unicode 问题
-
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.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类型。
如果您使用任何将数据返回到char缓冲区的Windows API,则需要将这些缓冲区重新声明为字节数组或AnsiChar数组。
如果您正在调用这些Windows API并发送缓冲区,那么在告诉API缓冲区有多长时间时一直使用sizeof函数。这些调用需要更改为Length函数,因为 Windows widechar API需要字符数,而不是字节数。
再见。
其他提示
使用Delphi 2009,Char是一个unicode char。该函数可能需要一个AnsiChar数组。
刚检查过。 GetTempFilename和GetTempPath都需要PWideString。
错误讯息是什么?
我建议始终(我真的是始终)查看有关每个 API 函数对 dwSize 参数和/或返回值的确切期望的文档。
不幸的是,有很多不同的情况,所以仅仅说“所有字符串函数需要/返回字符数”并不完全正确,并且可能会让读者陷入零星无效指针反病毒的噩梦。
- 大多数API函数确实期望/返回字符的数量,但有些函数则没有。
- 有些计算终止空字符,有些则不计算。
- 某些函数在传递 nil 指针时的行为与传递 nil 指针时的行为不同。当通过非nil指针时。
- 还有一些函数根本不提供任何方式来指示所需的缓冲区大小。
所有这些东西都可以在文档中轻松找到,但应该阅读它。真的。它可以节省您的时间。
使用 GetTempPathA
和 GetTempFileNameA
, GetTempPath
和 GetTempFileName
的Ansi版本。它们仍在Delphi 2009中可用,并在Delphi 2009帮助文件中提及,但未公布。