Search code examples
vb.netwinformsmonogame

Can't Programmatically Minimize Window


I'm trying to create a custom TitleBar for my game, i got everything else to work like i wanted but i can't get it to minimize without using the windows buttons from the windows frame.

I have a Game class with these in the constructor :

'Having this here or in the constructor doesn't make any difference
Public AsWindow As Windows.Forms.Form = CType(Windows.Forms.Form.FromHandle(Me.Window.Handle), Windows.Forms.Form)

Public Sub New()
    Window.AllowUserResizing = False
    Window.IsBorderless = True
end sub

Public Sub Minimize()
    AsWindow.WindowState = System.Windows.Forms.FormWindowState.Minimized
End Sub

Calling Minimize cause a "System.NullReferenceException" on AsWindow, regardless of if i define AsWindow on runtime or during the initiation.

Note that i have added "System.Windows.Forms" as a reference.

Things i've tried:

  1. This is where i got the initial code for the AsWindow field.

  2. And here i tried to send a Message to minimize the window.


Solution

  • The problem you're facing is that the MonoGame API (which is exactly like XNA) doesn't expose a direct way of controlling the window. This kinda makes sense, because MonoGame supports platforms that don't have a concept of a "window" so to speak.

    However, it's usually possible to get access to the underlying platform specific code and workaround these issues. It's important to keep in mind however that this approach will be platform specific and might break if MonoGame changes under the hood.

    Last I checked, under the hood MonoGame uses SDL on the Windows desktop platform. This may not be true anymore, but I do have some code in an old project that gives the general idea. My code is in C# but it should point you in the right direction.

    The first step is to import the method you want from the SDL.dll. This not managed code do you can't reference it like you normally would in .NET project.

    [DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern void SDL_MaximizeWindow(IntPtr window);
    

    Once you have access to the method you can call it by passing in the window handle.

    SDL_MaximizeWindow(Window.Handle);
    

    Obviously, this is code to maximize the window (that's the only code I had handy) but I'm sure you can figure out how to do the minimize version yourself.