55interface
66
77uses
8- FMX.Forms, PythonEngine, WrapDelphiClasses, WrapFmxTypes, WrapFmxControls;
8+ System.Classes, System.SysUtils, FMX.Forms,
9+ PythonEngine, WrapFmxTypes, WrapDelphiClasses, WrapFmxControls;
910
1011type
1112 TPyDelphiApplication = class (TPyDelphiComponent)
@@ -23,7 +24,9 @@ TPyDelphiCommonCustomForm = class(TPyDelphiFmxObject)
2324 private
2425 function GetDelphiObject : TCommonCustomForm;
2526 procedure SetDelphiObject (const Value : TCommonCustomForm);
27+ function HasFormRes (const AClass: TClass): boolean;
2628 public
29+ function CreateComponent (AOwner: TComponent): TComponent; override;
2730 // Class methods
2831 class function DelphiObjectClass : TClass; override;
2932 // Properties
@@ -85,10 +88,12 @@ TPyDelphiScreen = class(TPyDelphiComponent)
8588 property DelphiObject: TScreen read GetDelphiObject write SetDelphiObject;
8689 end ;
8790
91+ EInvalidFormClass = class (Exception);
92+
8893implementation
8994
9095uses
91- WrapDelphi;
96+ WrapDelphi, System.Types ;
9297
9398{ Register the wrappers, the globals and the constants }
9499type
@@ -153,6 +158,51 @@ procedure TPyDelphiApplication.SetDelphiObject(const Value: TApplication);
153158
154159{ TPyDelphiCommonCustomForm }
155160
161+ function TPyDelphiCommonCustomForm.CreateComponent (
162+ AOwner: TComponent): TComponent;
163+ type
164+ TCommonCustomFormClass = class of TCommonCustomForm;
165+ var
166+ LClass: TClass;
167+ LFormClass: TCommonCustomFormClass;
168+ LClassName: string;
169+ begin
170+ LFormClass := nil ;
171+ // get de default form class
172+ if DelphiObjectClass.InheritsFrom(TCommonCustomForm) then
173+ LFormClass := TCommonCustomFormClass(DelphiObjectClass);
174+
175+ // if we have a subclass of our Form wrapper, then check if we can find a
176+ // Delphi class that would have the same name as the Python class.
177+ // This would allow Python to instanciate an existing Delphi form class,
178+ // insted of only using a blank form.
179+ if (ob_type <> PythonType.TheTypePtr) then begin
180+ LClassName := string(ob_type.tp_name);
181+ LClass := GetClass(LClassName);
182+ if not Assigned(LClass) then
183+ LClass := GetClass(' T' + LClassName);
184+ if Assigned(LClass) and LClass.InheritsFrom(TCommonCustomForm) then
185+ LFormClass := TCommonCustomFormClass(LClass);
186+ end ;
187+
188+ if not Assigned(LFormClass) then
189+ raise EInvalidFormClass.CreateFmt(' Type %s is not a valid form class' , [
190+ DelphiObjectClass.ClassName]);
191+
192+ // if it's not a design form, so we create it as a non-resourced form,
193+ // using the non-resourced constructor.
194+ // if the Owner is TApplication, then we have to call its CreateForm method,
195+ // otherwise we won't have a mian form defined, as the main form is the first
196+ // created form. Of course, this is a concern only when Python controls all the
197+ // GUI and calls Apllication.Run by itself.
198+ if not HasFormRes(LFormClass) then
199+ Result := LFormClass.CreateNew(AOwner)
200+ else if (AOwner = Application) then
201+ Application.CreateForm(LFormClass, Result)
202+ else
203+ Result := LFormClass.Create(AOwner);
204+ end ;
205+
156206class function TPyDelphiCommonCustomForm.DelphiObjectClass : TClass;
157207begin
158208 Result := TCommonCustomForm;
@@ -163,6 +213,13 @@ function TPyDelphiCommonCustomForm.GetDelphiObject: TCommonCustomForm;
163213 Result := TCommonCustomForm(inherited DelphiObject);
164214end ;
165215
216+ function TPyDelphiCommonCustomForm.HasFormRes (const AClass: TClass): boolean;
217+ begin
218+ Result := FindResource(
219+ FindResourceHInstance(FindClassHInstance(AClass)),
220+ PChar(AClass.ClassName), PChar(RT_RCDATA)) <> 0 ;
221+ end ;
222+
166223procedure TPyDelphiCommonCustomForm.SetDelphiObject (
167224 const Value : TCommonCustomForm);
168225begin
0 commit comments