Thus far LoadNewResourceModule is translated and works properly. I've tested it by calling it before Application->Initialize. I am able to load a different language.
However, ReinitializeForms does not work. Upon calling it (affter LowNewResourceModule) form locaiton changes to 0, 0 but language is not loaded, and remains same... Something is wrong.
Help me translate it. Pascal code is included in coments.
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <SysInit.hpp>
#include <Vcl.Forms.hpp>
#include <ustring.h>
#include <windows.h>
#include <sysvari.h>
#pragma hdrstop
#include "reinit.h"
//#include "_TLog.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
class TAsInheritedReader : public TReader
{
public:
void __fastcall ReadPrefix(TFilerFlags &_flags, int &_aChildPos);
inline __fastcall TAsInheritedReader(TStream* Stream, int BufSize) : TReader(Stream, BufSize) {}
};
//---------------------------------------------------------------------------
void __fastcall TAsInheritedReader::ReadPrefix(TFilerFlags &_flags, int &_aChildPos)
{
TReader::ReadPrefix(_flags, _aChildPos);
_flags = _flags << ffInherited;
}
// GOOD
//---------------------------------------------------------------------------
int __fastcall SetResourceHInstance(int _newInstance)
{
PLibModule CurModule = LibModuleList;
while(CurModule != NULL) {
if (reinterpret_cast<void*>(CurModule->Instance) == HInstance) {
if (CurModule->ResInstance != CurModule->Instance) {
FreeLibrary(reinterpret_cast<HMODULE>(CurModule->ResInstance));
CurModule->ResInstance = _newInstance;
return _newInstance;
}
CurModule = CurModule->Next;
}
}
return 0;
}
// GOOD
//---------------------------------------------------------------------------
int __fastcall LoadNewResourceModule(LCID locale)
{
wchar_t FileName[260];
PChar P;
wchar_t LocaleName[4];
int NewInst = 0;
GetModuleFileNameW(HInstance, FileName, sizeof(FileName));
GetLocaleInfoW(locale, LOCALE_SABBREVLANGNAME, LocaleName, sizeof(LocaleName));
P = PChar(&FileName) + lstrlen(FileName);
while((*P != L'.') && (P != reinterpret_cast<PChar>(&FileName))) {
--P;
}
if (P != reinterpret_cast<PChar>(&FileName)) {
++P;
if (LocaleName[0] != L'\0') {
NewInst = reinterpret_cast<int>(LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE));
if (NewInst == 0) {
LocaleName[2] = L'\0';
lstrcpy(P, LocaleName);
NewInst = reinterpret_cast<int>(LoadLibraryEx(FileName, 0, LOAD_LIBRARY_AS_DATAFILE));
}
}
}
if (NewInst != 0) {
return SetResourceHInstance(NewInst);
}
return 0;
}
/*
function InternalReloadComponentRes(const ResName: string; HInst: THandle; var Instance: TComponent): Boolean;
var
HRsrc: THandle;
ResStream: TResourceStream;
AsInheritedReader: TAsInheritedReader;
begin { avoid possible EResNotFound exception }
if HInst = 0 then HInst := HInstance;
HRsrc := FindResource(HInst, PChar(ResName), RT_RCDATA);
Result := HRsrc <> 0;
if not Result then Exit;
ResStream := TResourceStream.Create(HInst, ResName, RT_RCDATA);
try
AsInheritedReader := TAsInheritedReader.Create(ResStream, 4096);
try
Instance := AsInheritedReader.ReadRootComponent(Instance);
finally
AsInheritedReader.Free;
end;
finally
ResStream.Free;
end;
Result := True;
end; */
//---------------------------------------------------------------------------
bool __fastcall InternalReloadComponentRes(String ResName, std::uintptr_t HInst, TComponent* Instance)
{
std::uintptr_t HRsrc = 0;
TResourceStream* ResStream = NULL;
TAsInheritedReader* AsInheritedReader = NULL;
if (HInst == 0) {
HInst = (std::uintptr_t)HInstance;
}
HRsrc = (std::uintptr_t)FindResourceW((HMODULE)HInst, (LPCWSTR)ResName.c_str(), (LPCWSTR)RT_RCDATA);
if (HRsrc == 0) {
return false;
}
try {
ResStream = new TResourceStream(HInst, ResName, (System::WideChar*)RT_RCDATA);
try {
AsInheritedReader = new TAsInheritedReader(ResStream, 4096);
Instance = AsInheritedReader->ReadRootComponent(Instance);
} __finally {
delete AsInheritedReader;
}
} __finally {
delete ResStream;
}
return true;
}
//---------------------------------------------------------------------------
bool __fastcall ReloadInheritedComponent(TComponent* Instance, TClass RootAncestor)
{
std::function<bool(TClass)> InitComponent = [&](TClass ClassType) -> bool
{
// This reaises questions, in particular ClassType = TComponent::ClassInfo() original delphi code has it differently
// please recheck
if ( (ClassType == TComponent::ClassInfo()) || (ClassType == RootAncestor) ) {
return false;
}
bool rvl = InitComponent(ClassType->ClassParent());
if (InternalReloadComponentRes( ClassType->ClassName(),
FindResourceHInstance(FindClassHInstance(ClassType)),
Instance ) == false)
{
return false;
}
return rvl;
};
return InitComponent(Instance->ClassType());
}
/*
function ReloadInheritedComponent(Instance: TComponent; RootAncestor: TClass): Boolean;
function InitComponent(ClassType: TClass): Boolean;
begin
Result := False;
if (ClassType = TComponent) or (ClassType = RootAncestor) then Exit;
Result := InitComponent(ClassType.ClassParent);
Result := InternalReloadComponentRes(ClassType.ClassName, FindResourceHInstance(
FindClassHInstance(ClassType)), Instance) or Result;
end;
begin
Result := InitComponent(Instance.ClassType);
end;
*/
//---------------------------------------------------------------------------
void __fastcall ReinitializeForms()
{
for(int i=0; i<Screen->FormCount; i++) {
// This raises questions as well, original delphi code, bellow has different second parameter
ReloadInheritedComponent(Screen->Forms[i], Screen->Forms[i]->ClassParent());
}
}
/*
procedure ReinitializeForms;
var
Count: Integer;
I: Integer;
Form: TForm;
begin
Count := Screen.FormCount;
for I := 0 to Count-1 do
begin
Form := Screen.Forms[I];
ReloadInheritedComponent(Form, TForm);
end;
end;
*/