Archives

Windows Forms w/ XNA Revisited

Here’s a sample demonstrating what I explained in an earlier blog post, but with quite a few updates and precisions.

Here’s what I deduced after working three evenings on this sample :

Only docked controls work, which means you need to create or use docked containers for all the controls you want to append (except the render panel which must not be docked, but anchored).

Only mouse input works, like Leaf pointed out on my other post, and as I have tested afterwards. Text input is eaten by XNA.

The XNA guys clearly didn’t want us to do that, so it’s not “the right way”. There’s a myriad of problems that can happen. I had to work-around on many aspects, like the auto-sizing of the form based on the presentation parameters’ backbuffer size and the background that’s never repainted… And it’s definitely not perfect.

It’s still the simplest way, and it works well enough for me. I can’t imagine re-writing the whole back-end of the Microsoft.Xna.Framework.Game assembly.

@Gerosa: As far as I can tell, you suggestion #2 would have the unwanted side effect that you can still switch input focus between the outer form and the embedded XNA window.

@Zaknafein: I tried this very same approach when I needed to embed XNA in a Windows.Forms window at first, but the GameWindow class used by the XNA GraphicsDeviceManager kept hogging the Application.Idle message by looping until another message enters the queue, which made it impossible to have more than one Game class active at the same time.

I don’t know whether you’ve found a workaround for this, but at least that was the problem that led me to the decision to clone the entire GraphicsDeviceManager and rewrite the idle loop for my game’s world editor…

@renaud.bedard: Each view in an editor requires its own graphics device, thus, its own instance of a Game class (or GameControl in my implementation).

My editor for example is an MDI application where you can have multiple ‘documents’ (game worlds) open at the same time. What happened when I used your approach was that the first MDI child to open always /wins/ — its Game class starts the idle loop (there’s an actual loop that continues until another message is put in the queue) and blocks all other windows from receiving the WM_IDLE message.

This is a beautiful approach to the problem because of the way it preserves the game object. This makes bringing already developed GameComponent’s from your game to your editor much easier, however I would like to see Gerosa’s suggestion reflected, though I’m not entirely sure I understand the method he would take.

It seems too cumbersome to have to copy designer/form code from a template. Any chance of an update? Again, great example.