Thanks Alpinist,You're welcome
I'll have a look at all that and see if that will work for me.
One of the problems of the traditional visual studio translation system is that when language resource dlls were not entirely in sync with the exe the result would be quite messed up.Yeah, quite a fragile environment. And the translation was the least thing that can go wrong. Not to mention its way of handling databases.
Hello fatmonk,
I'm using the following steps to achieve the result:
- Including PO files as a RC_DATA resources, each resource named as TRANSLATION.xx where the xx is the language code
- Adding the following unit translateu.pas into project
- Changing language with TranslateFromResource('bg') or whatever language resource included
There are issues, though. One of them is that if there is a translation of a specific item in, say 'bg' language, and there is no such translation in 'en' language (because it is the base for the form resource), translating to 'bg' and then back to 'en' won't change the item and it will stay in 'bg' form. But this is actually a general problem of a PO I18N way.
To cope with that, the PO files for all languages must have all items translated, even the base/design language.
Here is the translateu.pas source:
unit translateu; {$mode objfpc}{$H+} interface uses Classes, SysUtils; function TranslateFromResource(const Language: String; ForceUpdate: Boolean = True; const ResFile: String = 'TRANSLATION'): Boolean; implementation uses LCLTranslator, LResources, Translations, LCLType, Forms; function TranslateFromResource(const Language: String; ForceUpdate: Boolean; const ResFile: String): Boolean; var Res: TResourceStream; PoFile: TPOFile; LocalTranslator: TUpdateTranslator; I: Integer; begin Res := TResourceStream.Create(HInstance, ResFile + '.' + Language, RT_RCDATA); try PoFile := TPOFile.Create(Res); Result := TranslateResourceStrings(PoFile); LocalTranslator := TPOTranslator.Create(PoFile); if Assigned(LRSTranslator) then LRSTranslator.Free; LRSTranslator := LocalTranslator; if ForceUpdate then begin for I := 0 to Pred(Screen.CustomFormCount) do LocalTranslator.UpdateTranslation(Screen.CustomForms[I]); for I := 0 to Pred(Screen.DataModuleCount) do LocalTranslator.UpdateTranslation(Screen.DataModules[I]); end; finally Res.Free; end; end;
Hope that helps.
Regards,
Ah, I think I've spotted it now that I've shut down for the evening!
Missing an end. at the end of the unit!
Will try again tomorrow.
-FM
Is there anything else I need to do other than [...]
There is the issue, that Lazarus doesn't know when the resource was changed so it isn't automatically compiled. I just change the unit (e.g. adding an empty line) to tell Lazarus the unit should be recompiled on the next build. Perhaps there is a better method. Anyone?I have the same problem with the changed resources. I also touch some whitespace to force the make, but that affects the version control and I must revert if it isn't an actual change. :(