我的delphi 2009应用程序有一个使用GNUGetText的基本翻译系统。我使用了一些win API调用来准备字体。直到最近,当马耳他的某个人的应用程序出现问题时,我认为它才能正常工作。我的应用程序全局使用。由于d2009使用unicode,因此部分代码可能已经过时。
是否真的有必要让我的应用在所有区域设置中运行?
TForm.Font.Charset
我的理解是我必须根据用户的语言环境设置TForm实例的Font.Charset。这是对的吗?
TranslateCharsetInfo()获取API函数
delphi 2009的windows.pas说:
function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo;
dwFlags: DWORD): BOOL;
delphi 5的windows.pas说:
function TranslateCharsetInfo(var lpSrc: DWORD; var lpCs: TCharsetInfo;
dwFlags: DWORD): BOOL; stdcall;
来自microsoft的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不能自动完成大部分/全部操作吗?我的直觉告诉我,我正在努力工作......
谢谢你的帮助!
答案 0 :(得分:1)
实际上,我不确定Delphi 2009,但是MSDN说:
请注意,DEFAULT_CHARSET不是真正的字符集;相反,它是一个类似于NULL的常量,意味着“在任何字符集中显示字符都可用。”
所以我的猜测是你只需要删除你提到的所有代码,它应该可以工作。
答案 1 :(得分:0)
不是这个问题的真正答案,而是在D2009 +下使用此代码可能导致内存损坏的“小”注释。函数GetLocaleInfo“MSDN:返回在语言环境数据缓冲区中检索的字符数...”不是BYTES,所以在D2009 +下,你必须为每个字符分配2个字节。最好的方法是写:
GetMem(Buffer, iSize * SizeOf(Char)); //This will be safe for all delphi versions
如果没有这个你可以导致不可预知的AV(D2009 +),函数GetLocaleInfo可以覆盖你的内存,因为你已经分配了太小的缓冲区。
另外我不明白你为什么要尝试将变更字符集改为用户区域设置,我认为你应该将charset更改为你的目标翻译(比如,你的程序设置为翻译成俄语,但是用英语运行) OS,那么你需要将charset更改为RUSSIAN_CHARSET,而不是ANSI_CHARSET)。在D2009 +我不确定是否需要这个,但我可能错了。