C++ Builder 10.4, FMX : Multi-device form TAB problem, if derivation from another multi-device form unit

  

I made another post which is a simplified reproduction of the problem, without dealing with derivation/inheritance: C++ Builder 10.4, FMX: Mult-device form TabOrder problem

Old issue:
The Tab functionality to switch between control fields seems to be not working with C++ Builder 10.4 (with patch 1, 2 and 3), if a form is created using a master-form with only a TLayout component. The TLayout of the master-form is used as a parent for the top-form-component of the new form.
Steps to reproduce this issue:

Create a new Multi-Device Application, Blank Application.
For the generated Unit1, just drop a TLayout from the Palette to the Designer and resize this to match the Form’s size (480×640) from position (0, 0), and set the TabOrder of this Layout to 0.
For the project, “Add New / Multi-Device Form / HD Form” to create a Unit2.cpp in the project.
Drop a TLayout component on the new Form2, rename it to Layout2, resize it to fill almost all of the space, and change its TabOrder to 0.
Drop 2 TEdit components on Form2 (Edit1 and Edit2), set their default text to "edit1" and "edit2", and change TabOrder to 0 for Edit1 and 1 for Edit2.
Change Unit2.h to include Unit1.h and derive TForm2 from TForm1 instead of TForm:

//—————————————————————————
#ifndef Unit2H
#define Unit2H
//—————————————————————————
#include <System.Classes.hpp>
#include <FMX.Controls.hpp>
#include <FMX.Forms.hpp>
#include <FMX.Controls.Presentation.hpp>
#include <FMX.Edit.hpp>
#include <FMX.Layouts.hpp>
#include <FMX.Types.hpp>

#include "Unit1.h"

//—————————————————————————
class TForm2 : public TForm1
{
__published: // IDE-managed Components
TLayout *Layout2;
TEdit *Edit1;
TEdit *Edit2;
private: // User declarations
public: // User declarations
__fastcall TForm2(TComponent* Owner);
};
//—————————————————————————
extern PACKAGE TForm2 *Form2;
//—————————————————————————
#endif

Change Unit2.cpp to derive TForm2 from TForm1, and set Layout1 as the parent of Layout2:

//—————————————————————————
#include <fmx.h>
#pragma hdrstop

#include "Unit2.h"
//—————————————————————————
#pragma package(smart_init)
#pragma resource "*.fmx"
TForm2 *Form2;
//—————————————————————————
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm1(Owner)
{
Layout2->Parent = Layout1;
}
//—————————————————————————

Change Project1.cpp to auto-create only TForm2 (just by commenting out 1 line):

//—————————————————————————
#include <fmx.h>
#ifdef _WIN32
#include <tchar.h>
#endif
#pragma hdrstop
#include <System.StartUpCopy.hpp>
//—————————————————————————
USEFORM("Unit1.cpp", Form1);
USEFORM("Unit2.cpp", Form2);
//—————————————————————————
extern "C" int FMXmain()
{
try
{
Application->Initialize();
//Application->CreateForm(__classid(TForm1), &Form1);
Application->CreateForm(__classid(TForm2), &Form2);
Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (…)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//—————————————————————————

Start the project with “Run” (F9), and see that Tab is not working to switch between the 2 edit fields.

Now, if the class derivation of Form2 to Form1 is undone, Tab is working correctly.
It doesn’t matter which compiler is used (‘classic’ Borland, or CLang).
The PC used is a newly created virtual Windows10 Pro v1903 running on Intel Xeon CPU E5-2620 v4 @ 2.10Ghz 8GB

Reply on comment of Remy Lebeau, at 2020-10-08T09:32:00Z:
Thanx Remy, for improving the item with “Tab” (better to address the TAB-key), and your answer.
I discovered a way to add a new item into the project which is ment for adding a “multi-device form” with inheritance of another form. This can be done with “Add New/Other…”. Then, a “New Items”-dialog appears with a tree structure. If “C++ Builder/Inheritable Items” is selected all current existing forms are visible and 1 can be selected to “Inherit”. The effect seems to be exactly the same for the changes in “Unit2.cpp” and “Unit2.h” I did manually in my example reproduction. And, indeed, like you stated about the “inherited”-keyword in “Unit2.fmx”: This is generated as the first word in “Unit2.fmx” file, instead “object”. The effect is, the form components of the inherired forms are immediately visible in the IDE on the “Design”-tab of the unit. This last effect is not what I prefer. It is OK that the inherited form components are available and could be used, like all inherited properties and methods of the inherited form, but I like to design a new form which can be used instead the design of the inherited form. So, I don’t like to use the keyword “inherited” in the “.fmx”-file. Essential is that I can make a form component of the inherited unit, the “parent” of a form component of the new unit. That works in essence for both cases, by changing a new multi-device form manually (like described), or adding a new multi-device form with “Add new/Other/C++ Builder/Inheritable Items/Form1” (resulting in “inherited” in the “.fmx”-file).
But, the problem described in my posting above about the Tab key is not functioning remains. It is also actual if the multi-device form is added with “Add new/Other/C++ Builder/Inheritable Items/Form1”. It looks like the new Embarcadero C++ Builder version 10.4 looses Tab functionallity if the parent of a form component (“TLayout” in my case) is set to another form component programmaticly by setting the “Parent”-property.
Note: In the help (RAD Studio Topics), at “FMX.Layouts.TLayout Properties”, “Parent” is listed as “public”-property and description “Specifies the parent component of this FMX object.”.
I face this problem while upgrading a complex commercial software product from C++ Builder 10.2 (Tokyo) to version 10.4 (Sydney). In Tokyo, with the same code, the “Tab” functionallity keeps working after setting the “Parent” a “TControl” object (like an object of “FMX.TabControl.TTabControl”) to another “TControl” object (like an object of “FMX.Layouts.TLayout”). Users who intensively use a certain form with a lot of edit fields, than have to click with the mouse to get from one field to another instead using “Tab” which can be very anoying. Isn’t this issue just a BUG of the new version of Embarcadero C++ Builder?

Comments are closed.