开发者

WebBrowser in XNA 4.0 not Navigating

开发者 https://www.devze.com 2023-04-11 02:48 出处:网络
I\'ve been trying to get a WebBrowser to draw to a texture in XNA 4.0, and I\'ve found several guides on how to do it. The problem is when I try to implement it, whether I change the Url property or c

I've been trying to get a WebBrowser to draw to a texture in XNA 4.0, and I've found several guides on how to do it. The problem is when I try to implement it, whether I change the Url property or call Navigate() it just won't load the page. I have a feeling I'm being a bit ignorant about the threading required, since my project is not started as an STA thread, so I create a separate thread to start the web browser and render to a bitmap.

Here's how I start it:

public void LoadTexture(GraphicsDevice gfx, ContentManager content, string filename, float duration = -1f)
{
    this.gfx = gfx;
    this.filename = filename;
    this.duration = duration;

    _reset开发者_JS百科Event = new AutoResetEvent(false);
    Thread thread = new Thread(GetWebScreenshot);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    _resetEvent.WaitOne();
}

And here's GetWebScreenshot:

public void GetWebScreenshot()
{
    this.web = new WebBrowser();
    this.web.Size = new Size(gfx.Viewport.Width, gfx.Viewport.Height);
    this.web.Url = new Uri(this.filename);

    while (this.web.ReadyState != WebBrowserReadyState.Complete)
    {
        if (this.web.ReadyState != WebBrowserReadyState.Uninitialized)
        {
            Console.WriteLine(this.web.ReadyState.ToString());
        }
    }

    bitmap = new Bitmap(this.gfx.Viewport.Width, this.gfx.Viewport.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    this.web.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
    this.texture = BitmapToTexture2D(this.gfx, bitmap);
    _resetEvent.Set();
}

The ReadyState property never changes from Uninitialized, I've also tried using the DocumentReady event, and that never gets fired. I've also tried Join() instead of AutoResetEvent, but nothing seems to work.


I was right, it was ignorance on my part. The critical thing about ActiveX controls and Single Threaded Apartments is that the message queue needs to be pumped. So now I've restructured my code to the following:

public void LoadTexture(GraphicsDevice gfx, ContentManager content, string filename, float duration = -1f)
{
    this.gfx = gfx;
    this.filename = filename;
    this.duration = duration;

    Thread thread = new Thread(GetWebScreenshot);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
}

public void GetWebScreenshot()
{
    this.web = new WebBrowser();
    this.web.Size = new Size(gfx.Viewport.Width, gfx.Viewport.Height);
    this.web.Url = new Uri(this.filename);
    this.web.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(web_DocumentCompleted);
    Application.Run(); // Starts pumping the message queue (and keeps the thread running)
}

void web_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
    Bitmap bitmap = new Bitmap(this.gfx.Viewport.Width, this.gfx.Viewport.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    this.web.DrawToBitmap(bitmap, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height));
    this.texture = HTMLTextureFactoryMachine.BitmapToTexture2D(this.gfx, bitmap);
    Application.ExitThread(); // Exits the thread
}

This works no problem.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号