Turns out it isn't that hard, though it may bring undesirable side effects, such as stealing resources from the game, causing spontaneous lags (slightly noticeable), and to make it work perfectly, it will take some time.
What I did is created a new Form
and assigned an event handler to its ResizeEnd
event. The event handler sets the public static Rectangle fakeWindowRect
to new rectangle of the fake window client area, which is calculated with help of Form.RectangleToScreen()
method.
Here are some code pieces:
static void Main(string[] args)
{
System.Windows.Forms.Form f = new System.Windows.Forms.Form();
f.ClientSize = new System.Drawing.Size(800, 600);
f.TransparencyKey = f.BackColor;
((Action)(() => System.Windows.Forms.Application.Run(f))).BeginInvoke(
null, null);
using (Game1 game = new Game1())
{
f.ResizeEnd += new EventHandler(game.f_LocationChanged);
game.Run();
}
}
public class Game1 : Microsoft.Xna.Framework.Game
{
public static Rectangle windowRect;
/* ... */
protected override void Update(GameTime gameTime)
{
if (windowRect.X != this.Window.ClientBounds.X ||
windowRect.Y != this.Window.ClientBounds.Y ||
windowRect.Width != this.Window.ClientBounds.Width ||
windowRect.Height != this.Window.ClientBounds.Height)
{
// this method sets the game window size, but not location
InitGraphicsMode(windowRect.Width, windowRect.Height,
this.graphics.IsFullScreen);
var win = System.Windows.Forms.Control.FromHandle(
this.Window.Handle) as
System.Windows.Forms.Form;
win.SetBounds(windowRect.X,
windowRect.Y,
windowRect.Width,
windowRect.Height);
win.Activate();
}
}
public void f_LocationChanged(object sender, EventArgs e)
{
var FakeWindow = sender as System.Windows.Forms.Form;
var drawClientArea = FakeWindow.RectangleToScreen(
FakeWindow.ClientRectangle);
windowRect = new Rectangle(
drawClientArea.X,
drawClientArea.Y,
drawClientArea.Width,
drawClientArea.Height);
}
}
Implementation might be terrible and wrong all around, but it works without stealing all resources from the game, even when resizing the fake form the game drops some frames, but doesn't pause completely.
So I tested it, it works, but it was mainly for science, and I'm not planning on using this approach anytime soon. Maybe when I really, really need it.