/// <inheritdoc/>
        /// <remarks>
        /// NOTE: DevTools popups DO NOT trigger OnBeforePopup.
        /// </remarks>
        protected override bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            newBrowser = null;

            //No action so we'll go with the default behaviour.
            if (onPopupCreated == null)
            {
                return(false);
            }

            var webBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

            //We need to execute sync here so IWindowInfo.SetAsChild is called before we return false;
            webBrowser.InvokeSyncOnUiThreadIfRequired(new Action(() =>
            {
                var control = new ChromiumHostControl
                {
                    Dock = DockStyle.Fill
                };
                control.CreateControl();

                onPopupCreated?.Invoke(control, targetUrl);

                var rect = control.ClientRectangle;

                windowInfo.SetAsChild(control.Handle, rect.Left, rect.Top, rect.Right, rect.Bottom);
            }));

            return(false);
        }
        /// <inheritdoc/>
        protected override bool DoClose(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                //We don't have a parent control so we allow the default behaviour, required to close
                //default popups e.g. DevTools
                if (control == null)
                {
                    return(false);
                }

                //If the main browser is disposed or the handle has been released then we don't
                //need to remove the popup (likely removed from menu)
                if (!control.IsDisposed && control.IsHandleCreated)
                {
                    //We need to invoke in a sync fashion so our IBrowser object is still in scope
                    //Calling in an async fashion leads to the IBrowser being disposed before we
                    //can access it.
                    control.InvokeSyncOnUiThreadIfRequired(new Action(() =>
                    {
                        onPopupDestroyed?.Invoke(control, browser);
                    }));
                }
            }

            //No WM_CLOSE message will be sent, manually handle closing
            return(true);
        }
        /// <summary>
        /// Open DevTools using your own Control as the parent. If inspectElementAtX and/or inspectElementAtY are specified then
        /// the element at the specified (x,y) location will be inspected.
        /// For resize/moving to work correctly you will need to use the <see cref="CefSharp.WinForms.Handler.LifeSpanHandler"/> implementation.
        /// (Set <see cref="ChromiumWebBrowser.LifeSpanHandler"/> to an instance of <see cref="CefSharp.WinForms.Handler.LifeSpanHandler"/>)
        /// </summary>
        /// <param name="chromiumWebBrowser"><see cref="ChromiumWebBrowser"/> instance</param>
        /// <param name="addParentControl">
        /// Action that is Invoked when the DevTools Host Control has been created and needs to be added to it's parent.
        /// It's important the control is added to it's intended parent at this point so the <see cref="Control.ClientRectangle"/>
        /// can be calculated to set the initial display size.</param>
        /// <param name="inspectElementAtX">x coordinate (used for inspectElement)</param>
        /// <param name="inspectElementAtY">y coordinate (used for inspectElement)</param>
        /// <returns>Returns the <see cref="Control"/> that hosts the DevTools instance if successful, otherwise returns null on error.</returns>
        public static Control ShowDevToolsDocked(this IChromiumWebBrowserBase chromiumWebBrowser, Action <ChromiumHostControl> addParentControl, string controlName = nameof(ChromiumHostControl) + "DevTools", DockStyle dockStyle = DockStyle.Fill, int inspectElementAtX = 0, int inspectElementAtY = 0)
        {
            if (chromiumWebBrowser.IsDisposed || addParentControl == null)
            {
                return(null);
            }

            var host = chromiumWebBrowser.GetBrowserHost();

            if (host == null)
            {
                return(null);
            }

            var control = new ChromiumHostControl()
            {
                Name = controlName,
                Dock = dockStyle
            };

            control.CreateControl();

            //It's now time for the user to add the control to it's parent
            addParentControl(control);

            //Devtools will be a child of the ChromiumHostControl
            var rect         = control.ClientRectangle;
            var windowInfo   = new WindowInfo();
            var windowBounds = new CefSharp.Structs.Rect(rect.X, rect.Y, rect.Width, rect.Height);

            windowInfo.SetAsChild(control.Handle, windowBounds);
            host.ShowDevTools(windowInfo, inspectElementAtX, inspectElementAtY);

            return(control);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ParentFormMessageInterceptor"/> class.
 /// </summary>
 /// <param name="browser">The browser.</param>
 public ParentFormMessageInterceptor(ChromiumHostControl browser)
 {
     Browser = browser;
     // Get notified if our browser window parent changes:
     Browser.ParentChanged += ParentParentChanged;
     // Find the browser form to subclass to monitor WM_MOVE/WM_MOVING
     RefindParentForm();
 }
Exemple #5
0
        /// <inheritdoc />
        protected override void OnLoadingStateChange(IWebBrowser chromiumWebBrowser, LoadingStateChangedEventArgs args)
        {
            var browser = args.Browser;

            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                control?.OnLoadingStateChange(args);
            }

            base.OnLoadingStateChange(chromiumWebBrowser, args);
        }
