在Delphi 7中进行字符串转换

时间:2012-09-09 06:54:01

标签: delphi unicode localization delphi-7 ansi

我的应用程序是用Delphi 7编写的非unicode应用程序。

我想用这个函数将unicode字符串转换为ANSI:

function convertU(ws : widestring) : string;
begin
  result := string(ws);
end;

我还使用此代码设置要转换的正确代码页。

initialization
  SetThreadLocale(GetSystemDefaultLCID);
  GetFormatSettings;

它在VCL主线程中运行良好,但在TThread中运行不正常, 函数 convertU 导致我得到一些问题'?

为什么不在TThread?

2 个答案:

答案 0 :(得分:6)

AFAIK SetThreadLocale不会更改当前的系统代码页,因此不会影响Delphi 7中的widestringansistring转换,后者依赖于GetACP API调用,即系统代码页。

系统代码页设置为例如在控制面板中的Windows 7中,然后是非Unicode应用程序的区域语言/管理选项卡/代码页。这需要重新启动系统。

Delphi 7使用此系统代码页,为所有转换API调用提供0。因此,AFAIR SetThreadLocale不会影响Delphi 7中的widestringansistring转化。它会更改区域设置(例如日期/时间和货币格式),而不会更改其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的组件;
  • 使用您自己的类型,使用专用的字符集,但在使用VCL / RTL或“Ansi”API调用之前,您需要进行显式转换 - 例如MyString = type AnsiString(这是我们在mORMot中所做的,通过为内部UTF-8流程定义自定义RawUTF8类型。)

使用Delphi 2009及更高版本可以更好地处理这个问题,因为您可以为每个AnsiString类型指定一个代码页,并正确处理与Unicode之间的转换,以及API调用或VCL处理。

答案 1 :(得分:5)

SetThreadLocale()块内调用initializationTThread没有影响。如果要设置线程的区域设置,则必须在SetThreadLocale()方法内调用TThread.Execute()

更好的选择是完全不依赖SetThreadLocale()。通过直接调用WideCharToMultiByte()进行自己的转换,以便指定要转换为的特定Ansi代码页。