Inno Setup - 将字符串数组转换为 Unicode 并返回到 ANSI
Inno Setup - Convert array of string to Unicode and back to ANSI
我正在将朝鲜语 CP51949 (EUC-KR) 编码的 ANSI 文件加载到字符串数组 (LoadStringsFromFile
) 中。我的系统和预期的最终用户系统没有将 CP51949 设置为传统的非 Unicode 编码。
目前我有两个问题:
- 除非我 运行 带有 Locale Emulator 的应用程序(这很烦人,因为设置本身只有英文),韩文文本显示为乱码。
Pos
给出了错误的结果并且 StringChange
完全失败,除非我切换到 String
,执行操作,然后返回 AnsiString
。
所以,我想知道是否有办法将数组转换为 unicode,然后在保存之前返回。
要将以特定 Ansi 编码编码的文件转换为 Unicode string
(UTF-16 LE),请使用 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;
(请注意,我使用 TStrings
来存储 strings/lines 集合而不是 TArrayOfString
,因为 TStrings
更易于使用)
要将 Unicode string
转换回 Ansi,请使用 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;
使用如下函数:
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;
在我的纯英文系统上正常工作:
我正在将朝鲜语 CP51949 (EUC-KR) 编码的 ANSI 文件加载到字符串数组 (LoadStringsFromFile
) 中。我的系统和预期的最终用户系统没有将 CP51949 设置为传统的非 Unicode 编码。
目前我有两个问题:
- 除非我 运行 带有 Locale Emulator 的应用程序(这很烦人,因为设置本身只有英文),韩文文本显示为乱码。
Pos
给出了错误的结果并且StringChange
完全失败,除非我切换到String
,执行操作,然后返回AnsiString
。
所以,我想知道是否有办法将数组转换为 unicode,然后在保存之前返回。
要将以特定 Ansi 编码编码的文件转换为 Unicode string
(UTF-16 LE),请使用 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;
(请注意,我使用 TStrings
来存储 strings/lines 集合而不是 TArrayOfString
,因为 TStrings
更易于使用)
要将 Unicode string
转换回 Ansi,请使用 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;
使用如下函数:
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;
在我的纯英文系统上正常工作: