diff --git a/Source/fmx/WrapDelphiFmx.pas b/Source/fmx/WrapDelphiFmx.pas new file mode 100644 index 00000000..5bd1b3b5 --- /dev/null +++ b/Source/fmx/WrapDelphiFmx.pas @@ -0,0 +1,23 @@ +unit WrapDelphiFmx; + +interface + +implementation + +uses + WrapDelphiTypes, + WrapDelphiClasses, + WrapDelphiWindows, + WrapFireDac, + WrapFmxTypes, + WrapFmxStdCtrls, + WrapFmxActnList, + WrapFmxComCtrls, + WrapFmxDialogs, + WrapFmxForms, + WrapFmxShapes, + WrapFmxLayouts, + WrapFmxScrollBox, + WrapFmxGrids; + +end. diff --git a/Source/fmx/WrapFmxForms.pas b/Source/fmx/WrapFmxForms.pas index 646bfd03..9e463e61 100644 --- a/Source/fmx/WrapFmxForms.pas +++ b/Source/fmx/WrapFmxForms.pas @@ -5,7 +5,8 @@ interface uses - FMX.Forms, PythonEngine, WrapDelphiClasses, WrapFmxTypes, WrapFmxControls; + System.Classes, System.SysUtils, FMX.Forms, + PythonEngine, WrapFmxTypes, WrapDelphiClasses, WrapFmxControls; type TPyDelphiApplication = class(TPyDelphiComponent) @@ -23,7 +24,9 @@ TPyDelphiCommonCustomForm = class(TPyDelphiFmxObject) private function GetDelphiObject: TCommonCustomForm; procedure SetDelphiObject(const Value: TCommonCustomForm); + function HasFormRes(const AClass: TClass): boolean; public + function CreateComponent(AOwner: TComponent): TComponent; override; // Class methods class function DelphiObjectClass: TClass; override; // Properties @@ -85,10 +88,12 @@ TPyDelphiScreen = class(TPyDelphiComponent) property DelphiObject: TScreen read GetDelphiObject write SetDelphiObject; end; + EInvalidFormClass = class(Exception); + implementation uses - WrapDelphi; + WrapDelphi, System.Types; { Register the wrappers, the globals and the constants } type @@ -153,6 +158,51 @@ procedure TPyDelphiApplication.SetDelphiObject(const Value: TApplication); { TPyDelphiCommonCustomForm } +function TPyDelphiCommonCustomForm.CreateComponent( + AOwner: TComponent): TComponent; +type + TCommonCustomFormClass = class of TCommonCustomForm; +var + LClass: TClass; + LFormClass: TCommonCustomFormClass; + LClassName: string; +begin + LFormClass := nil; + //get de default form class + if DelphiObjectClass.InheritsFrom(TCommonCustomForm) then + LFormClass := TCommonCustomFormClass(DelphiObjectClass); + + //if we have a subclass of our Form wrapper, then check if we can find a + //Delphi class that would have the same name as the Python class. + //This would allow Python to instanciate an existing Delphi form class, + //insted of only using a blank form. + if (ob_type <> PythonType.TheTypePtr) then begin + LClassName := string(ob_type.tp_name); + LClass := GetClass(LClassName); + if not Assigned(LClass) then + LClass := GetClass('T' + LClassName); + if Assigned(LClass) and LClass.InheritsFrom(TCommonCustomForm) then + LFormClass := TCommonCustomFormClass(LClass); + end; + + if not Assigned(LFormClass) then + raise EInvalidFormClass.CreateFmt('Type %s is not a valid form class', [ + DelphiObjectClass.ClassName]); + + //if it's not a design form, so we create it as a non-resourced form, + //using the non-resourced constructor. + //if the Owner is TApplication, then we have to call its CreateForm method, + //otherwise we won't have a mian form defined, as the main form is the first + //created form. Of course, this is a concern only when Python controls all the + //GUI and calls Apllication.Run by itself. + if not HasFormRes(LFormClass) then + Result := LFormClass.CreateNew(AOwner) + else if (AOwner = Application) then + Application.CreateForm(LFormClass, Result) + else + Result := LFormClass.Create(AOwner); +end; + class function TPyDelphiCommonCustomForm.DelphiObjectClass: TClass; begin Result := TCommonCustomForm; @@ -163,6 +213,13 @@ function TPyDelphiCommonCustomForm.GetDelphiObject: TCommonCustomForm; Result := TCommonCustomForm(inherited DelphiObject); end; +function TPyDelphiCommonCustomForm.HasFormRes(const AClass: TClass): boolean; +begin + Result := FindResource( + FindResourceHInstance(FindClassHInstance(AClass)), + PChar(AClass.ClassName), PChar(RT_RCDATA)) <> 0; +end; + procedure TPyDelphiCommonCustomForm.SetDelphiObject( const Value: TCommonCustomForm); begin