Delphi 7中的Widestring到字符串转换
我的应用程序是一个用Delphi 7编写的非Unicode应用程序。
我想用这个函数将unicode字符串转换为ANSI:
function convertU(ws : widestring) : string;
begin
result := string(ws);
end;
我也使用此代码来设置要转换的正确的代码页。
initialization
SetThreadLocale(GetSystemDefaultLCID);
GetFormatSettings;
它在VCL主线程中运行良好,但不在TThread中,在那里我得到一些问题标记'?' 作为函数convertU的结果。
为什么不在TThread中?
在initialization
块内调用SetThreadLocale()
对TThread
没有影响。 如果要设置线程的语言环境,则必须在TThread.Execute()
方法内调用SetThreadLocale()
。
更好的选择是完全不依赖SetThreadLocale()
。 通过直接调用WideCharToMultiByte()
自己的转换,以便指定要转换的特定Ansi代码页。
AFAIK SetThreadLocale
不改变当前系统代码页,所以不会影响widestring
以ansistring
在Delphi 7,依靠转换GetACP
API调用,即该系统的代码页。
系统代码页被设置为例如在控制面板中的Windows Seven中,然后针对非Unicode应用程序的区域语言/管理选项卡/代码页。 这需要重新启动系统。
Delphi 7使用此系统代码页,为所有转换API调用提供0。 所以AFAIR SetThreadLocale
不会影响widestring
到ansistring
转换在Delphi 7.都会改变本地化(例如日期/时间和货币格式),而不是由系统以其安西使用的代码页< - > Unicode转换。
较新版本的Delphi具有SetMultiByteConversionCodePage()
函数,能够将代码页设置为用于所有AnsiString
处理。
但是API调用(即所有....A()
函数在Windows.pas中被映射为...()
在Delphi 7中)将使用这个系统代码页。 所以如果你想处理另一个代码页,你必须在转换为Unicode之后调用...W()
宽API。 也就是说,Delphi 7 VCL只能用于系统代码页,而不SetThreadLocale
指定的值。
在Delphi 7下,我的建议是:
WideString
,以及特定的“Wide”API调用 - Delphi 7中有几组组件用于处理WideString
; MyString = type AnsiString
(这是我们在mORMot中执行的操作,通过定义一个定制的RawUTF8
键入内部UTF-8进程)。 使用Delphi 2009或更高版本可以更好地处理这个问题,因为您可以为每个AnsiString
类型指定一个代码页,并且正确处理从Unicode转换到/从Unicode调用的API调用或VCL进程。