#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
}
Это работает без проблем.