zed 10 Posted March 23, 2023 No, I mean what should I do in my Test.exe to make it possible to load translations from some subfolder? I don't like idea to keep this files in the application root folder. Share this post Link to post
Anders Melander 1705 Posted March 23, 2023 7 hours ago, zed said: No, I mean what should I do in my Test.exe to make it possible to load translations from some subfolder? I don't like idea to keep this files in the application root folder. Ah, I see. No, that isn't really supported, but I can see how that would be beneficial. I've created an issue for it: https://bitbucket.org/anders_melander/better-translation-manager/issues/39 Assuming you are using BTMs resource module load functions (amLocalization.Utils unit), you will have to modify the following function in the amLanguageInfo unit: function LoadNewResourceModule(LocaleItem: TLanguageItem; var ModuleFilename: string): HModule; overload; For example, change this: ModuleFilename := TPath.ChangeExtension(Filename, '.'+FileType); ...to this (note that this hard codes the sub-folder name): var Folder := TPath.Combine(TPath.GetDirectoryName(Filename), '.\lang'); ModuleFilename := TPath.Combine(Folder, TPath.GetFileNameWithoutExtension(Filename)+'.'+FileType); If you are using the RTLs built-in loading mechanism then there isn't any way I can think of. Share this post Link to post
CTorres 0 Posted July 12 (edited) Hi, First of all I wanted to thank Anders Melander for his application and for sharing it with the whole developer community. I am posting here because I have encountered a problem when dynamically loading the language libraries generated with BTM in projects developed with newer versions of Delphi, and I was hoping someone could help me. I've been using BTM for quite some time now and I developed the software under Delphi XE, here I have never had any problems. Things changed when I recently upgraded to more modern versions of Delphi (Delphi 11 and 12) and, after updating the corresponding BTM projects and generating the languages normally, when I changed at run time the language of my applications, the texts that come from resourcestrings were no longer translated. All the DFM controls appear perfectly translated in the language I have selected within the application, but in those points where the text is defined dynamically from a resourcestring, they are always shown in the original language in which I defined them. I load the language libraries with the reinit.pas unit and its LoadNewResourceModule, and I've never had any problem before with older versions of Delphi. Does anyone know why it treats differently the DFM texts (which it shows perfectly translated) and the resourcestrings (which it doesn't translate at all) and what I could do to fix it? Any help will be appreciated. Thanks! ------------- EDIT ------------- It always happens the same, after spending days trying to solve a problem without success, as soon as I ask for help I find the solution right under my nose. I found this post (I don't know how I missed it earlier) on this very forum: It describes my same problem and gives a solution by calling ResStringCleanupCache before loading the language library. I have tried it and now everything works perfectly. Thanks anyway and sorry for the inconvenience. Edited July 12 by CTorres Share this post Link to post
Anders Melander 1705 Posted July 12 13 minutes ago, CTorres said: Does anyone know why it treats differently the DFM texts (which it shows perfectly translated) and the resourcestrings (which it doesn't translate at all) and what I could do to fix it? The RTLs DFM and resourcestring load mechanisms are separate and, for the most part, completely different. The RTL's resourcestring handling changed in a recent version of Delphi and, assuming your dynamic resource DLL loader doesn't take this into account, I suspect that this is the cause of your problem. The problem is likely that the RTL is caching both the resolved resourcestrings and the resource module, so once a resource module has been loaded and a resourcestring has been resolved it will not be read from the resource module again. My guess is that since your dynamic resource module loader probably executes after the RTL has already loaded the default resource module, your module is ignored. If you place a breakpoint in System.pas LoadResString and run your application you will be able to see the sausages being made. You should end up in DelayLoadResourceModule (via FindResourceHInstance) where the decision is made to reuse an already loaded resource module if there is one or load one if there isn't (FWIW, the DFM loader also goes through this function). Once system.pas has done its thing, sysutils.pas replaces the default resourcestring loader with a caching string loader, so all resourcestrings resolved after that point will be cached. If all my guessed are correct, the solution will be to modify the resource entry of the main module record (maybe your solution already does this). Something like this: var Module: PLibModule := LibModuleList; while (Module <> nil) do begin if (Module.Instance = hInstance) then begin Module.ResInstance := TheModuleHandleOfYourResourceModule; break; end; Module := Module.Next; end; Note that this will not change the already cached resourcestrings. In order to do that you will need to call SysUtils.ResStringCleanupCache If the above doesn't solve the problem for you I will need you to: Create an issue at the bug tracker Attach a minimal reproducible example and I'll see if I can find a solution. Share this post Link to post
CTorres 0 Posted July 12 Thank you very much for your help, Anders. Indeed, the problem is that it loaded both modules but it cached the first one, the one of the original language, and from there it ignored the one of the selected language. I have solved it with the call to SysUtils.ResStringCleanupCache, thank you very much (updating the instance of the loaded module was already done before, but of course, with the resourcestrings already cached it had no effect). Best regards and thanks for your time! Share this post Link to post
limelect 48 Posted July 21 (edited) I have your demo In it HelloWorld.xlat I do not seem to translate. How am I translating? Your demo does not seem to show that Edited July 21 by limelect Share this post Link to post
Anders Melander 1705 Posted July 21 6 hours ago, limelect said: I do not seem to translate. How am I translating? Your question doesn't make sense. Please rephrase it. You message, before you edited it, said "No HEBREW to translate". If you are asking how to add an additional target language, then that is done by clicking on the little settings button on the Language bar (yes, it's a bad UI, I know): ...and then selecting the desired target languages: Share this post Link to post
aehimself 391 Posted July 21 @Anders Melander Is an auto-update feature planned for BTM in the future? That, and a filter to only show untranslated and/or changed entries would make BTM a perfect tool imo. Thank you very much for it! Share this post Link to post
Anders Melander 1705 Posted July 21 33 minutes ago, aehimself said: Is an auto-update feature planned for BTM in the future? Not really but it's a very reasonable feature request. Please create an issue for it. 36 minutes ago, aehimself said: a filter to only show untranslated and/or changed entries I assume you mean a filter on the module list because you can hide already translated entries by filtering on State=Pending in the property list. If so, please create an issue for this too. Share this post Link to post
limelect 48 Posted July 22 (edited) @Anders Melander Ok I found the HEBREW But my main problem is simple. In your demo Am I suppose to see the translated text It seems I do not understand how to use the source and the .xlat file I have been using DKLang for many years Can you elaborate on steps of new Delphiproject I am also trying to change in your application the source lang from Hebrew to English and I cannot Edited July 22 by limelect Share this post Link to post
Anders Melander 1705 Posted July 22 2 hours ago, limelect said: But my main problem is simple. In your demo Am I suppose to see the translated text Specify the project Source language. Specify the current Target language. Enter the translations in the grid. 2 hours ago, limelect said: It seems I do not understand how to use the source and the .xlat file I don't know what you mean by "how to use the source". The xlat file is BTM's translation project file; It contain the source texts and the translated texts for all selected target languages of the application being localized. BTM uses the information in this file to build the language modules (which are in fact just code-less DLLs containing the translated resourcestring and DFM resources) that are loaded at run-time by your application. See the Delphi help for info about how the Delphi localization system works (I believe I have some info at the project page too). 2 hours ago, limelect said: Can you elaborate on steps of new Delphiproject See: Getting started Share this post Link to post