Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue when change parent of form #13

Closed
amancini opened this issue Jan 10, 2022 · 4 comments
Closed

Issue when change parent of form #13

amancini opened this issue Jan 10, 2022 · 4 comments

Comments

@amancini
Copy link

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

@salvadordf
Copy link
Owner

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 :

  • Set TWVBrowser.ParentWindow to a THandle value of any control in FormB.
  • Reparent FormA.
  • Set TWVBrowser.ParentWindow to the original TWVWindowParent.Handle in FormA.

I tested this method with a beta version of BriskBard and it works.

@amancini
Copy link
Author

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;

@roknjohn
Copy link

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?

@salvadordf
Copy link
Owner

salvadordf commented May 13, 2023

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants