Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Capturing a Pop Up Window using LifeSpanHandler and CefSharp

5.00/5 (16 votes)
26 Feb 2021CPOL2 min read 47.6K   1.7K  
How to capture the event open of a pop up, stop this event and open them wherever you wish
In this post, I'll show how to simply capture the open event of a pop-up, stop this event and open it wherever you wish.

Image 1

Introduction

CefSharp is a powerful embedding of Chrome that allows you to customize a browser to perform the most diverse tasks of the day-to-day. As an example, we can mention: read authentication cookies of the sites that must be sign in, intercept pop up loaded by sites, among other necessities.

In the lines below, I'll show you how to simply capture the open event of a pop-up, stop this event and open it wherever you wish.

To do this, we use the CefSharp interface, called IlifeSpanHandler.

ILifeSpanHandler has 4 events (OnBeforePopup, DoClose, OnBeforeClose and OnAfterCreated) and they are responsible for handling all pop up events. For this task, I'll use only the OnBeforePopup event.

Background

For design, I used:

  • Microsoft .NET Framework 4.6.1
  • CefSharp available in the NuGet Package
  • Windows Forms Application
  • Visual Studio 2017

Using the Code

This article is a complement for projects created with CefSharp.
If you don't know how to create a new project, click here to learn.

For using this interface:

  1. Create a class within the project Inheriting this interface:
    C#
    public class LifespanHandler: ILifeSpanHandler
  2. Create the event for receiving the url of the pop up:
    C#
    public event Action<string> popup_request;
  3. In the OnBeforePopup event, send the url to the event of item 2 and stop the popup that is opening:
    C#
    //get url popup
    this.popup_request?.Invoke(targetUrl);
    
    //stop open popup
    newBrowser = null;	
  4. Type the other events in the class. They have no source code.

When we forget to declare the signature of all interface events in the class, even if they are not used, this error "'popup_cefsharp.LifespanHandler' does not implement interface member 'CefSharp.ILifeSpanHandler.OnAfterCreated(CefSharp.IWebBrowser, CefSharp.IBrowser)'" happens.

Below is the complete code class:

C#
using CefSharp;
using CefSharp.WinForms;

namespace popup_cefsharp
{
    public class LifespanHandler: ILifeSpanHandler
    {
        //event that receive url popup
        public event Action<string> popup_request;

        bool ILifeSpanHandler.OnBeforePopup(IWebBrowser browserControl, 
             IBrowser browser, IFrame frame, string targetUrl, 
             string targetFrameName, WindowOpenDisposition targetDisposition, 
             bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, 
             IBrowserSettings browserSettings, ref bool noJavascriptAccess, 
             out IWebBrowser newBrowser)
        {
            //get url popup
            this.popup_request?.Invoke(targetUrl);

            //stop open popup
            newBrowser = null;
            return true;
        }

        bool ILifeSpanHandler.DoClose(IWebBrowser browserControl, IBrowser browser)
        { return false; }

        void ILifeSpanHandler.OnBeforeClose(IWebBrowser browserControl, IBrowser browser){}

        void ILifeSpanHandler.OnAfterCreated(IWebBrowser browserControl, IBrowser browser) {}
    }
}

Inside of the form, the class LifeSpanHandler is initialized and attributed in the variable of the browser.

C#
LifespanHandler life = new LifespanHandler();
chrome.LifeSpanHandler = life;

Create the event for url of the pop up captured:

C#
private void life_popup_request(string obj){}

Add the event in the variable of the class LifeSpanHandler:

C#
life.popup_request += life_popup_request;

Below is the complete code. This code was typed inside of the Windows Form.

C#
using CefSharp;
using CefSharp.WinForms;

namespace popup_cefsharp
{
    public partial class frm_main : Form
    {
        public frm_main()
        {
            InitializeComponent();
        }

        //variable 
        ChromiumWebBrowser chrome, chrome_popup;

        private void initialize_browser()
        {
            try
            {
                CefSettings settings = new CefSettings();
                Cef.Initialize(settings);

                //main browser
                chrome = new ChromiumWebBrowser(this.txt_url.Text.Trim());
                LifespanHandler life = new LifespanHandler();
                chrome.LifeSpanHandler = life;
                life.popup_request += life_popup_request;
                this.pan_container.Controls.Add(chrome);
                chrome.Dock = DockStyle.Fill;

                //second browser (popup browser)
                chrome_popup = new ChromiumWebBrowser("");
                this.pan_container_popup.Controls.Add(chrome_popup);
                chrome_popup.Dock = DockStyle.Fill;

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error in initializing the browser. Error: " + ex.Message);
            }
        }

        private void carregar_popup_new_browser(string url)
        {
            //open pop up in second browser
            chrome_popup.Load(url);
        }

        private void frm_main_FormClosing(object sender, FormClosingEventArgs e)
        {
            //close o object cef
            Cef.Shutdown();
            Application.Exit();
        }

        private void frm_main_Load(object sender, EventArgs e)
        {
            //initialize the browser
            this.initialize_browser();
        }

        private void life_popup_request(string obj)
        {
            //function for open pop up in a new browser
            this.carregar_popup_new_browser(obj);
        }
    }
}

Points of Interest

When you try to manipulate an object, other than the browser, in the life_popup_request event, the project generates an exception.

Image 2

For correct, use invoke delegate. Example:

C#
private void life_popup_request(string obj)
{
	chrome_popup = new ChromiumWebBrowser(url);
	this.Invoke((MethodInvoker)delegate()
	{
		this.pan_container_popup.Controls.Clear();
		this.pan_container_popup.Controls.Add(chrome_popup);
	});
	chrome_popup.Dock = DockStyle.Fill;
}

References

History

  • July 2017: Version 1 - Publication of the article
  • February 2021: Version 2 - Update of CefSharp to version 87, Visual Studio version 2017, .NET version 4.6.1

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)