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