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),请使用
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:
- 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.
Pos
gives wrong results andStringChange
fails completely unless I switch toString
, do the thing, and then back toAnsiString
.
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屋!