Lazarus 字符集转换 Utf8ToAnsi,UTF8ToWinCP,UTF8ToSys,UTF8ToConsole

由于Lazarus从1.2版开始默认字符集就是UTF8,如果要转到系统正常显示或文本保存,就必须对字符集进行转换。Lazarus提供了很多函数。如题。

那么这里面有什么关系呢?

UTF8ToSys 需要 启用编译参数 –dDisableUTF8RTL,否则还是UTF8,如果变码还是Utf8ToAnsi,但做了基本的处理。

image

对应代码

function UTF8ToSys(const s: string): string;
begin
  {$IFDEF UTF8_RTL}
  Result:=s;
  {$ELSE}
  if NeedRTLAnsi and (not IsASCII(s)) then
    Result:=UTF8ToAnsi(s)
  else
    Result:=s;
  {$ENDIF}
end;

Utf8ToAnsi是freePascal 自带的,变码道Ansi ,在ustringh.inc文件里面

function Utf8ToAnsi(const s : RawByteString) : RawByteString;{$ifdef SYSTEMINLINE}inline;{$endif}
  begin
    Result:=RawByteString(Utf8Decode(s));
  end;
{$ifdef FPC_HAS_CPSTRING}
  RawByteString       = type AnsiString(CP_NONE);
{$else FPC_HAS_CPSTRING}
  RawByteString       = ansistring;
{$endif FPC_HAS_CPSTRING}

UTF8ToWinCP 是Lazarus 针对Windows 功能封包,不变化代码页,仅仅变化字符编码

{$ifdef WinCe}
function UTF8ToWinCP(const s: string): string; inline;
begin
  Result := Utf8ToSys(s);
end;
{$else}
function UTF8ToWinCP(const s: string): string;
// result has codepage CP_ACP
var
  src: UnicodeString;
  len: LongInt;
begin
  Result:=s;
  if IsASCII(Result) then begin
    {$ifdef FPC_HAS_CPSTRING}
    // prevent codepage conversion magic
    SetCodePage(RawByteString(Result), CP_ACP, False);
    {$endif}
    exit;
  end;
  src:=UTF8Decode(s);
  if src='' then
    exit;
  len:=WideCharToMultiByte(CP_ACP,0,PUnicodeChar(src),length(src),nil,0,nil,nil);
  SetLength(Result,len);
  if len>0 then begin
    WideCharToMultiByte(CP_ACP,0,PUnicodeChar(src),length(src),@Result[1],length(Result),nil,nil);
    {$ifdef FPC_HAS_CPSTRING}
    // prevent codepage conversion magic
    SetCodePage(RawByteString(Result), CP_ACP, False);
    {$endif}
  end;
end;
{$endif not wince}

UTF8ToConsole 是Lazarus 针对Windows 功能封包 ,变码后,同时会配置成默认代码页文本。

{$ifdef WinCe}
function UTF8ToConsole(const s: string): string; // converts UTF8 to console string (used by Write, WriteLn)
begin
  Result := UTF8ToSys(s);
end;
{$else}
function UTF8ToConsole(const s: string): string; // converts UTF8 to console string (used by Write, WriteLn)
var
  Dst: PChar;
begin
  {$ifndef NO_CP_RTL}
  Result := UTF8ToWinCP(s);
  {$else NO_CP_RTL}
  Result := UTF8ToSys(s); // Kept for compatibility
  {$endif NO_CP_RTL}
  Dst := AllocMem((Length(Result) + 1) * SizeOf(Char));
  if CharToOEM(PChar(Result), Dst) then
    Result := StrPas(Dst);
  FreeMem(Dst);
  {$ifndef NO_CP_RTL}
  SetCodePage(RawByteString(Result), CP_OEMCP, False);
  {$endif NO_CP_RTL}
end;
{$endif not WinCE}
posted @ 2019-05-19 11:08  海利鸟  阅读(1328)  评论(0编辑  收藏  举报