Jump to content
Vandrovnik

Loading of translated resourcestrings broken in 10.4.2

Recommended Posts

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

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

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
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;

 

  • Thanks 1

Share this post


Link to post

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

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 by Vandrovnik
  • Like 1

Share this post


Link to post

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

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
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
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 :classic_cool:

 

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 by Stefan Glienke

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×