Avalonia学习(十七)-CEF

今天开始继续Avalonia练习。

本节:CefNet

1.引入

CefNet.Avalonia.Eleven

2.项目引入

Program中加入

using Avalonia;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
using CefNet;
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;

namespace CefAvalonia
{
    internal sealed class Program
    {
        internal static CefAppImpl? app;
        private static DispatcherTimer? messagePump;
        private const int messagePumpDelay = 10;
        // Initialization code. Don't use any Avalonia, third-party APIs or any
        // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
        // yet and stuff might break.
        [STAThread]
        public static void Main(string[] args)
        {
            string cefPath = GetProjectPath(PlatformInfo.IsMacOS);
            bool externalMessagePump = args.Contains("--external-message-pump");

            if (PlatformInfo.IsMacOS)
            {
                externalMessagePump = true;
            }

            var settings = new CefSettings();
            settings.MultiThreadedMessageLoop = !externalMessagePump;
            settings.ExternalMessagePump = externalMessagePump;
            settings.NoSandbox = true;
            settings.WindowlessRenderingEnabled = true;
            settings.LocalesDirPath = Path.Combine(cefPath, PlatformInfo.IsMacOS ? "Resources" : "locales");
            settings.ResourcesDirPath = Path.Combine(cefPath, PlatformInfo.IsMacOS ? "Resources" : "");
            settings.LogSeverity = CefLogSeverity.Warning;
            settings.UncaughtExceptionStackSize = 8;

            App.FrameworkInitialized += App_FrameworkInitialized;
            App.FrameworkShutdown += App_FrameworkShutdown;

            app = new CefAppImpl();
            app.ScheduleMessagePumpWorkCallback = OnScheduleMessagePumpWork;
            app.Initialize(cefPath, settings);
            BuildAvaloniaApp()
                .StartWithClassicDesktopLifetime(args);
        }
        private static string GetProjectPath(bool isMacOS)
        {
            return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".cefnet", "Release", isMacOS ? Path.Combine("cefclient.app", "Contents", "Frameworks", "Chromium Embedded Framework.framework") : "");
        }
        private static void App_FrameworkInitialized(object? sender, EventArgs e)
        {
            if (CefNetApplication.Instance.UsesExternalMessageLoop)
            {
                messagePump = new DispatcherTimer(TimeSpan.FromMilliseconds(messagePumpDelay), DispatcherPriority.Normal, (s, e) =>
                {
                    CefApi.DoMessageLoopWork();
                    Dispatcher.UIThread.RunJobs();
                });
                messagePump.Start();
            }
        }
        private static void App_FrameworkShutdown(object? sender, EventArgs e)
        {
            messagePump?.Stop();
        }

        private static async void OnScheduleMessagePumpWork(long delayMs)
        {
            await Task.Delay((int)delayMs);
            Dispatcher.UIThread.Post(CefApi.DoMessageLoopWork);
        }

        // Avalonia configuration, don't remove; also used by visual designer.
        public static AppBuilder BuildAvaloniaApp()
            => AppBuilder.Configure()
                .UsePlatformDetect()
                .WithInterFont()
                .LogToTrace()
                .UseReactiveUI();
    }
}

APP中加入

using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using CefAvalonia.ViewModels;
using CefAvalonia.Views;
using System;

namespace CefAvalonia
{
    public partial class App : Application
    {
        public static event EventHandler? FrameworkInitialized;
        public static event EventHandler? FrameworkShutdown;
        public override void Initialize()
        {
            AvaloniaXamlLoader.Load(this);
        }

        public override void OnFrameworkInitializationCompleted()
        {
            if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
            {
                desktop.MainWindow = new MainWindow
                {
                    DataContext = new MainWindowViewModel(),
                };
            }

            base.OnFrameworkInitializationCompleted();
        }
    }
}

添加一个实现处理类

using CefNet;
using System;
using System.Runtime.InteropServices;

namespace CefAvalonia
{
    internal class CefAppImpl:CefNetApplication
    {
        protected override void OnBeforeCommandLineProcessing(string processType, CefCommandLine commandLine)
        {
            base.OnBeforeCommandLineProcessing(processType, commandLine);

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                commandLine.AppendSwitch("no-zygote");
                commandLine.AppendSwitch("no-sandbox");
            }
        }
        public Action ScheduleMessagePumpWorkCallback { get; set; }

        protected override void OnScheduleMessagePumpWork(long delayMs)
        {
            ScheduleMessagePumpWorkCallback(delayMs);
        }
    }
}

窗口后台

using Avalonia.Controls;
using CefNet.Avalonia;


namespace CefAvalonia.Views
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            WebView webview = new() { Focusable = true };
            Content = webview;

            webview.BrowserCreated += (s, e) => webview.Navigate("https://www.baidu.com");

            webview.DocumentTitleChanged += (s, e) => Title = e.Title;

            Closing += (s, e) => Program.app?.Shutdown();
        }
    }
}

最后,下载对应的库

CEF Automated Builds (spotifycdn.com)

运行效果

Avalonia学习(十七)-CEF_第1张图片

你可能感兴趣的:(学习,Avalonia)