2009-09-14 178 views
4

嗨我一直在Delphi 2006中使用此功能,但現在與D2010它引發錯誤。 我認爲它與切換到Unicode有關。德爾福2009/2010和Windows API調用的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被稱爲

+0

你應該編輯你的問題,以包括錯誤信息(一個好習慣 - 有道理,對不對?) – Argalatyr 2009-09-14 13:02:14

+1

請參閱以下鏈接,討論問題(幾乎相同的代碼)和更好的版本說明API文檔中關於最大緩衝區大小的更多內容。 https://forums.embarcadero.com/thread.jspa?threadID=18246 – 2009-09-14 13:53:42

回答

6

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 widechar API的要求字符數,而不是字節數

再見。

+4

舊代碼出現問題的原因是GetTempPath()中的SizeOf(Buffer)-1。 SizeOf的字符數組與2009年之前的Delphi長度相同,因爲SizeOf(AnsiChar)= 1。在Delphi 2009及更高版本中,SizeOf(Char)= SizeOf(WideChar)= 2,所以代碼要求GetTempPath()用更多的字符填充緩衝區。 – jasonpenny 2009-09-14 11:22:38

+0

第二個選項的作品謝謝:) – 2009-09-14 12:08:03

+0

我在「delphi 2010」中嘗試了兩個選項,並且它們工作正常。 ;) – RRUZ 2009-09-14 12:18:15

0

德爾福2009年,字符是一個Unicode字符。該函數可能需要一個AnsiChar數組。

剛剛檢查過它。 GetTempFilename和GetTempPath都需要一個PWideString。

什麼是錯誤信息?

+0

你應該不是指'PWideChar'嗎? 'PWideString'完全是另一回事。 – 2009-09-14 13:48:59

0

使用GetTempPathAGetTempFileNameA,Ansi版本GetTempPathGetTempFileName。他們仍然可以在德爾福2009年,並在德爾福2009年的幫助文件中提到,但沒有公佈。

+0

在Windows NT操作系統版本上大多數(如果不是全部)* API函數的版本只是存根轉換參數並調用相同函數的* W版本。因此,在Delphi 2009+中,您可以將內部寬字符數據轉換爲Ansi,調用*函數,該函數將內部轉換爲寬字符並返回,程序會將結果轉換爲寬字符。你會說這條路線有意義嗎? – mghie 2010-03-27 10:07:13

0

我建議總是,而且我真的是說總是查看關於每個API函數關於dwSize參數和/或返回值的確切期望值的文檔。

不幸的是,有很多不同的情況,所以只是說「所有字符串函數需要/返回字符數」是不完全正確的,可能會使讀者陷入零星無效指針AVs的噩夢。

  • 大部分API函數都會預期/返回字符數,但有些 則不會。
  • 有些計數終止空字符,有些不計數。
  • 當一個零指針傳遞與一個非零指針傳遞時,一些函數的行爲不同。
  • 還有一些功能根本不提供任何方式來指示所需的緩衝區大小。

所有這些東西都可以在文檔中找到,但應該可以閱讀。真。它可以節省你的時間。