Inno Setup - 将字符串数组转换为 Unicode 并返回到 ANSI [英] Inno Setup - Convert array of string to Unicode and back to ANSI

查看:39
本文介绍了Inno Setup - 将字符串数组转换为 Unicode 并返回到 ANSI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将韩国 CP51949 (EUC-KR) 编码的 ANSI 文件加载到字符串数组 (LoadStringsFromFile) 中.我的系统和预期的最终用户系统没有将 CP51949 设置为传统的非 Unicode 编码.

目前我有两个问题:

  1. 除非我使用 Locale Emulator 运行应用程序(这很烦人,因为设置本身只有英文),否则韩语文本会显示为乱码.
  2. Pos 给出错误的结果并且 StringChange 完全失败,除非我切换到 String,做这件事,然后回到 AnsiString.

所以,我想知道是否有办法将数组转换为 unicode,然后在保存之前返回.

解决方案

要将使用特定 Ansi 编码的文件转换为 Unicode string (UTF-16 LE),请使用

I'm loading a Korean CP51949 (EUC-KR) encoded ANSI file into an array of strings (LoadStringsFromFile). My system and the intended end user systems do not have CP51949 set as a legacy non-Unicode encoding.

At the moment I have 2 problems with this:

  1. Unless I run the application with Locale Emulator (which is just annoying, since the setup itself is in English only), the Korean text is displayed as gibberish.
  2. Pos gives wrong results and StringChange fails completely unless I switch to String, do the thing, and then back to AnsiString.

So, I'm wondering if there's a way to convert the array to unicode, and then back before saving.

解决方案

To convert a file encoded in a specific Ansi encoding to Unicode string (UTF-16 LE), use MultiByteToWideChar function:

function MultiByteToWideChar(
  CodePage: UINT; dwFlags: DWORD; const lpMultiByteStr: AnsiString;
    cchMultiByte: Integer; lpWideCharStr: string; cchWideChar: Integer): Integer;
  external 'MultiByteToWideChar@kernel32.dll stdcall';  

function LoadStringFromFileInCP(
  FileName: string; var S: string; CP: Integer): Boolean;
var
  Ansi: AnsiString;
  Len: Integer;
begin
  Result := LoadStringFromFile(FileName, Ansi);
  if Result then
  begin
    Len := MultiByteToWideChar(CP, 0, Ansi, Length(Ansi), S, 0);
    SetLength(S, Len);
    MultiByteToWideChar(CP, 0, Ansi, Length(Ansi), S, Len);
  end;
end;

function LoadStringsFromFileInCP(
  FileName: string; Strings: TStrings; CP: Integer): Boolean;
var
  S: string;
begin
  Result := LoadStringFromFileInCP(FileName, S, CP);
  if Result then Strings.Text := S;
end;

(Note that I'm using TStrings to store strings/lines collection instead of TArrayOfString, as TStrings is easier to work with)


To convert Unicode string back to Ansi, use WideCharToMultiByte function:

function WideCharToMultiByte(CodePage: UINT; dwFlags: DWORD;
  lpWideCharStr: string; cchWideChar: Integer; lpMultiByteStr: AnsiString;
  cchMultiByte: Integer; lpDefaultCharFake: Integer;
  lpUsedDefaultCharFake: Integer): Integer;
  external 'WideCharToMultiByte@kernel32.dll stdcall';

function SaveStringToFileInCP(FileName: string; S: string; CP: Integer): Boolean;
var
  Ansi: AnsiString;
  Len: Integer;
begin
  Len := WideCharToMultiByte(CP, 0, S, Length(S), Ansi, 0, 0, 0);
  SetLength(Ansi, Len);
  WideCharToMultiByte(CP, 0, S, Length(S), Ansi, Len, 0, 0);
  Result := SaveStringToFile(FileName, Ansi, False);
end;

function SaveStringsToFileInCP(
  FileName: string; Strings: TStrings; CP: Integer): Boolean;
begin
  Result := SaveStringToFileInCP(FileName, Strings.Text, CP);
end;


Use the functions like:

const
  CP_EUC_KOREAN = 51949;

var
  I: Integer;
  Strings: TStrings;
begin
  Strings := TStringList.Create;
  if LoadStringsFromFileInCP('korean.txt', Strings, CP_EUC_KOREAN) then
  begin
    for I := 0 to Strings.Count - 1 do
    begin
      MsgBox(Strings[I], mbInformation, MB_OK);
    end;
  end;

  SaveStringsToFileInCP('korean_out.txt', Strings, CP_EUC_KOREAN);
end;


Works correctly on my English-only system:

这篇关于Inno Setup - 将字符串数组转换为 Unicode 并返回到 ANSI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