Веб-браузер в XNA 4.0 не выполняет навигацию

#c# #.net #xna #webbrowser-control #textures

#c# #.net #xna #веб-браузер-управление #Текстуры

Вопрос:

Я пытался заставить веб-браузер рисовать текстуру в XNA 4.0, и я нашел несколько руководств о том, как это сделать. Проблема в том, что когда я пытаюсь это реализовать, независимо от того, изменяю ли я Url свойство или вызываю Navigate() его, страница просто не загружается. У меня такое чувство, что я немного неосведомлен о требуемых потоках, поскольку мой проект запускается не как поток STA, поэтому я создаю отдельный поток для запуска веб-браузера и рендеринга в растровое изображение.

Вот как я его запускаю:

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

    _resetEvent = new AutoResetEvent(false);
    Thread thread = new Thread(GetWebScreenshot);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    _resetEvent.WaitOne();
}
  

И вот 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();
}
  

ReadyState Свойство никогда не меняется Uninitialized , я также пробовал использовать DocumentReady событие, и оно никогда не срабатывает. Я также пробовал Join() вместо AutoResetEvent , но, похоже, ничего не работает.

Ответ №1:

Я был прав, это было невежество с моей стороны. Критическая вещь в элементах управления ActiveX и однопоточных квартирах заключается в том, что очередь сообщений должна быть загружена. Итак, теперь я изменил свой код следующим образом:

 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
}
  

Это работает без проблем.