0
votes

I currently have a way to do exactly what im asking, but the results are very in-efficient for some users. Some users reported it making it as if it minimized (no window showing ever but still in taskbar), some reported for example in an ultrawide 21:9 it would only maximize from the left of a 1080p 16:9 width, yet I have a 32:9 super-ultrawise and have had no issues.

My current flow:

  • Get the Screen Dimensions excluding the taskbar on-load:

    MaximizedBounds = Screen.FromHandle(mForm.Handle).WorkingArea; (mForm = Application.OpenForms[0], for support from any thread and such)

  • From another thread/function/class run: Form1.mForm.Invoke(new MethodInvoker(() => Form1.mForm.WindowState = FormWindowState.Maximized));
  • This should result in a maximized window with the proper resolution, but it doesn't :/

What I would prefer:

  • NOT require to get the screen dimensions on-load, so use something from official Microsoft Code, either DllImport's, .NET Framework Code, or msapi to get the PROPER MaximizedBounds for Borderless Forms. (formborderstyle.none)

I set MaximizedBounds because if I don't, the application will fullscreen the entire screen, not "maximize" like traditional apps but would end up doing more of a Video Player style fullscreen.

Using my 32:9 screen and my 4k 16:9 laptop's screen on Extend Display mode, I managed to re-create the issue

enter image description here

Re-production Steps:

  • Open the application, leave it on the screen it first started in
  • Maximize the application (will work fine)
  • Unmaximize and move it to the other screen
  • Click maximize, your result should be like above.

This means, the on-load Maximize Bounds only gets the active bounds once which is expected, but due to me executing the Form Style change on a different class and different thread, I cant actually edit the MaximizedBounds property on it everytime I want to maximize, due to property not being public.

1
@HansPassant I can confirm I have no DPI related issues with my app. I used to, but it was resolved months ago before I implemented a Maximize button.Ma Dude
You'll have to interview these users to discover what is special about their setup. It might have something to do with them having multiple monitors on their machine with different resolutions. Perhaps one of them being a projector. Still a DPI issue, per-monitor DPI is possible since Win8.1 and requires True/PM in the manifest. Getting the form properly maximized on both monitors is little joy.Hans Passant
@HansPassant I see, I do theorize they may have a dual-monitor setup, perhaps one is 1080p 16:9 causing it to use that as perhaps that screen is priority 1 in Windows settings? Either way, the MaximizedBounds code should be getting the right screen. Perhaps he booted it up onto Screen 16:9, then moved it to Screen 21:9 clicked Maximize, and kabam?Ma Dude
Sure, why not. Do ask them instead of me.Hans Passant

1 Answers

0
votes

Thanks to HansPassant!

Found out exactly whats needed.

Problem:

  • When moving application to other monitor, it would use the same bounds. Causing it to not properly Maximize
  • When updating bounds via WndProc(), it would still try and maximize on Monitor 1 but outside its actual bounds, making it look like the application was hidden >:(

Updating the Bounds (put this in Form1):

protected override void WndProc(ref Message m) {
    if(m.Msg == 0x02E0) {
        Rectangle b = Screen.FromControl(mForm).WorkingArea; //where mForm is Application.OpenForms[0], this is specific to my applications use case.
        b.X = 0; //The bounds will try to base it on Monitor 1 for example, 1920x1080, to another 1920x1080 monitor on right, will set X to 1080, making it show up on the monitor on right, outside its bounds.
        b.Y = 0; //same as b.X
        MaximizedBounds = b; //Apply it to MaximizedBounds
        m.Result = (IntPtr)0; //Tell WndProc it did stuff
    }
    base.WndProc(ref m); //If any other messages were called, do the defaults this method does. Required even if you edited a msg.
}

Updating DPI Awareness for the WndProc message to fire (put this in app.manifest, make it if it doesnt exist):

<application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitor</dpiAwareness> //Windows 10
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware> //Old-Compatibility
    </windowsSettings>
</application>

Now it no longer shows up out of bounds, and is finally updating the MaximizeBounds when changing monitors!

Thanks @HansPassant for the tips!