如何在Monogame项目中实现Awesomium 1.7.4.2?

我试图在我的monogame项目中渲染渲染浏览器,用于绘制一些界面和东西。 我在过去使用旧版本的awesomium完成了这项工作,没有任何问题。 但我无法弄清楚如何在这个新版本中正确地初始化awesomium,无论我如何尝试它,我都会收到错误。 据我所知,我需要调用WebCore.Run()一次,而不是WebCore.Update(),但我得到该方法的variusexception。

以下是我到目前为止所遵循的步骤:

  1. 安装Awesomium 1.7.4.2
  2. 我的项目中的Refrenced \1.7.4.2\wrappers\Awesomium.NET\Assemblies\Packed\Awesomium.Core.dll

以下是我的一些尝试:

  WebCore.Initialize(new WebConfig()); WebCore.Run(); //Error: Starting an update loop on a thread with an existing message loop, is not supported. 

  WebCore.Initialized += (sender, e) => { WebCore.Run(); }; WebCore.Initialize(new WebConfig()); WebView WebView = WebCore.CreateWebView(500, 400); //Error: Starting an update loop on a thread with an existing message loop, is not supported. 

  WebCore.Initialize(new WebConfig()); WebView WebView = WebCore.CreateWebView(500, 400); WebView.Source = new Uri("http://www.google.com"); WebView.DocumentReady += (sender, e) => { JSObject js = WebView.CreateGlobalJavascriptObject("w"); }; // No errors, but DocumentReady is never fired.. 

我还设法得到NullRefrence错误,如果我在调用WebCore.Run()之前等待Thread.Sleep(400),它只是进入WebCore.Run()并且永远不会完成该行。

我该如何设置? 在任何地方都找不到任何例子。 所有在线示例仍然告诉您使用更新已过时

我刚刚开始工作,你必须创建一个新线程,然后调用Run,然后监听由WebCore引发的事件,届时将创建一个新的SynchronizationContext。 然后,您希望在主线程上保留对该上下文的引用…

 Thread awesomiumThread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { WebCore.Started += (s, e) => { awesomiumContext = SynchronizationContext.Current; }; WebCore.Run(); })); awesomiumThread.Start(); WebCore.Initialize(new WebConfig() { }); 

…然后,您可以使用该SynchronizationContext调用所有WebView方法…

 awesomiumContext.Post(state => { this.WebView.Source = "http://www.google.com"; }, null); 