Exemple #6
0
        /// <inheritdoc />
        protected override void OnFrameLoadStart(IWebBrowser chromiumWebBrowser, FrameLoadStartEventArgs args)
        {
            var browser = args.Browser;

            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                control?.OnFrameLoadStart(args);
            }

            base.OnFrameLoadStart(chromiumWebBrowser, args);
        }
Exemple #7
0
        /// <inheritdoc />
        protected override void OnStatusMessage(IWebBrowser chromiumWebBrowser, StatusMessageEventArgs args)
        {
            var browser = args.Browser;

            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                control?.OnStatusMessage(args);
            }

            base.OnStatusMessage(chromiumWebBrowser, args);
        }
Exemple #8
0
        /// <inheritdoc />
        protected override bool OnConsoleMessage(IWebBrowser chromiumWebBrowser, ConsoleMessageEventArgs args)
        {
            var browser = args.Browser;

            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                control?.OnConsoleMessage(args);
            }

            return(base.OnConsoleMessage(chromiumWebBrowser, args));
        }
Exemple #9
0
        /// <inheritdoc />
        protected override void OnAddressChanged(IWebBrowser chromiumWebBrowser, AddressChangedEventArgs args)
        {
            var browser = args.Browser;

            if (browser.IsPopup)
            {
                var control = ChromiumHostControl.FromBrowser(browser);

                control?.OnAddressChanged(args);
            }

            base.OnAddressChanged(chromiumWebBrowser, args);
        }
Exemple #10
0
        public void RemoveTab(ChromiumHostControl ctrl)
        {
            if (!ctrl.IsDisposed)
            {
                var tabPage = ctrl.GetParentOfType <TabPage>();

                if (tabPage == null)
                {
                    throw new Exception("Unable to find parent TabPage");
                }

                browserTabControl.TabPages.Remove(tabPage);
            }
        }
        public BrowserTabUserControl(ChromiumHostControl chromiumHostControl)
        {
            InitializeComponent();

            Browser = chromiumHostControl;

            browserPanel.Controls.Add(chromiumHostControl);

            chromiumHostControl.LoadingStateChanged         += OnBrowserLoadingStateChanged;
            chromiumHostControl.ConsoleMessage              += OnBrowserConsoleMessage;
            chromiumHostControl.TitleChanged                += OnBrowserTitleChanged;
            chromiumHostControl.AddressChanged              += OnBrowserAddressChanged;
            chromiumHostControl.StatusMessage               += OnBrowserStatusMessage;
            chromiumHostControl.IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
            chromiumHostControl.LoadError += OnLoadError;
        }
