// Resource converter to utf-8 by Alexander Fediachov (Samuray) // 29.11.2007 program res2utf8; {$APPTYPE CONSOLE} {$WARN SYMBOL_PLATFORM OFF} uses Windows, SysUtils, Classes, frxXML; var Codepages: TStringList; StartDir: String; procedure Help; begin WriteLn('Usage: res2utf8.exe codepages.txt'); end; procedure DoConvertFile(const FileName: String; const Lang: String); var FoutXML: TfrxXMLDocument; VName, Val, outname: String; us: WideString; j, idx: Integer; cp: Integer; List: TStringList; Root: TfrxXMLItem; begin List := TStringList.Create; List.LoadFromFile(FileName); FoutXML := TfrxXMLDocument.Create; FoutXML.Root.Name := 'Resources'; FoutXML.AutoIndent := True; Root := FoutXML.Root; outname := ChangeFileExt(FileName, '.xml'); if FileExists(outname) then DeleteFile(outname); try if Codepages.Values[UpperCase(Lang)] <> '' then cp := StrToInt(Codepages.Values[UpperCase(Lang)]) else cp := 0; FoutXML.Root.Prop['CodePage'] := IntToStr(cp); try for idx := 0 to List.Count - 1 do begin VName := List[idx]; Val := Copy(VName, Pos('=', VName) + 1, MaxInt); VName := Copy(VName, 1, Pos('=', VName) - 1); if (Length(VName) = 0) or (Length(Val) = 0) then continue; j := MultiByteToWideChar(cp, 0, PAnsiChar(Val), Length(Val), nil, 0); SetLength(us, j); MultiByteToWideChar(cp, 0, PAnsiChar(Val), Length(Val), PWideChar(us), j); SetLength(Val, Length(us) * 6); j := UnicodeToUtf8(PChar(Val), Length(us) * 6, PWideChar(us), Length(us)); SetLength(Val, j - 1); with Root.Add do begin Name := 'StrRes'; Prop['Name'] := VName; Prop['Text'] := frxStrToXML(Val); end; end; except on e: Exception do WriteLn(e.Message); end; WriteLn(ExtractFileName(FileName) + ' -> ' + outname); FoutXML.SaveToFile(outname); finally FoutXML.Free; List.Free; end; end; procedure DoConvert(const Dir: String; const Lang: String); var SRec: TSearchRec; i: Integer; begin i := FindFirst(Dir + '\*.*', faDirectory + faArchive, SRec); try while i = 0 do begin if (SRec.Name <> '.') and (SRec.Name <> '..') then begin if (LowerCase(ExtractFileExt(SRec.Name)) = '.frc') then DoConvertFile(Dir + '\' + SRec.Name, Lang) else if (SRec.Attr and faDirectory) = faDirectory then begin WriteLn(SRec.Name + ':'); DoConvert(Dir + '\' + SRec.Name, SRec.Name); end; end; i := FindNext(SRec); end; WriteLn; finally FindClose(SRec); end; end; begin if (ParamCount > 0) and FileExists(ParamStr(1)) then begin Codepages := TStringList.Create; try Codepages.LoadFromFile(ParamStr(1)); Codepages.Text := UpperCase(Codepages.Text); StartDir := GetCurrentDir; DoConvert(StartDir, ''); finally Codepages.Free; end; end else Help; end.