我试图在我的monogame项目中渲染渲染浏览器,以绘制一些界面和内容。过去,我使用旧版本的Awesomium做到了这一点,没有任何问题。但是我不知道如何在这个新版本中正确初始化awesomium,无论我如何尝试都会遇到错误。
据我了解,我需要调用一次WebCore.Run()而不是WebCore.Update(),但是我从该方法中获得了各种异常。
到目前为止,这是我已经执行的步骤:

  • 安装Awesomium 1.7.4.2
  • 我的项目中的\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<object, CancelEventArgs> 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); ;
            }
        }
    }
    

    关于c# - 如何在Monogame项目中实现Awesomium 1.7.4.2?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23030220/

    10-12 16:25