2009-11-13 53 views
2

我的delphi 2009應用程序有一個使用GNUGetText的基本翻譯系統。我曾使用一些win API調用來準備字體。我認爲它的工作是正確的,直到最近馬耳他的某個人在我的應用程序出現問題時才完全失敗。我的應用程序全球使用。由於d2009使用unicode,因此一些代碼可能已經過時。確定要使用的字符集

爲了讓我的應用程序能夠在所有語言環境中工作,這些都是真正必需的嗎?

TForm.Font.Charset

這是我的理解,我必須根據用戶的區域設置TForm的實例的Font.Charset。它是否正確?

TranslateCharsetInfo()贏得API函數

德爾福2009年的windows.pas說:

function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; 

德爾福5的windows.pas說:

function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; stdcall; 
從微軟的MSDN

BOOL TranslateCharsetInfo(
    __inout DWORD FAR *lpSrc, 
    __out LPCHARSETINFO lpCs, 
    __in  DWORD dwFlags 
); 
當這個代碼寫(在Delphi回5天)

回,字功能的運行軌跡是不正確的和正確的方法是:

function TranslateCharsetInfo(lpSrc: Pointer; var lpCs: TCharsetInfo; 
dwFlags: DWORD): BOOL; stdcall; external gdi32; 

公告稱,D2009 windows.pas文件複製不是stdcall。我應該使用TranslateCharsetInfo的哪個聲明?

代碼

的是,除了基本上我一直在做如下:

var 
    Buffer : PChar; 
    iSize, iCodePage : integer; 
    rCharsetInfo: TCharsetInfo; 
begin 
    // SysLocale.DefaultLCID = 1802 
    iSize := GetLocaleInfo(SysLocale.DefaultLCID, LOCALE_IDefaultAnsiCodePage, 
       nil, 0); 
    // size=14 
    GetMem(Buffer, iSize); 
    try 
    if GetLocaleInfo(SysLocale.DefaultLCID, LOCALE_IDefaultAnsiCodePage, Buffer, 
     iSize)=0 then 
     RaiseLastOSError; 

    // Buffer contains 0 so codepage = 0 
    iCodePage:=Result := StrToInt(string(Buffer)); 
    finally 
    FreeMem(Buffer); 
    end; 

    // this function is not called according to MSDN's directions for 
    // TCI_SRCCODEPAGE and the call fails. 
    if not TranslateCharsetInfo(Pointer(iCodePage), rCharsetInfo, 
    TCI_SRCCODEPAGE) then 
     RaiseLastOSError; 

    // acts upon the form 
    Font.Charset:= rCharsetInfo.ciCharset; 
end; 

我只是不知道有足夠的瞭解這個......奇怪的是,幾年前,當我寫這個,我被說服了,它工作正常。未能檢查API調用返回碼的結果...

是不是有更聰明的方法來做到這一點? RTL/VCL不會自動完成大部分/全部這些操作嗎?我的直覺告訴我,我正在努力工作......

謝謝你的幫助!

回答

1

其實,我不知道德爾福2009年,但MSDN說:

注意DEFAULT_CHARSET是不是一個真正的字符集;相反,它是一個類似於NULL的常量,意思是「以任何可用的字符集顯示字符」。

所以我的猜測是,你只需要刪除所有你提到的代碼,它應該工作。

+0

感謝您的評論Lars D!我會要求某人在這樣的語言環境中嘗試我的應用。 – 2009-11-23 22:45:13

0

這個問題並不是真正的答案,但是對於D2009 +下的這段代碼可能會造成內存損壞的'小'注意。函數GetLocaleInfo「MSDN:返回在語言環境數據緩衝區中檢索到的字符數......」不是BYTES,因此在D2009 +中,必須爲每個字符分配2個字節。要做到這一點最好的辦法是寫:

GetMem(Buffer, iSize * SizeOf(Char)); //This will be safe for all delphi versions 

如果沒有這一點,你可能會導致不可預測的AV(D2009 +),功能GetLocaleInfo可以覆蓋你的記憶,因爲您已經分配過小的緩衝區。

此外,我不明白爲什麼你要改變字符集到用戶區域設置一,我認爲你應該改變字符集到你的目的地翻譯(例如,你的程序被設置爲翻譯爲俄語,但運行英文操作系統,那麼你需要改變字符集到RUSSIAN_CHARSET,而不是ANSI_CHARSET)。而在D2009 +我不確定這是否需要,但我可能是錯的。

+0

好點。謝謝。 – 2009-11-23 22:50:13