我会用未来的编辑来整理这个,但为了让你们开始,这是我的组件……

 using Awesomium.Core; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace AwesomiumComponent { public class BasicAwesomiumComponent : DrawableGameComponent { private Byte[] imageBytes; private Rectangle area; private Rectangle? newArea; private Boolean resizing; private SpriteBatch spriteBatch; private Texture2D WebViewTexture { get; set; } private SynchronizationContext awesomiumContext = null; private WebView WebView { get; set; } private BitmapSurface Surface { get; set; } private MouseState lastMouseState; private MouseState currentMouseState; private Keys[] lastPressedKeys; private Keys[] currentPressedKeys = new Keys[0]; private static ManualResetEvent awesomiumReady = new ManualResetEvent(false); public Rectangle Area { get { return this.area; } set { this.newArea = value; } } public BasicAwesomiumComponent(Game game, Rectangle area) : base(game) { this.area = area; this.spriteBatch = new SpriteBatch(game.GraphicsDevice); Thread awesomiumThread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { WebCore.Started += (s, e) => { awesomiumContext = SynchronizationContext.Current; awesomiumReady.Set(); }; WebCore.Run(); })); awesomiumThread.Start(); WebCore.Initialize(new WebConfig() { }); awesomiumReady.WaitOne(); awesomiumContext.Post(state => { this.WebView = WebCore.CreateWebView(this.area.Width, this.area.Height, WebViewType.Offscreen); this.WebView.IsTransparent = true; this.WebView.CreateSurface += (s, e) => { this.Surface = new BitmapSurface(this.area.Width, this.area.Height); e.Surface = this.Surface; }; }, null); } public void SetResourceInterceptor(IResourceInterceptor interceptor) { awesomiumContext.Post(state => { WebCore.ResourceInterceptor = interceptor; }, null); } public void Execute(string method, params object[] args) { string script = string.Format("viewModel.{0}({1})", method, string.Join(",", args.Select(x => "\"" + x.ToString() + "\""))); this.WebView.ExecuteJavascript(script); } public void RegisterFunction(string methodName, Action handler) { // Create and acquire a Global Javascript object. // These object persist for the lifetime of the web-view. using (JSObject myGlobalObject = this.WebView.CreateGlobalJavascriptObject("game")) { // The handler is of type JavascriptMethodEventHandler. Here we define it // using a lambda expression. myGlobalObject.Bind(methodName, true, (s, e) => { handler(s, e); // Provide a response. e.Result = "My response"; }); } } public void Load() { LoadContent(); } protected override void LoadContent() { if (this.area.IsEmpty) { this.area = this.GraphicsDevice.Viewport.Bounds; this.newArea = this.GraphicsDevice.Viewport.Bounds; } this.WebViewTexture = new Texture2D(this.Game.GraphicsDevice, this.area.Width, this.area.Height, false, SurfaceFormat.Color); this.imageBytes = new Byte[this.area.Width * 4 * this.area.Height]; } public override void Update(GameTime gameTime) { awesomiumContext.Post(state => { if (this.newArea.HasValue && !this.resizing && gameTime.TotalGameTime.TotalSeconds > 0.10f) { this.area = this.newArea.Value; if (this.area.IsEmpty) this.area = this.GraphicsDevice.Viewport.Bounds; this.WebView.Resize(this.area.Width, this.area.Height); this.WebViewTexture = new Texture2D(this.Game.GraphicsDevice, this.area.Width, this.area.Height, false, SurfaceFormat.Color); this.imageBytes = new Byte[this.area.Width * 4 * this.area.Height]; this.resizing = true; this.newArea = null; } lastMouseState = currentMouseState; currentMouseState = Mouse.GetState(); this.WebView.InjectMouseMove(currentMouseState.X - this.area.X, currentMouseState.Y - this.area.Y); if (currentMouseState.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released) { this.WebView.InjectMouseDown(MouseButton.Left); } if (currentMouseState.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed) { this.WebView.InjectMouseUp(MouseButton.Left); } if (currentMouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released) { this.WebView.InjectMouseDown(MouseButton.Right); } if (currentMouseState.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed) { this.WebView.InjectMouseUp(MouseButton.Right); } if (currentMouseState.MiddleButton == ButtonState.Pressed && lastMouseState.MiddleButton == ButtonState.Released) { this.WebView.InjectMouseDown(MouseButton.Middle); } if (currentMouseState.MiddleButton == ButtonState.Released && lastMouseState.MiddleButton == ButtonState.Pressed) { this.WebView.InjectMouseUp(MouseButton.Middle); } if (currentMouseState.ScrollWheelValue != lastMouseState.ScrollWheelValue) { this.WebView.InjectMouseWheel((currentMouseState.ScrollWheelValue - lastMouseState.ScrollWheelValue), 0); } lastPressedKeys = currentPressedKeys; currentPressedKeys = Keyboard.GetState().GetPressedKeys(); // Key Down foreach (var key in currentPressedKeys) { if (!lastPressedKeys.Contains(key)) { this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() { Type = WebKeyboardEventType.KeyDown, VirtualKeyCode = (VirtualKey)(int)key, NativeKeyCode = (int)key }); if ((int)key >= 65 && (int)key <= 90) { this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() { Type = WebKeyboardEventType.Char, Text = key.ToString().ToLower() }); } else if (key == Keys.Space) { this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() { Type = WebKeyboardEventType.Char, Text = " " }); } } } // Key Up foreach (var key in lastPressedKeys) { if (!currentPressedKeys.Contains(key)) { this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() { Type = WebKeyboardEventType.KeyUp, VirtualKeyCode = (VirtualKey)(int)key, NativeKeyCode = (int)key }); } } }, null); base.Update(gameTime); } public override void Draw(GameTime gameTime) { awesomiumContext.Post(state => { if (Surface != null && Surface.IsDirty && !resizing) { unsafe { // This part saves us from double copying everything. fixed (Byte* imagePtr = this.imageBytes) { Surface.CopyTo((IntPtr)imagePtr, Surface.Width * 4, 4, true, false); } } this.WebViewTexture.SetData(this.imageBytes); } }, null); Vector2 pos = new Vector2(0, 0); spriteBatch.Begin(); spriteBatch.Draw(this.WebViewTexture, pos, Color.White); spriteBatch.End(); GraphicsDevice.Textures[0] = null; base.Draw(gameTime); } public Uri Source { get { return this.WebView.Source; } set { awesomiumContext.Post(state => { this.WebView.Source = value; }, null); } } public void Resize(int width, int height) { this.newArea = new Rectangle(0, 0, width, height); ; } } }