I'm new to C# and Win32 and I have a problem that might not be complicated to solve but I can't figure it out.
After migrating from CEFSharp to CEFSharp.HwndHost.
In my implementation of LifeSpanHandler.cs (take from https://github.com/cefsharp/CefSharp/blob/4608924d5a0c676857720917550674b88bd7b701/CefSharp.Wpf.Example/Handlers/ExperimentalLifespanHandler.cs), a popup window is created and the content of this window is a new ChromiunWebBrowser.
With CefSharp I only have my popup window with ChromiunWebBrowser as the content of this window. (One window)
But with CEFSharp.HwndHost it doesn't work anymore.
I now have 2 windows, the popup window and the ChromiunWebBrowser window. (Two windows)
When creating the popup window putting only the content and the new ChromiunWebBrowser does not work, I have 2 windows on the screen but no exceptions.
How to do ?
- Code: Select all
using CefSharp;
using CefSharp.Wpf;
using CefSharp.Wpf.HwndHost;
//using System;
using System.Windows;
using System.Windows.Interop;
namespace WindowsDesktopFCC.Browser.Handler
{
class LifeSpanHandler : ILifeSpanHandler
{
public bool DoClose(IWebBrowser browserControl, IBrowser browser)
{
return false;
}
public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser)
{
if (!browser.IsDisposed && browser.IsPopup)
{
var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
chromiumWebBrowser.Dispatcher.Invoke(() =>
{
var owner = System.Windows.Window.GetWindow(chromiumWebBrowser);
if (owner != null && owner.Content == browserControl)
{
owner.Show();
}
});
}
}
public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser)
{
if (!browser.IsDisposed && browser.IsPopup)
{
var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
chromiumWebBrowser.Dispatcher.Invoke(() =>
{
var owner = System.Windows.Window.GetWindow(chromiumWebBrowser);
if (owner != null && owner.Content == browserControl)
{
owner.Close();
}
});
}
}
public bool 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)
{
//Set newBrowser to null unless your attempting to host the popup in a new instance of ChromiumWebBrowser
//newBrowser = null;
//return false;
var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
ChromiumWebBrowser chromiumBrowser = null;
var windowX = (windowInfo.X == int.MinValue) ? double.NaN : windowInfo.X;
var windowY = (windowInfo.Y == int.MinValue) ? double.NaN : windowInfo.Y;
var windowWidth = (windowInfo.Width == int.MinValue) ? double.NaN : windowInfo.Width;
var windowHeight = (windowInfo.Height == int.MinValue) ? double.NaN : windowInfo.Height;
chromiumWebBrowser.Dispatcher.Invoke(() =>
{
var owner = System.Windows.Window.GetWindow(chromiumWebBrowser);
var downHandler = new DownloadHandler();
chromiumBrowser = new ChromiumWebBrowser
{
Address = targetUrl,
DialogHandler = new DialogHandler(),
DownloadHandler = downHandler,
MenuHandler = new MenuHandler(),
LifeSpanHandler = this //new PopupLifeSpanHandler()
};
chromiumBrowser.SetAsPopup();
//chromiumBrowser.LifeSpanHandler = this;
//chromiumBrowser.DownloadHandler = downHandler;
downHandler.OnBeforeDownloadFired += PopupDownloadHandler_OnBeforeDownloadFired;
downHandler.OnDownloadUpdatedFired += PopupDownloadHandler_OnDownloadUpdatedFired;
var popup = new System.Windows.Window
{
Left = windowX,
Top = windowY,
Width = windowWidth,
Height = windowHeight,
Content = chromiumBrowser,
Owner = owner,
Title = targetFrameName
};
downHandler.LinkedPopup = popup;
var windowInteropHelper = new WindowInteropHelper(popup);
//Create the handle Window handle (In WPF there's only one handle per window, not per control)
var handle = windowInteropHelper.EnsureHandle();
//The parentHandle value will be used to identify monitor info and to act as the parent window for dialogs,
//context menus, etc. If parentHandle is not provided then the main screen monitor will be used and some
//functionality that requires a parent window may not function correctly.
windowInfo.SetAsWindowless(handle);
popup.Closed += (o, e) =>
{
var w = o as System.Windows.Window;
if (w != null && w.Content is IWebBrowser)
{
(w.Content as IWebBrowser).Dispose();
w.Content = null;
}
};
});
newBrowser = chromiumBrowser;
return false;
}
private void PopupDownloadHandler_OnBeforeDownloadFired(object sender, DownloadItem e)
{
var downloadHandler = (DownloadHandler) sender;
if (downloadHandler.LinkedPopup != null)
{
downloadHandler.LinkedPopup.Dispatcher.Invoke(() => {
downloadHandler.LinkedPopup.Hide();
});
}
}
private void PopupDownloadHandler_OnDownloadUpdatedFired(object sender, DownloadItem e)
{
var downloadHandler = (DownloadHandler)sender;
if (e.IsCancelled || e.IsComplete || !e.IsValid)
{
downloadHandler.LinkedPopup.Dispatcher.Invoke(() => {
downloadHandler.LinkedPopup.Close();
});
}
}
}
}