Delphi 2009/2010およびWindows API呼び出しでのUnicodeの問題
-
07-07-2019 - |
質問
こんにちは、Delphi 2006でこの関数を使用していましたが、D2010ではエラーがスローされます。 ユニコードへの切り替えに関係していると思います。
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関数を使用している場合 Windowsワイド文字APIにはバイト数ではなく文字数が必要であるため、これらの呼び出しはLength関数に変更する必要があります。
はい。
他のヒント
Delphi 2009では、CharはUnicode文字です。この関数には、おそらくAnsiCharの配列が必要です。
チェックしました。 GetTempFilenameとGetTempPathの両方にPWideStringが必要です。
エラーメッセージとは何ですか?
dwSizeパラメータおよび/または戻り値に関する各API関数の正確な期待についてドキュメントを参照することを常にお勧めします。
残念ながら、多くの異なるケースがありますので、「すべての文字列関数に必要な文字数を返す」とだけ言ってください。正確ではなく、リーダーを散発的な無効なポインターAVの悪夢に送り込む可能性があります。
- ほとんどのAPI関数は、文字数を期待/返しますが、一部の しないでください。
- 終端のnull文字をカウントするものとしないものがあります。
- 一部の関数は、nilポインターが渡されたときと 非nilポインターが渡されます。
- また、必要なバッファサイズを示す方法をまったく提供しない関数もあります。
これらはすべてドキュメントで簡単に見つけることができますが、読む必要があります。本当に。時間を節約できます。
GetTempPathA
および GetTempFileNameA
、 GetTempPath
および GetTempFileName
のAnsiバージョンを使用します。これらはDelphi 2009でも引き続き利用でき、Delphi 2009ヘルプファイルで言及されていますが、宣伝されていません。