Vandrovnik 214 Posted March 16, 2021 Hello, I use Better Translation Manager from @Anders Melander to create language modules. This works fine even with 10.4.2. In the application, I use resourcestrings. BTM translates them and saves them to, for example, .DEU file for German translation. I have checked with Resource Hacker that translated resourcestrings are there. In the application, I load resource file, it works for components. Unfortunatelly, when I use resourcestring in the application like MyButton.Caption:=xxZavrit (resourcestring), it is not correctly loaded from .DEU file (it is loaded from .exe instead). It was working fine in 10.3.3, but does not work in 10.4.2. Were there any changes regarding loading resourcestrings? I am using an old function which sets new resource file in place: function SetResourceHInstance(NewInstance: HModule): HModule; var CurModule: PLibModule; begin CurModule := LibModuleList; Result := 0; while CurModule <> nil do begin if CurModule.Instance = HInstance then begin if (CurModule.ResInstance <> CurModule.Instance) then FreeLibrary(CurModule.ResInstance); CurModule.ResInstance := NewInstance; Result := NewInstance; Exit; end; CurModule := CurModule.Next; end; end; Kind regards, Karel Share this post Link to post
Vandrovnik 214 Posted March 16, 2021 I am attaching test project, it contains prepared .DEU file but no .exe file. In PSC.pas in TPSCForm.FormShow, resourcestring is assigned to button's caption, which is not working for me. Test66.zip Share this post Link to post
Vandrovnik 214 Posted March 16, 2021 Hmm, when I use this, it seems to work again: LoadResStringFunc:=nil; Share this post Link to post
Anders Melander 1782 Posted March 16, 2021 I don't have time to investigate myself right now but can you see where LoadResStringFunc is assigned? I briefly scanned through the 10.4 source and I couldn't find anything there. Share this post Link to post
Vandrovnik 214 Posted March 16, 2021 1 minute ago, Anders Melander said: I don't have time to investigate myself right now but can you see where LoadResStringFunc is assigned? I briefly scanned through the 10.4 source and I couldn't find anything there. In System.SysUtils: procedure InitResStrings; begin InitializeCriticalSection(ResStringCritSect); AddModuleUnloadProc(ResStringModuleUnloadProc); LoadResStringFunc := @ResStringLoad; end; 1 Share this post Link to post
Anders Melander 1782 Posted March 16, 2021 Got it. Wow. Nice that they've added a hook but they really seem to have made that complicated. I'll look at it later. Share this post Link to post
Vandrovnik 214 Posted March 16, 2021 (edited) They have added ResStringCleanupCache to System.SysUtils. When I call it when loading another language module, it seems to work OK, too. { ResStringCleanupCache cleanups internal cache of loaded resource strings. Useful for applications dynamically changing resource DLL's. } procedure ResStringCleanupCache; "Documented" here: http://docwiki.embarcadero.com/Libraries/Sydney/en/API:System.SysUtils.ResStringCleanupCache Edited March 16, 2021 by Vandrovnik 1 Share this post Link to post
Stefan Glienke 2002 Posted March 16, 2021 Interesting, I did not notice that change until now - but that change is actually pretty nice! It avoids tons of identical string instances around the memory and loading them over and over again. But of course now we get the problem of cache invalidation hence this routine must be called when language got changed. Share this post Link to post
jbg 239 Posted March 16, 2021 Does it use a ring buffer (like IDE Fix Pack to make the compile dialog not spend the time on loading the same strings) or did they cache everything? (I don't have access to the new RTL's source code) Share this post Link to post
Stefan Glienke 2002 Posted March 16, 2021 They store the string reference along with the ident in a hashtable. Share this post Link to post
Anders Melander 1782 Posted March 16, 2021 1 hour ago, Stefan Glienke said: But of course now we get the problem of cache invalidation hence this routine must be called when language got changed. I haven't looked at it at all (still fighting with the damned PDB stuff) but maybe that could have been done automatically when a new resource module is loaded? That would have made the change backward compatible. Share this post Link to post
Stefan Glienke 2002 Posted March 16, 2021 (edited) 24 minutes ago, Anders Melander said: I haven't looked at it at all (still fighting with the damned PDB stuff) Don't let yourself get distracted - I am eagerly awaiting your results Well it seems there is some DLL unload callback registered that clears the cache for that module should it exist. But given I understood the initial problem properly the case when the resourcestring was initially from the exe itself is not handled by that mechanism. Edited March 16, 2021 by Stefan Glienke Share this post Link to post