2

I have game of XNA, that opens a window's form containing a webBrowser.

Every time I open the form it shows me the following error:

    System.Threading.ThreadStateException was unhandled
  Message=ActiveX control '8856f961-340a-11d0-a96b-00c04fd705a2' cannot be instantiated because the current thread is not in a single-threaded apartment.
  Source=System.Windows.Forms
  StackTrace:
       at System.Windows.Forms.WebBrowserBase..ctor(String clsidString)
       at System.Windows.Forms.WebBrowser..ctor()
       at GameOfLifeV2._0.Help.InitializeComponent() in C:\Users\Gilad\Documents\C# projects\GameOfLifeV2.0\GameOfLifeV2.0\GameOfLifeV2.0\Help.Designer.cs:line 33
       at GameOfLifeV2._0.Help..ctor() in C:\Users\Gilad\Documents\C# projects\GameOfLifeV2.0\GameOfLifeV2.0\GameOfLifeV2.0\Help.cs:line 17
       at GameOfLifeV2._0.Game.RespondKeyboard(KeyboardState state) in C:\Users\Gilad\Documents\C# projects\GameOfLifeV2.0\GameOfLifeV2.0\GameOfLifeV2.0\Game.cs:line 111
       at GameOfLifeV2._0.Game.Update(GameTime gameTime) in C:\Users\Gilad\Documents\C# projects\GameOfLifeV2.0\GameOfLifeV2.0\GameOfLifeV2.0\Game.cs:line 68
       at Microsoft.Xna.Framework.Game.Tick()
       at Microsoft.Xna.Framework.Game.HostIdle(Object sender, EventArgs e)
       at Microsoft.Xna.Framework.GameHost.OnIdle()
       at Microsoft.Xna.Framework.WindowsGameHost.RunOneFrame()
       at Microsoft.Xna.Framework.WindowsGameHost.ApplicationIdle(Object sender, EventArgs e)
       at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FDoIdle(Int32 grfidlef)
       at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
       at System.Windows.Forms.Application.Run(Form mainForm)
       at Microsoft.Xna.Framework.WindowsGameHost.Run()
       at Microsoft.Xna.Framework.Game.RunGame(Boolean useBlockingRun)
       at Microsoft.Xna.Framework.Game.Run()
       at GameOfLifeV2._0.Program.Main(String[] args) in C:\Users\Gilad\Documents\C# projects\GameOfLifeV2.0\GameOfLifeV2.0\GameOfLifeV2.0\Program.cs:line 15
  InnerException:

in the following line:

this.InfoBrowsersd = new System.Windows.Forms.WebBrowser();

Solutions will be welcomed :)

Alternate problem: Is there any better way to show help-documents then creating HTML files and showing them in webBrowser Control?

Gilad Naaman
  • 6,390
  • 15
  • 52
  • 82

3 Answers3

2

Do you need to be able to show the help on the Xbox, or only on Windows? To get it working on Windows, just add a [STAThread] attribute to your Main() function in Program.cs:

[STAThread]
static void Main(string[] args)
{
    ...
}

See http://blogs.msdn.com/b/oldnewthing/archive/2008/04/24/8420242.aspx for background on the STA vs. MTA models.

Justin
  • 6,611
  • 3
  • 36
  • 57
1

Have you tried just launching the Help file via

System.Diagnostics.Process.Start("c:\...\MyHelpFile.html")  

That would open your HTML file in whatever program the user has setup by default on their PC to view HTML files. (you'd have to replace the path in the above code with the path to your actual HTML file).

Since you say you have to display it in the game, then I think your only other option would be to try and open the form in it's own thread.

  Thread helpThread = new Thread(new ThreadStart(delegate() { 
     this.InfoBrowsersd = new System.Windows.Forms.WebBrowser();
  })); 

  helpThread.Start(); 

Hopefully I got the syntax right for that, but give that a try and see if that give you your desired result. I think you're running into an issue because you can't launch a WinForm from within the game loop thread. It's not really designed to support that. So launch it in a new thread may help you get around it.

George Clingerman
  • 1,395
  • 9
  • 15
  • I need the browser to be implanted in the program. – Gilad Naaman Jan 13 '11 at 20:33
  • 1
    Oh, ok, well I updated my answer with another suggestion. I didn't have a chance to try it out but it seems like something like that might work. – George Clingerman Jan 13 '11 at 20:46
  • Your edit will only call the constructor for the `WebBrowser` control on a separate thread, but the message loop will still be running on the current thread, which "is not in a single-threaded apartment". If you're lucky, the best it will do is give the same error the OP is already getting. You would have to make a new thread, set its ApartmentState, and run a separate message loop to get this working, but I'm not sure if it is possible in C#. See http://stackoverflow.com/questions/787023/c-thread-safe-form-show/787042#787042 – Justin Jan 13 '11 at 21:03
1

Depending on what your target platform is, you could use Awesomium with the .net wrapper to render your HTML files in-game.

Chris
  • 4,393
  • 1
  • 27
  • 33
  • For some reason I can't seem to be able to use Awesomium.NET. I referenced it and added the 'using', but the debuget tells me that the assembly 'awesomium' + blablabla + '.dll' cannot be found – Gilad Naaman Jan 13 '11 at 20:32