@@ -27,12 +27,19 @@ interface
2727{ $I LangIDs.inc}
2828
2929type
30+ TCPData = record
31+ CPID: Integer;
32+ CPName: String;
33+ CPLang: String;
34+ end ;
35+
3036 TdevMultiLangSupport = class (TObject)
3137 private
3238 fLangList: TStringList;
3339 fLangListLoaded: Boolean;
3440 fLangFile: String;
3541 fCurLang: String;
42+ fCurCodePage: Integer;
3643 fStrings: TStringList;
3744 fDefaultLangStrings: TStringList;
3845 function GetString (ID: integer): String;
@@ -50,17 +57,201 @@ TdevMultiLangSupport = class(TObject)
5057 property CurrentLanguage: String read GetLangName;
5158 property Langs: TStringList read GetLangList;
5259 end ;
60+ // https://stackoverflow.com/questions/2574289/codepage-id-to-codepage-name-getencoding-equivalent-in-delphi
61+ const
62+ MaxEncodings = 20 ;// 148;
63+
64+ Encodings: Array [0 ..MaxEncodings - 1 ] of TCPData =
65+ (
66+ // (CPID: 37; CPName: 'IBM037'),
67+ // (CPID: 437; CPName: 'IBM437'),
68+ // (CPID: 500; CPName: 'IBM500'),
69+ // (CPID: 708; CPName: 'ASMO-708'),
70+ // (CPID: 720; CPName: 'DOS-720'),
71+ // (CPID: 737; CPName: 'ibm737'),
72+ // (CPID: 775; CPName: 'ibm775'),
73+ // (CPID: 850; CPName: 'ibm850'),
74+ // (CPID: 852; CPName: 'ibm852'),
75+ // (CPID: 855; CPName: 'IBM855'),
76+ // (CPID: 857; CPName: 'ibm857'),
77+ // (CPID: 858; CPName: 'IBM00858'),
78+ // (CPID: 860; CPName: 'IBM860'),
79+ // (CPID: 861; CPName: 'ibm861'),
80+ // (CPID: 862; CPName: 'DOS-862'),
81+ // (CPID: 863; CPName: 'IBM863'),
82+ // (CPID: 864; CPName: 'IBM864'),
83+ // (CPID: 865; CPName: 'IBM865'),
84+ // (CPID: 866; CPName: 'cp866'),
85+ // (CPID: 869; CPName: 'ibm869'),
86+ // (CPID: 870; CPName: 'IBM870'),
87+ // (CPID: 874; CPName: 'windows-874'),
88+ // (CPID: 875; CPName: 'cp875'),
89+ (CPID: 932 ; CPName: ' shift_jis' ; CPLang: ' Japanese' ;),
90+ (CPID: 936 ; CPName: ' gb2312' ; CPLang: ' Chinese' ;),
91+ (CPID: 949 ; CPName: ' ks_c_5601-1987' ; CPLang: ' Korean' ;),
92+ // (CPID: 950; CPName: 'big5'),
93+ // (CPID: 1026; CPName: 'IBM1026'),
94+ // (CPID: 1047; CPName: 'IBM01047'),
95+ // (CPID: 1140; CPName: 'IBM01140'),
96+ // (CPID: 1141; CPName: 'IBM01141'),
97+ // (CPID: 1142; CPName: 'IBM01142'),
98+ // (CPID: 1143; CPName: 'IBM01143'),
99+ // (CPID: 1144; CPName: 'IBM01144'),
100+ // (CPID: 1145; CPName: 'IBM01145'),
101+ // (CPID: 1146; CPName: 'IBM01146'),
102+ // (CPID: 1147; CPName: 'IBM01147'),
103+ // (CPID: 1148; CPName: 'IBM01148'),
104+ // (CPID: 1149; CPName: 'IBM01149'),
105+ // (CPID: 1200; CPName: 'utf-16'),
106+ // (CPID: 1201; CPName: 'unicodeFFFE'),
107+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Croatian' ;),
108+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Czech' ;),
109+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Hungarian' ;),
110+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Polish' ;),
111+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Romanian' ;),
112+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Slovak' ;),
113+ (CPID: 1250 ; CPName: ' windows-1250' ; CPLang: ' Slovenian' ;),
114+ (CPID: 1251 ; CPName: ' windows-1251' ; CPLang: ' Russian' ;),
115+ (CPID: 1251 ; CPName: ' windows-1251' ; CPLang: ' Ukrainian' ;),
116+ (CPID: 1252 ; CPName: ' Windows-1252' ; CPLang: ' English' ;),
117+ (CPID: 1253 ; CPName: ' windows-1253' ; CPLang: ' Greek' ;),
118+ (CPID: 1254 ; CPName: ' windows-1254' ; CPLang: ' Turkish' ;),
119+ (CPID: 1255 ; CPName: ' windows-1255' ; CPLang: ' Hebrew' ;),
120+ // (CPID: 1256; CPName: 'windows-1256'),
121+ // (CPID: 1257; CPName: 'windows-1257'),
122+ // (CPID: 1258; CPName: 'windows-1258'),
123+ // (CPID: 1361; CPName: 'Johab'),
124+ // (CPID: 10000; CPName: 'macintosh'),
125+ // (CPID: 10001; CPName: 'x-mac-japanese'),
126+ // (CPID: 10002; CPName: 'x-mac-chinesetrad'),
127+ // (CPID: 10003; CPName: 'x-mac-korean'),
128+ // (CPID: 10004; CPName: 'x-mac-arabic'),
129+ // (CPID: 10005; CPName: 'x-mac-hebrew'),
130+ // (CPID: 10006; CPName: 'x-mac-greek'),
131+ // (CPID: 10007; CPName: 'x-mac-cyrillic'),
132+ // (CPID: 10008; CPName: 'x-mac-chinesesimp'),
133+ // (CPID: 10010; CPName: 'x-mac-romanian'),
134+ // (CPID: 10017; CPName: 'x-mac-ukrainian'),
135+ // (CPID: 10021; CPName: 'x-mac-thai'),
136+ // (CPID: 10029; CPName: 'x-mac-ce'),
137+ // (CPID: 10079; CPName: 'x-mac-icelandic'),
138+ // (CPID: 10081; CPName: 'x-mac-turkish'),
139+ // (CPID: 10082; CPName: 'x-mac-croatian'),
140+ // (CPID: 12000; CPName: 'utf-32'),
141+ // (CPID: 12001; CPName: 'utf-32BE'),
142+ // (CPID: 20000; CPName: 'x-Chinese-CNS'),
143+ // (CPID: 20001; CPName: 'x-cp20001'),
144+ // (CPID: 20002; CPName: 'x-Chinese-Eten'),
145+ // (CPID: 20003; CPName: 'x-cp20003'),
146+ // (CPID: 20004; CPName: 'x-cp20004'),
147+ // (CPID: 20005; CPName: 'x-cp20005'),
148+ // (CPID: 20105; CPName: 'x-IA5'),
149+ // (CPID: 20106; CPName: 'x-IA5-German'),
150+ // (CPID: 20107; CPName: 'x-IA5-Swedish'),
151+ // (CPID: 20108; CPName: 'x-IA5-Norwegian'),
152+ // (CPID: 20127; CPName: 'us-ascii'),
153+ // (CPID: 20261; CPName: 'x-cp20261'),
154+ // (CPID: 20269; CPName: 'x-cp20269'),
155+ // (CPID: 20273; CPName: 'IBM273'),
156+ // (CPID: 20277; CPName: 'IBM277'),
157+ // (CPID: 20278; CPName: 'IBM278'),
158+ // (CPID: 20280; CPName: 'IBM280'),
159+ // (CPID: 20284; CPName: 'IBM284'),
160+ // (CPID: 20285; CPName: 'IBM285'),
161+ // (CPID: 20290; CPName: 'IBM290'),
162+ // (CPID: 20297; CPName: 'IBM297'),
163+ // (CPID: 20420; CPName: 'IBM420'),
164+ // (CPID: 20423; CPName: 'IBM423'),
165+ // (CPID: 20424; CPName: 'IBM424'),
166+ // (CPID: 20833; CPName: 'x-EBCDIC-KoreanExtended'),
167+ // (CPID: 20838; CPName: 'IBM-Thai'),
168+ // (CPID: 20866; CPName: 'koi8-r'),
169+ // (CPID: 20871; CPName: 'IBM871'),
170+ // (CPID: 20880; CPName: 'IBM880'),
171+ // (CPID: 20905; CPName: 'IBM905'),
172+ // (CPID: 20924; CPName: 'IBM00924'),
173+ // (CPID: 20932; CPName: 'EUC-JP'),
174+ // (CPID: 20936; CPName: 'x-cp20936'),
175+ // (CPID: 20949; CPName: 'x-cp20949'),
176+ (CPID: 21025 ; CPName: ' cp1025' ; CPLang: ' Bulgarian' ;),
177+ // (CPID: 21866; CPName: 'koi8-u'),
178+ // (CPID: 28591; CPName: 'iso-8859-1'),
179+ // (CPID: 28592; CPName: 'iso-8859-2'),
180+ // (CPID: 28593; CPName: 'iso-8859-3'),
181+ (CPID: 28594 ; CPName: ' iso-8859-4' ; CPLang: ' Estonian' ;),
182+ (CPID: 28594 ; CPName: ' iso-8859-4' ; CPLang: ' Latvian' ;),
183+ // (CPID: 28595; CPName: 'iso-8859-5'),
184+ // (CPID: 28596; CPName: 'iso-8859-6'),
185+ // (CPID: 28597; CPName: 'iso-8859-7'),
186+ // (CPID: 28598; CPName: 'iso-8859-8'),
187+ // (CPID: 28599; CPName: 'iso-8859-9'),
188+ // (CPID: 28603; CPName: 'iso-8859-13'),
189+ // (CPID: 28605; CPName: 'iso-8859-15'),
190+ // (CPID: 29001; CPName: 'x-Europa'),
191+ // (CPID: 38598; CPName: 'iso-8859-8-i'),
192+ // (CPID: 50220; CPName: 'iso-2022-jp'),
193+ // (CPID: 50221; CPName: 'csISO2022JP'),
194+ // (CPID: 50222; CPName: 'iso-2022-jp'),
195+ // (CPID: 50225; CPName: 'iso-2022-kr'),
196+ // (CPID: 50227; CPName: 'x-cp50227'),
197+ // (CPID: 51932; CPName: 'euc-jp'),
198+ // (CPID: 51936; CPName: 'EUC-CN'),
199+ // (CPID: 51949; CPName: 'euc-kr'),
200+ // (CPID: 52936; CPName: 'hz-gb-2312'),
201+ // (CPID: 54936; CPName: 'GB18030'),
202+ // (CPID: 57002; CPName: 'x-iscii-de'),
203+ // (CPID: 57003; CPName: 'x-iscii-be'),
204+ // (CPID: 57004; CPName: 'x-iscii-ta'),
205+ // (CPID: 57005; CPName: 'x-iscii-te'),
206+ // (CPID: 57006; CPName: 'x-iscii-as'),
207+ // (CPID: 57007; CPName: 'x-iscii-or'),
208+ // (CPID: 57008; CPName: 'x-iscii-ka'),
209+ // (CPID: 57009; CPName: 'x-iscii-ma'),
210+ // (CPID: 57010; CPName: 'x-iscii-gu'),
211+ // (CPID: 57011; CPName: 'x-iscii-pa'),
212+ // (CPID: 65000; CPName: 'utf-7'),
213+ (CPID: 65001 ; CPName: ' utf-8' )
214+ );
53215
54216function Lang : TdevMultiLangSupport;
55217
56218implementation
57219
58220uses
59- System.UITypes, LangFrm, Forms, Utils, Version, Controls, devCFG;
221+ System.WideStrUtils, System. UITypes, LangFrm, Forms, Utils, Version, Controls, devCFG;
60222
61223var
62224 fLangSingleton: TdevMultiLangSupport = nil ;
63225
226+ function GetEncoding (CPID: Integer): String;
227+ var
228+ I: Integer;
229+ begin
230+ Result := ' iso-8859-2' ; // put the default encoding here
231+
232+ for I := 0 to MaxEncodings - 1 do
233+ if Encodings[I].CPID = CPID then
234+ begin
235+ Result := Encodings[I].CPName;
236+ break;
237+ end ;
238+ end ;
239+
240+ function GetCodePage (const ALanguage: String): Integer;
241+ var
242+ I: Integer;
243+ begin
244+ Result := 1252 ; // put the default encoding here
245+
246+ for I := 0 to MaxEncodings - 1 do
247+ if ALanguage.IndexOf(Encodings[I].CPLang)>-1 then
248+ begin
249+ Result := Encodings[I].CPID;
250+ break;
251+ end ;
252+ end ;
253+
254+
64255function Lang : TdevMultiLangSupport;
65256begin
66257 if not Assigned(fLangSingleton) and not Application.Terminated then
@@ -77,6 +268,7 @@ constructor TdevMultiLangSupport.Create;
77268 fLangListLoaded := False; // only load when needed
78269 fStrings := TStringList.Create;
79270 fDefaultLangStrings := TStringList.Create;
271+ fCurCodePage := 1252 ;
80272
81273 // Load default english file from languages directory
82274 DefaultLangFile := ValidateFile(' English.lng' , devDirs.Lang);
@@ -108,13 +300,15 @@ procedure TdevMultiLangSupport.Open(const Filename: String);
108300 end ;
109301
110302 // Load file into fStrings
111- fStrings.LoadFromFile(LangFile);
303+ fStrings.LoadFromFile(LangFile,TEncoding.ANSI );
112304 fLangFile := LangFile;
113305
114306 // Get languange
115307 fCurLang := fStrings.Values[' Lang' ];
116308 if fCurLang = ' ' then
117309 fCurLang := ChangeFileExt(ExtractFileName(LangFile), ' ' );
310+
311+ fCurCodePage := GetCodePage(fCurLang);
118312 devData.Language := ExtractFileName(LangFile);
119313end ;
120314
@@ -158,7 +352,7 @@ procedure TdevMultiLangSupport.CheckLanguageFiles;
158352
159353function TdevMultiLangSupport.GetString (ID: integer): String;
160354begin
161- result := fStrings.Values[IntToStr(ID)];
355+ result := AnsiToUtf8Ex( fStrings.Values[IntToStr(ID)],fCurCodePage) ;
162356 if Result = ' ' then
163357 Result := fDefaultLangStrings.Values[IntToStr(ID)];
164358 if result = ' ' then
0 commit comments