# XNA + Windows Forms: How make them work together without making the trick of the custom GraphicsDeviceControl?

What I've found is a solution where you have to code a custom GraphicsDeviceControl to put inside the form (the well known tutorial from the APPHub), but that's not what I'm searching for.

I would like to say that before start to write my question here, I "googled" a lot and I saw some questions here, but I couldn't find what I'm looking for.

I would like to have the Draw/Update loops completly managed by XNAFrameWork (with XNA project and so), and not by a custom component.

I hope you understand what I asked.

Edit

What's the most important thing for me and wasn't shown in the tutorial of APPHub is: where I have to put the input handling? That's one the problems that wasn't covered by the tutorial.

• Do you want the game to run inside of a winfrom enviroment? You will need some control. Like a picturebox to draw the game in. Controls for the game itself would still be managed by XNA. – Dialock Nov 5 '12 at 5:02
• Yes, that's what I want. I tried with a picturebox, but I was getting an exception saying that I was running a loop inside another (something like that). – Renann Nov 5 '12 at 12:12
• The final result that I'm looking for is something like that: Make the picture box behind controls that I'll drop using the VS' GUI designer and still have the loops being managed by the XNA. – Renann Nov 5 '12 at 12:22

What I learned to do was to start your main project as usual with a Windows Game (4.0) then add your winform.

Create a field to hold a reference to the Game1 class inside the form1 class

Game1 gameEntry;

Set the modifier on your pictureBox to public.

In Program.cs : replace everything in static void Main()

Form1 form = new Form1();
form.show();
// This line creates a Game1 object in the gameEntry field created earlier.
form.gameEntry = new Game1(form.pictureBox1.Handle, form, form.pictureBox1);
form.gameEntry.Run();


OR:

using (Form1 editorForm = new Form1())
{
editorForm.Show();
editorForm.gameEntry = new Game1(editorForm);
editorForm.gameEntry.Run();
}


This means we need to modify the constructor that comes with Game1.

System.Windows.Forms.Control gameForm;

public Game1(IntPtr drawingSurface, System.Windows.Forms parentForm, System.Windows.Forms.PictureBox pictureBox)
{
this.drawingSurface = drawingSurface;
this.parentForm = parentForm;
this.pictureBox = pictureBox;

// prepare graphics event
graphics.PreparingDeviceSettings +=
new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);

gameForms = System.Windows.Forms.Control.FromHandle(this.Window.Handle);

//Tell the mouse it will be getting it's input through the pictureBox
Mouse.WindowHandle = drawSurface;

}

private void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
{
// Finally attach game1's draw ability to the picture box in winforms.
e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = drawSurface;
}


At this point you should be able to run the program and will have two windows. You probably don't want the game1 window showing so create an event to hide it.

private void gameForm_VisiblilityChanged(object sender, EventArgs e)
{
if (gameForm.Visible = true)
gameForm.Visible = false;
}