Closed amancini closed 2 years ago
Try setting TWVBrowser.ParentWindow to a THandle of another control before reparenting the form.
Let's say you hay 2 forms : FormA and FormB.
If you want to reparent FormA and it has a browser then you have to follow these steps :
I tested this method with a beta version of BriskBard and it works.
at the moment i found this solution
maybe it can be useful to you
private
FRestoreHandle : Boolean;
aFormTmp : TForm;
procedure TFormBrowserEDGE.WndProc(var Message: TMessage);
begin
inherited;
if csDestroying in Self.ComponentState then Exit;
if (csRecreating in ControlState) then
ChangeParent
else if FRestoreHandle then
RestoreParent;
end;
procedure TFormBrowserEDGE.ChangeParent;
begin
if csDestroying in Self.ComponentState then Exit;
if ( WVBrowser1 <> nil) and (WVBrowser1.Initialized) then
begin
if not Assigned(aFormTmp) then
begin
aFormTmp := TForm.Create(nil);
end;
if aFormTmp.Handle <> WVBrowser1.ParentWindow then
WVBrowser1.ParentWindow := aFormTmp.Handle;
FRestoreHandle := True;
end;
end;
procedure TFormBrowserEDGE.RestoreParent;
begin
if csDestroying in Self.ComponentState then Exit;
if ( WVBrowser1 <> nil ) and FRestoreHandle and WVBrowser1.Initialized then
begin
if WVBrowser1.ParentWindow <> WVWindowParent1.Handle then
begin
WVBrowser1.ParentWindow := WVWindowParent1.Handle;
WVBrowser1.NotifyParentWindowPositionChanged;
WVWindowParent1.UpdateSize;
end;
FRestoreHandle := False;
if Assigned(aFormTmp) then
FreeAndNil(aFormTmp);
end;
end;
Procedure TFormBrowserEDGE.FormDestroy
begin
if Assigned(aFormTmp) then
FreeAndNil(aFormTmp);
end;
I think I understand the steps here. But let me pose another scenario:
The architecture of my application consists of a MainForm with a MainPanel, and many various ChildForms, each with a with ChildPanel. The ChildForms are always hidden, but at any point in time, one and only one of the ChildPanels is parented to the MainPanel, e.g. ChildFormA.ChildPanel.Parent := MainForm.MainPanel. As a child panel is switched out, their original parent is restored, e.g. ChildFormA.ChildPanel.Parent := ChildFormA; This gives a "midi" style effect and works great.
I also have another form, WVForm, with a WVPanel and on that, there is a WVBrowser and WVWindowParent.
Here's what I'm trying to do..
1) I want to "embed" the browser onto one of my child forms, say ChildFormB.ChildPanel. Keep in mind that this child panel gets parented to MainPanel, which can be swapped out with other child panels over time. I need to make sure that whenever ChildFormB.ChildPanel is set to MainPanel, the browser function is properly restored and resized.
2) I also want to allow a "popout" function, which will show a modeless WVForm , separate from my MainForm, to allow the user a full screen mode or to use it on another monitor. Here, the WVPanel would be reparented to WVForm, then shown in a different window, i.e. WVForm.Show;
What do I need to do to restore the WVBrowser function whenever ChildFormB.ChildPanel parent changes or if the WVForm is shown. Are there any special considerations that I need to be aware of here?
@roknjohn It should be possible to do what you describe. Follow the steps I gave previously and call NotifyParentWindowPositionChanged and UpdateSize when necessary as @amancini showed.
Alternatively, consider creating TFrames with embedded browsers at runtime as you can see in the TabbedBrowser demo.
Edit: I forgot to mention that moving browsers between monitors can be tricky because they can have different scale. I haven't tried this scenario.
Hello,
if you change the parent of the form that hosts the WVBroser, you go to create an inconsistency in the CoreWebView2Controller interface which is invisible and without parent.
i also tried re-assigning the parentWindow and resetting the visibility but it doesn't work.
I think it's a Microsoft bug, do you know any workarounds?
you can easily reproduce the problem through the tabbedBrowser demo unit that I modified and attached
best regards TabbedBrowserChange.zip