type TForm1 = class(TForm) Layout1: TLayout; BtnCallsForm2InMyLayout: TButton; procedure BtnCallsForm2InMyLayoutClick(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.fmx}
uses Unit2;
procedure TForm1.BtnCallsForm2InMyLayoutClick(Sender: TObject); begin for var i: integer := 0 to (Layout1.ChildrenCount - 1) do begin if (Layout1.Children.Items[i] is TLayout) and (Layout1.Children.Items[i].Owner is TForm2) then Layout1.Children.Items[i].Owner.Free; end; // Form2 := TForm2.Create(Self); // self for usage "caFree" on Form2! // Layout1.AddObject(Form2.Layout1); end;
end.
---------- Form2 -- Called! type TForm2 = class(TForm) Label1: TLabel; BtnCloseMe: TButton; Layout1: TLayout; procedure BtnCloseMeClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form2: TForm2;
implementation
{$R *.fmx}
var MyText: string = '';
procedure TForm2.BtnCloseMeClick(Sender: TObject); begin Close; end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin Action := TCloseAction.caFree; // if created with "SELF" end;
procedure TForm2.FormCreate(Sender: TObject); begin MyText := 'Im Form2 at ' + DateTimeToStr(now); Label1.Text := MyText; end;
procedure TForm2.FormDestroy(Sender: TObject); begin ShowMessage('destroying form2...: ' + MyText); end;
end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
Thanks @emailx45 for your reply. But your solution is still to put the Layout component in Form2 on top of the component in Form1. I wish I could embed Form2 directly into the Layout component of Form1.
----------------------------------------------
-
Please let me talk about the business requirements behind me: I need to play video on the Layout of Form1, my plan is to call ffplay.exe to play the video file, then embed the ffplay's playback window into Form2, and then embed Form2 into Form1.Layout1.
The following line of code is the key code used to embed the ffplay window into Form2. Only TForm can been got the Windows handle in Firemonkey. Winapi.Windows.SetParent(ffPlayVideoWnd, Form2_Wnd);
----------------------------------------------
-
Unfortunatelly, you CAN NOT put another "Form" into a "Form". Because the forms particularity...
Like a "root-container" it is like a application-in-live. You notice this when it takes over the screen in a modal window.
It has behaviors of its own, which would conflict with other forms within it.
Therefore, a "FRAME" is accepted, mainly because it does not inherit all the characteristics of a form, such as modal properties.
Therefore, the most common and accepted practice is to place a form inside a container such as a "TPanel" or a "TLayout/FMX" (or similar), however, note that the form must be of the "NOT MODAL" type, so we use "SHOW" or it can be embedded as an object inside the container, as I showed above.
On the other hand, you can, through more advanced techniques, redirect the output of one application, and capture it on the screen of another application.
I'm not very familiar with the operating system's nuances, but in summary, this can be done by capturing the "Handle" of the window you want to control, and sending it to another control. As you are indicating in the line of the Windows API "SetParent()".
NOTE: in VCL, a "FRAME" have a "handle" property... in FMX, does not! TFrame FMX = TControl... TFrame VCL = TWinControl... normally, will have a "handle"
To try to help you I would have to look at your code and see how you are making the calls from the external application, etc...
But I can't say much without something to actually analyze.
my email: emailx45 @ yahoo com br
It is also worth analyzing, if FFplay provides access to its main library of functions (DLL/OS), above you could just "IMPORT" the calls from this library to Delphi, which would, in theory, be much easier to control.
For that, try using the following from Delphi: --> Components -> Import Components -> Type Library -> .... and find the DLL of said software installed on your system.
Remembering that on the target device of the software installation, you must have the same DLL/OS installed or copied to your software folder.
此帖子包含附件: 大小:15.7K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
AddOject(...) already does it! = Layout1FromForm2.Parent = Layout1FromForm1
uses Unit2;
procedure TForm1.BtnCallsForm2InMyLayoutClick(Sender: TObject); begin for var i: integer := 0 to (Layout1.ChildrenCount - 1) do begin if (Layout1.Children.Items[i] is TLayout) and (Layout1.Children.Items[i].Owner is TForm2) then begin ShowMessage( Layout1.Children.Items[i].Parent.Name); ShowMessage( Layout1.Children.Items[i].Parent.Parent.Name); // Layout1.Children.Items[i].Owner.Free; end; end; // Form2 := TForm2.Create(Self); // self for usage "caFree" on Form2! // Layout1.AddObject(Form2.Layout1); end;
end.
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
procedure TForm1.BtnCallsForm2InMyLayoutClick(Sender: TObject); begin (* for var i: integer := 0 to (Layout1.ChildrenCount - 1) do begin if (Layout1.Children.Items[i] is TLayout) and (Layout1.Children.Items[i].Owner is TForm2) then begin ShowMessage( Layout1.Children.Items[i].Parent.Name); ShowMessage( Layout1.Children.Items[i].Parent.Parent.Name); Layout1.Children.Items[i].Owner.Free; end; end; *) // Form2 := TForm2.Create(Self); // self for usage "caFree" on Form2! // Form2.Parent := Layout1; // Form2.Show; // show does not works like expected! Layout1.AddObject(Form2.Layout1); // Form2.Show; // show does not works like expected! end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
ONLY "TCONTROLS" can be "ParentED" to appears on root-object FMX.Controls.pas, line 2210: if AObject is TControl then
a form (TFmxObject) is a root-object, then, form-in-form does not works!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
In VCL it's more easy have the "external-app-window" into "Form1" because we have "HANDLEs" to identify each window: external-app and Form-handle in RAD.
you can use some MS Windows API functions: -- Winapi.ShellAPI.ShellExecuteEx() // run external-app -- Winapi.Windows.WaitForInputIdle() // wait external-app-works -- Winapi.Windows.FindWindow() // find external-app-window -- Winapi.Windows.SetParent() // define external-app-window parent -- Winapi.Windows.ShowWindow() // show the external-app-window -- Winapi.Windows.SetWindowPos() // to resize your new-window-app
NOTE: this technic does not works with all external-application, of course!
.
此帖子包含附件: 大小:53.4K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3