CefSharp OnFullscreenModeChange 事件

CefSharp OnFullscreenModeChange event

我目前正在做一个 CefSharp 项目,我目前正在努力让 HTML5 视频在我的应用程序中全屏打开。

我已经在互联网上搜索了有关此类活动如何运作的答案,但我还不太了解。

我的 winforms 项目我已经走到这一步了:

public partial class Form1 : Form
{
    public ChromiumWebBrowser chromeBrowser;

    public Form1()
    {
        InitializeComponent();
        InitializeChromium();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

    }

    private void InitializeChromium()
    {
        CefSettings settings = new CefSettings();

        Cef.Initialize(settings);

        chromeBrowser = new ChromiumWebBrowser("http://youtube.com/");

        this.Controls.Add(chromeBrowser);
        chromeBrowser.Dock = DockStyle.Fill;
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        Cef.Shutdown();
    }
}

但每次我加载 YouTube 视频(或来自不同网站的视频)并点击 "Fullscreen" 按钮时,视频只会填满应用程序,而不是整个监视器屏幕。我猜这是因为我还没有从 IDisplayHandler 接口实现 OnFullscreenModeChange 方法。

在我寻找答案的过程中,我发现我可以使用一种方法重载 CefSharp 的 IDisplayHandler.OnFullscreenModeChange 方法,如下所示:

class DisplayHandler : IDisplayHandler
{
...
    void IDisplayHandler.OnFullscreenModeChange(IWebBrowser browserControl, IBrowser browser, bool fullscreen)
    {
        var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;

        chromiumWebBrowser.InvokeOnUiThreadIfRequired(() =>
        {
            if (fullscreen)
            {
                parent = chromiumWebBrowser.Parent;

                parent.Controls.Remove(chromiumWebBrowser);

                fullScreenForm = new Form();
                fullScreenForm.FormBorderStyle = FormBorderStyle.None;
                fullScreenForm.WindowState = FormWindowState.Maximized;

                fullScreenForm.Controls.Add(chromiumWebBrowser);

                fullScreenForm.ShowDialog(parent.FindForm());
            }
            else
            {
                fullScreenForm.Controls.Remove(chromiumWebBrowser);

                parent.Controls.Add(chromiumWebBrowser);

                fullScreenForm.Close();
                fullScreenForm.Dispose();
                fullScreenForm = null;
            }
        });
    }
...
}

所以我的问题是:如何将此重载添加到我的 ChromiumWebBrowser 控件中?

我已经使用 GeckoFX 网络浏览器而不是 CefSharp 解决了这个问题。

由于版本 45 中的全屏 API 存在问题,我选择使用版本 33 的 GeckoFX。

我的解决方案:

...
Xpcom.Initialize(@"..\..\xulrunner");

GeckoPreferences.User["full-screen-api.enabled"] = true;
GeckoPreferences.Default["full-screen-api.enabled"] = true;

geckoWebBrowser1.EnableDefaultFullscreen();

geckoWebBrowser1.Navigate(url);

geckoWebBrowser1.GetDocShellAttribute().SetIsBrowserInsideApp(0);
geckoWebBrowser1.GetDocShellAttribute().SetFullscreenAllowed(true);
...

请完整实现 IDisplayHandler 接口,如下所示示例代码:

using CefSharp;
using CefSharp.MinimalExample.WinForms.Controls;
using CefSharp.WinForms;
using System.Collections.Generic;
using System.Windows.Forms;
namespace FullScreen
{
    public class DisplayHandler : IDisplayHandler
    {
        private Control parent;
        private Form fullScreenForm;
        void IDisplayHandler.OnAddressChanged(IWebBrowser browserControl, AddressChangedEventArgs addressChangedArgs)
        {
        }
        void IDisplayHandler.OnTitleChanged(IWebBrowser browserControl, TitleChangedEventArgs titleChangedArgs)
        {
        }
        void IDisplayHandler.OnFaviconUrlChange(IWebBrowser browserControl, IBrowser browser, IList<string> urls)
        {
        }
        void IDisplayHandler.OnFullscreenModeChange(IWebBrowser browserControl, IBrowser browser, bool fullscreen)
        {
            var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;
            chromiumWebBrowser.InvokeOnUiThreadIfRequired(() =>
            {
                if (fullscreen)
                {
                    parent = chromiumWebBrowser.Parent;
                    parent.Controls.Remove(chromiumWebBrowser);
                    fullScreenForm = new Form();
                    fullScreenForm.FormBorderStyle = FormBorderStyle.None;
                    fullScreenForm.WindowState = FormWindowState.Maximized;
                    fullScreenForm.Controls.Add(chromiumWebBrowser);
                    fullScreenForm.ShowDialog(parent.FindForm());
                }
                else
                {
                    fullScreenForm.Controls.Remove(chromiumWebBrowser);
                    parent.Controls.Add(chromiumWebBrowser);
                    fullScreenForm.Close();
                    fullScreenForm.Dispose();
                    fullScreenForm = null;
                }
            });
        }
        bool IDisplayHandler.OnTooltipChanged(IWebBrowser browserControl, string text)
        {
            return false;
        }
        void IDisplayHandler.OnStatusMessage(IWebBrowser browserControl, StatusMessageEventArgs statusMessageArgs)
        {
        }
        bool IDisplayHandler.OnConsoleMessage(IWebBrowser browserControl, ConsoleMessageEventArgs consoleMessageArgs)
        {
            return false;
        }
    }
}

并在 WinForm 上使用 ChromiumWebBrowesr 分配一个新的 displayhandler,示例代码如下所示:

public ChromiumWebBrowser WebBrowser2;  
public Form1()
{
  InitializeComponent();
  DisplayHandler displayer = new DisplayHandler();
  WebBrowser2 = new ChromiumWebBrowser("https://www.google.com");
  WebBrowser2.Dock = DockStyle.Fill;
  this.Panel1.Controls.Add(this.WebBrowser2);
  this.WebBrowser2.DisplayHandler = displayer;         
}

我实施了 McMillian 的回答。工作得很好!

此外,如果你想在 CefSharp 中使用 Esc 键退出全屏,你需要实现 IKeyboardHandler。这是我的做法:

using CefSharp;
using CefSharp.WinForms;
using System.Windows.Forms;

namespace WatchNow
{
    public class KeyboardHandler : IKeyboardHandler
    {
        public bool OnKeyEvent(IWebBrowser chromiumWebBrowser, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
        {
            return false;
        }

        public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
        {
            var chromiumWebBrowser = (ChromiumWebBrowser)browserControl;

            if ((Keys)windowsKeyCode == Keys.Escape)
            {
                chromiumWebBrowser.Invoke((MethodInvoker)delegate 
                {
                    bool fullScreen = Screen.FromControl(chromiumWebBrowser).Bounds.Size == chromiumWebBrowser.Size;
                    if (fullScreen)
                    {
                        chromiumWebBrowser.DisplayHandler.OnFullscreenModeChange(browserControl, browser, false);
                    }
                });
            }

            return false;
        }
    }
}