2009-11-13 20 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