ChromiumWebBrowser 简单封装
public partial class CustomChromiumWebBrowser : ChromiumWebBrowser
{
public event Action LoadOver;
public event Action<ConsoleMessageEventArgs> LoadMessage;
public event Func<object> ResolveObject;
public CustomChromiumWebBrowser(string url) : base(url)
{
// 可以不要这个事件
IsBrowserInitializedChanged += OnIsBrowserInitializedChanged;
Dock = DockStyle.Fill;
// 跨域
BrowserSettings.ApplicationCache = CefState.Enabled;
BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
MenuHandler = new MenuHandlerEx();
KeyboardHandler = new CEFKeyBoardHander();
// 页面加载完毕后
ConsoleMessage += (s, eve) =>
{
try
{
// 等待页面 Console.log("ready") 自带的加载完毕事件 没办法等网页加载完之后再执行
if (eve.Message == "ready")
{
LoadOver?.Invoke();
}
LoadMessage?.Invoke(eve);
}
catch (Exception e)
{
Log.ForContext<CustomChromiumWebBrowser>().Error(e,"ready");
}
};
// 注入类到页面
JavascriptObjectRepository.ResolveObject += (s, eve) =>
{
var repo = eve.ObjectRepository;
if (eve.ObjectName == "cs")
{
object oj = ResolveObject?.Invoke();
if (oj != null)
{
repo.Register("cs", oj, isAsync: true, options: BindingOptions.DefaultBinder);
}
}
};
}
#region Help
private void OnIsBrowserInitializedChanged(object sender, EventArgs e)
{
var b = ((ChromiumWebBrowser)sender);
//浏览器初始化更改 浏览器获取焦点
this.InvokeOnUiThreadIfRequired(() => b.Focus());
}
/// <summary>
/// 监听按键
/// </summary>
public class CEFKeyBoardHander : IKeyboardHandler
{
public bool OnKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey)
{
if (type == KeyType.KeyUp && Enum.IsDefined(typeof(Keys), windowsKeyCode))
{
var key = (Keys)windowsKeyCode;
switch (key)
{
case Keys.F12:
browser.ShowDevTools();
break;
case Keys.F5:
if (modifiers == CefEventFlags.ControlDown)
{
//ctrl+f5
browser.Reload(true);
}
else
{
//f5
browser.Reload();
}
break;
}
}
return false;
}
public bool OnPreKeyEvent(IWebBrowser browserControl, IBrowser browser, KeyType type, int windowsKeyCode, int nativeKeyCode, CefEventFlags modifiers, bool isSystemKey, ref bool isKeyboardShortcut)
{
return false;
}
}
/// <summary>
/// 禁用右键菜单
/// </summary>
public class MenuHandlerEx : IContextMenuHandler
{
public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model)
{
model.Clear();
}
public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, CefMenuCommand commandId, CefEventFlags eventFlags)
{
return false;
}
public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
{
}
public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame, IContextMenuParams parameters, IMenuModel model, IRunContextMenuCallback callback)
{
return false;
}
}
#endregion Help
}
上面 InvokeOnUiThreadIfRequired 方法
public static class ControlExtensions
{
/// <summary>
/// Executes the Action asynchronously on the UI thread, does not block execution on the calling thread.
/// </summary>
/// <param name="control">the control for which the update is required</param>
/// <param name="action">action to be performed on the control</param>
public static void InvokeOnUiThreadIfRequired(this Control control, Action action)
{
//If you are planning on using a similar function in your own code then please be sure to
//have a quick read over https://stackoverflow.com/questions/1874728/avoid-calling-invoke-when-the-control-is-disposed
//No action
if (control.Disposing || control.IsDisposed || !control.IsHandleCreated)
{
return;
}
if (control.InvokeRequired)
{
control.BeginInvoke(action);
}
else
{
action.Invoke();
}
}
}
简单使用
public partial class HtmlForm : Form
{
private CustomChromiumWebBrowser _chromiumWebBrowser;
public HtmlForm()
{
InitializeComponent();
}
protected override void Init()
{
_chromiumWebBrowser = new CustomChromiumWebBrowser ("your url");
// 加载完毕后调用
_chromiumWebBrowser.LoadOver += _chromiumWebBrowser_LoadOver;
// 注入对象
_chromiumWebBrowser.ResolveObject += ChromiumWebBrowser_ResolveObject;
// 添加到容器
panelControl.Controls.Add(_chromiumWebBrowser);
// 页面中的刷新按钮
btnRefresh.ItemClick += BtnRefresh_ItemClick;
}
/// <summary>
/// ready 后 调用方法
/// </summary>
private void _chromiumWebBrowser_LoadOver()
{
// 调用 网页的方法 比如注入 Token
_chromiumWebBrowser.ExecuteScriptAsync("EventName", [parameter]);
}
/// <summary>
/// 返回注入对象
/// </summary>
/// <returns></returns>
private object ChromiumWebBrowser_ResolveObject()
{
return new JsInteraction();
}
public class JsInteraction
{
public async Task<bool> openItem(string parameterName)
{
// 写一些方法 让网页可以调用 winform 比如打开 winform 的某个页面等
}
}
private void BtnRefresh_ItemClick(object sender, ItemClickEventArgs e)
{
//刷新页面
_chromiumWebBrowser.Reload();
}
}
对于网页的一些优化
在 Program 的 Main方法中 开启关闭一些 我也不是特别清楚的的属性
#if ANYCPU
CefRuntime.SubscribeAnyCpuAssemblyResolver();
#endif
var cachePath = Path.Combine(Application.StartupPath, "CefSharp\\Cache");
var settings = new CefSettings();
settings.CachePath = cachePath;
/// <summary>
/// https://github.com/cefsharp/CefSharp/commit/8706aadd3f4d2effc563cc5158734e66639c5293
/// 设置命令行参数以获得最佳 OSR(Offscreen and WPF) 渲染性能 Swiftshader 将用于 WebGL
/// </summary>
//使用软件渲染和合成(禁用 GPU)来提高 FPS 并降低 CPU 使用率
settings.CefCommandLineArgs.Add("disable-gpu");
settings.CefCommandLineArgs.Add("disable-gpu-compositing");
//同步所有进程之间的帧率 通过避免生成额外的帧来降低 CPU 使用率
settings.CefCommandLineArgs.Add("enable-begin-frame-scheduling");
//settings.CefCommandLineArgs.Add("enable-media-stream");
//settings.CefCommandLineArgs.Add("use-fake-ui-for-media-stream");
//settings.CefCommandLineArgs.Add("enable-usermedia-screen-capturing");
//settings.UserAgent = "Mozilla/5.0 (Linux; Android 6.0; Nexus 6P Build/XXXXX; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/47.0.2526.68 Mobile Safari/537.36";
//执行依赖项检查以确保所有相关资源都在输出目录中。
Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null);
CefSharpSettings.ConcurrentTaskExecution = true;
app.manifest
在官方Demo中 有看到通过启动清单(app.manifest 文件)去优化ChromiumWebBrowser 这个就不太懂了 有需要自行百度
版权声明:本文为weixin_44734310原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。