I'm иrazilian and I need the Firemonkey's Resource Strings in my language, for example when I use the dialogs. I couldn't find a way to translate it. Does someone know how to do it?
-
What exactly do you need to translate? Something like the OK button on ShowMessage? – David Heffernan Apr 17 '12 at 17:46
-
1Dialogs are somewhat special, as normally the OS dialogs are used, which probably are displayed in the current OS language. – Uwe Raabe Apr 17 '12 at 17:50
-
There is no "Firemonkey's API". Are you talking about resource strings (strings for built-in dialogs and button captions)? – Ken White Apr 17 '12 at 17:57
-
Probably is not that clear. You don't need API in your language but the constants already defined in Delphi. – EMBarbosa Apr 17 '12 at 18:00
-
1A search for "resourcestring" in the 'fmx' source folder yields only one file: 'FMX.Consts.pas', a really small file... – Sertac Akyuz Apr 17 '12 at 18:00
-
3@Uwe I'd guess that FMX doesn't use the system dialogs – David Heffernan Apr 17 '12 at 18:07
-
1@David, indeed they do! In Windows they use GetOpenFileNameW, while for Mac they use some Cocoa stuff. Have a look into FMX.Platform.Win and FMX.Platform.Mac and search for TPlatform descendants and DialogOpenFiles. – Uwe Raabe Apr 17 '12 at 18:56
-
1@Uwe That's one dialog. Have you tried `ShowMessage` yet? I bet that doesn't use system dialog. As for the file dialogs, I bet they look dreadful when you are using some funky FMX style and suddenly you land back in a native platform dialog! – David Heffernan Apr 17 '12 at 19:05
3 Answers
What you need is something like this, but for FMX. In a quick search, the only file that I've found in help for Delphi XE2 is FMX.Consts
. You take that file, translate it, and then put the translated file in your project.
Take care when Delphi got an update. The original file can be changed and you will need to update your translation. Also, you will probably want to change any others files that have Resource Strings, and are in use by your project.
Finally, I'm not expert in this, but if you are planing use multi-language, this could be not the better approach.

- 1,473
- 1
- 22
- 76
-
1It's actually good if you can use Delphi's internal ITE, because it pulls all strings necessary for translation out for you and you know what you have to translate. It can even identify your own string constants, if they're declared as `resourcestring` constants. However, when you have 5 comments asking for the question to be clarified because it isn't clear, you should try not to answer until it's edited by the poster. Answering it means they have no reason to improve it, and if it's really unclear it's of no use to future readers searching here. :) And `resourcestring` uses a resourcetable, – Ken White Apr 17 '12 at 18:15
-
1(continued), so even if you can't use ITE you can extract the resource and set up a second one based on another language ID. – Ken White Apr 17 '12 at 18:16
-
@KenWhite Thanks for suggestions. I'm sorry. I've answered cause as a Portuguese speaker and Delphi user I could understand what he is looking for. Indeed, one of the comments that claims OP is not clear is mine. Anyway, I will take your advice next time. – EMBarbosa Apr 17 '12 at 18:37
-
Sorry, I tough I was clear for you. But @EMBarbosa got my question, maybe because he needed to use it in another Delphi's version. I translated the FMX.Consts file, but anything is changed in my project. The buttons and dialog captions were not changed :( – llanfair Apr 17 '12 at 18:44
-
3@JuninhoDG You are doing it wrong. Do this: 1. Make a copy of FMX.Consts.pas, somewhere in your project file tree. 2. Add that copy to your project. 3. Translate that file. – David Heffernan Apr 17 '12 at 19:08
You can change dialogs using FMX.Consts.pas, but it fixes the language during compilation. If you want to check the language version of the host OS in runtime, you should correct FMX.Platform.Android.pas or FMX.Platform.iOS.pas.
For Android, in FMX.Platform.Android.pas, in procedure TPlatformAndroid.MessageDialog... find ButtonCaptions and surround it with your own function, for example: ZSTranslate( ButtonCaptions[B]). Declare ZSTranslate in the following way:
function ZSTranslate(txt: String):String;
var
LocaleSvc: IFMXLocaleService;
begin
LocaleSvc := TPlatformServices.Current.GetPlatformService(IFMXLocaleService) as IFMXLocaleService;
result:=txt;
if LocaleSvc.GetCurrentLangID ='your_language_two_letter_id' then
begin
if txt= 'Yes' then
result := 'yes in your language'
else
if txt= 'No' then
result := 'no in your language'
else
if txt= 'Confirm' then
result := 'confirm in your language'
else
if txt= 'Cancel' then
result := 'cancel in your language';
end
end;
Place ZSTranslate somewhere above TPlatformAndroid.MessageDialog in a copy of FMX.Platform.Android.pas, and add this corrected version of FMX.Platform.Android.pas to your project.
Note that above example is very simple, and as far as I remember there is unsolved case in Embarcadero quality system, suggesting translate method here (so TLang should work ok). I did not try with translate, my version did the job (as there are just a few button labels in dialogs and I wanted only two different languages).
For iOS you should look in FMX.Platform.iOS.pas for function TPlatformCocoaTouch.MessageDialog. Please note, that there are two overloaded versions. There are also MsgTitles and ButtonCaptions in iOS, as dialogs at iOS show captions.
PS. For Polish I had to correct also GetCurrentLangID method, because it always returned 'en' - please double-check the result for your language. The versions that worked for me: in FMX.Platform.iOS.pas:
function TPlatformCocoaTouch.GetCurrentLangID: string;
var
lngs : NSArray;
CurrentLocale: NSLocale;
LanguageISO: NSString;
begin
lngs := TNSLocale.OCClass.preferredLanguages;
LanguageISO:= TNSString.Wrap(lngs.objectAtIndex(0));
//CurrentLocale := TNSLocale.Wrap(TNSLocale.OCClass.currentLocale);
//LanguageISO := TNSString.Wrap(CurrentLocale.objectForKey((NSLocaleLanguageCode as ILocalObject).GetObjectID));
Result := UTF8ToString(LanguageISO.UTF8String);
if Length(Result) > 2 then
Delete(Result, 3, MaxInt);
end;
in FMX.Platform.Android.pas:
function TPlatformAndroid.GetCurrentLangID: string;
var
Locale: JLocale;
begin
Locale := TJLocale.JavaClass.getDefault;
Result := JStringToString(Locale.getLanguage);//getISO3Language); //zs
if Length(Result) > 2 then
Delete(Result, 3, MaxInt);
end;

- 205
- 2
- 6