Exemple #12
0
        /// <inheritdoc/>
        protected override void OnAfterCreated(IWebBrowser chromiumWebBrowser, IBrowser browser)
        {
            if (browser.IsPopup)
            {
                //WinForms will kindly lookup the child control from it's handle
                //If no parentControl then likely it's a native popup created by CEF
                //(Devtools by default will open as a popup, at this point the Url hasn't been set, so
                // we're going with this assumption as it fits the use case currently)
                var control = ChromiumHostControl.FromBrowser(browser);

                //If control is null then we'll treat as a native popup (do nothing)
                //If control is disposed there's nothing for us to do either.
                if (control != null && !control.IsDisposed)
                {
                    control.BrowserHwnd = browser.GetHost().GetWindowHandle();

                    control.InvokeOnUiThreadIfRequired(() =>
                    {
                        var interceptor     = new ParentFormMessageInterceptor(control);
                        interceptor.Moving += (sender, args) =>
                        {
                            if (!browser.IsDisposed)
                            {
                                browser?.GetHost()?.NotifyMoveOrResizeStarted();
                            }
                        };

                        popupParentFormMessageInterceptors.Add(browser.Identifier, interceptor);
                    });

                    control.BrowserCore = browser;
                    control.RaiseIsBrowserInitializedChangedEvent();
                }

                onPopupBrowserCreated?.Invoke(control, browser);
            }
        }
Exemple #13
0
        /// <summary>
        /// Used to add a Popup browser as a Tab
        /// </summary>
        /// <param name="browserHostControl"></param>
        public void AddTab(ChromiumHostControl browserHostControl, string url)
        {
            browserTabControl.SuspendLayout();

            var browser = new BrowserTabUserControl(browserHostControl)
            {
                Dock   = DockStyle.Fill,
                Bounds = browserTabControl.Bounds
            };

            var tabPage = new TabPage(url)
            {
                Dock = DockStyle.Fill
            };

            tabPage.Controls.Add(browser);

            browserTabControl.TabPages.Add(tabPage);

            //Make newly created tab active
            browserTabControl.SelectedTab = tabPage;

            browserTabControl.ResumeLayout(true);
        }
Exemple #14
0
        /// <inheritdoc/>
        /// <remarks>
        /// NOTE: DevTools popups DO NOT trigger OnBeforePopup.
        /// </remarks>
        protected override bool OnBeforePopup(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
        {
            newBrowser = null;

            PopupCreation userAction = onBeforePopupCreated?.Invoke(chromiumWebBrowser, browser, frame, targetUrl, targetFrameName, targetDisposition, userGesture, browserSettings) ?? PopupCreation.Continue;

            //Cancel popup creation
            if (userAction == PopupCreation.Cancel)
            {
                return(true);
            }

            if (userAction == PopupCreation.ContinueWithJavascriptDisabled)
            {
                noJavascriptAccess = true;
            }

            //No action so we'll go with the default behaviour.
            if (onPopupCreated == null)
            {
                return(false);
            }

            var webBrowser = (ChromiumWebBrowser)chromiumWebBrowser;

            //Load and Display Handlers are used to trigger the relevant events.
            //If they are already assigned we'll leave the user preference in place
            if (webBrowser.LoadHandler == null)
            {
                webBrowser.LoadHandler = new LoadHandler();
            }
            if (webBrowser.DisplayHandler == null)
            {
                webBrowser.DisplayHandler = new DisplayHandler();
            }

            //We need to execute sync here so IWindowInfo.SetAsChild is called before we return false;
            webBrowser.InvokeSyncOnUiThreadIfRequired(new Action(() =>
            {
                ChromiumHostControl control = chromiumHostControlCreatedDelegate?.Invoke();

                if (control == null)
                {
                    control = new ChromiumHostControl
                    {
                        Dock = DockStyle.Fill
                    };
                }
                control.CreateControl();

                onPopupCreated?.Invoke(control, targetUrl);

                var rect = control.ClientRectangle;

                var windowBounds = new CefSharp.Structs.Rect(rect.X, rect.Y, rect.Width, rect.Height);

                windowInfo.SetAsChild(control.Handle, windowBounds);
            }));

            return(false);
        }