2

I have a VB.NET WinForm program in MS VS2017 on MS Windows 10, that has a restricted width, but that should maximize in height the same as any normal Windows application. I have multiple monitors, of different sizes, which seems to be messing with how the application determines the desktop's height. I should note, that my task-bar is set to not expand across the second screen, but only appear on the primary screen (this does not seem to affect other Windows applications behavior though).

I am using the following code in the Move event handler (I tried overriding WndProc too, but no luck) but the form maximizes behind the task-bar on the primary screen, i.e. it takes up the full screen height, where it should take up the full screen height minus the task-bar height. It does however, maximize to the correct height on the secondary screen.

Private Sub form1_Move(sender As Object, e As EventArgs) _
    Handles MyBase.Move
    Me.MaximumSize = New Size(Me.MaximumSize.Width, _ 'fixed width
            My.Computer.Screen.Bounds.Height) 'screen height
End Sub

Today I tried changing the line to:

    Me.MaximumSize = New Size(Me.MaximumSize.Width, _ 'fixed width
            My.Computer.Screen.FromControl(Me).WorkingArea.Height) 'screen height

But this now results in more complex, but still incorrect behavior! (Not full height on the secondary screen). I also tried using SystemInformation.VirtualScreen.Height, but again, no luck

What is correct way of managing to get the correct height?

Here is an image two of the issues described, the left is the primary monitor, with the form maximizing with a height that places part of it behind the task-bar, the right is the secondary monitor with the maximized height not being high enough to fill the screen that doesn't have the task-bar. As described above, some code ended up also having the form not even meeting the task-bar when maximized on the primary monitor. Basically I just want it to maximize just like any other application, correctly on either monitor, with or without a task-bar, but with a restricted width. screen-grab

Toby
  • 9,696
  • 16
  • 68
  • 132
  • Don't do that, bad usability, more technical challenges. Instead make a proper multi-monitor application, one form shows on 1 screen, another form on screen 2. User can then decide if they want to split screen (WIN+Left,Right, if they only have 1 monitor) or show 1 form on each for dual monitor setups. This scales well if they have 3 monitors and you happen to have 3 full screen form options (and so on). – Victor Zakharov Apr 11 '17 at 12:58
  • @Neolisk I think you have taken my meaning wrong, I mean that it should only maxmize on a single screen as a normal application, just that it should maximize as normal, ie: without any extra space at the bottom and without changing to a size that means a portion of it is behind the task-bar – Toby Apr 11 '17 at 13:00
  • 1
    I thought you wanted to maximize across 2+ screens. Can you attach a screenshot / mockup to explain? – Victor Zakharov Apr 11 '17 at 13:00
  • @Neolisk, added as requested, hope it is clear. – Toby Apr 11 '17 at 13:10
  • What the heck is a "Move event handler"?? This question requires decent repro code to go anywhere, design-time code needs to be included. – Hans Passant Apr 11 '17 at 13:25
  • @HansPassant, the *form's* move event handler I have added this clarification - is the meaning clear now? – Toby Apr 11 '17 at 13:28
  • If Win+Left,Right works for you, I suggest you don't reinvent the wheel. Just supply the instructions for the user. There is probably an easy way to programmatically trigger Win+Left,Right through winapi (example, focus window A - sendkeys, focus window B - sendkeys, or perhaps even a special win7+ specific snap function - you'll need to dig into that). – Victor Zakharov Apr 11 '17 at 13:30
  • I've removed the comment about the L/R keys, obviously it was causing confusion. I simply want maximise to behave as it should, irrespective of which screen the form is on. – Toby Apr 11 '17 at 13:32
  • You want to maximize a form to take half screen, right? – Victor Zakharov Apr 11 '17 at 13:38
  • No I want a maximized form to take full *height*, while remaining at the fixed *width* (312). It doesn't make sense for it to be any wider. There are only a few controls on it, they would just end up either massively sized or spread out too far if the form was half-screen *width*. Maximizing just makes the a text box longer here (also no point in having that wider, it's contents only go so wide and it doesn't accept user input) – Toby Apr 11 '17 at 13:41
  • Possible duplicate of [Is it possible to set the Maximum Width for a Form but leave the Maximum Height Unrestricted?](http://stackoverflow.com/questions/13527142/is-it-possible-to-set-the-maximum-width-for-a-form-but-leave-the-maximum-height) – GSerg Apr 11 '17 at 13:44
  • @GSerg I've specifically mentioned, in the question, that those methods do not work. – Toby Apr 11 '17 at 14:04
  • @Toby You set `MaximumSize` once in the beginning, or even in the designer, not from the `Move` handler. Otherwise [this method](http://stackoverflow.com/a/22672691/11683) does work. – GSerg Apr 11 '17 at 14:11
  • @GSerg I have (again) tried all answers there, they still suffer the same problem of the form extending behind the task-bar – Toby Apr 11 '17 at 14:23

2 Answers2

2

Look at the documentation for WM_GETMINMAXINFO, and however that's exposed in .NET.

You might also want to look at WM_WINDOWPOSCHANGING message.

Both of these allow you to control the size of your window.

Roger Lipscombe
  • 89,048
  • 55
  • 235
  • 380
  • Roger, I have zero idea how to access win APi from vb.net ... I have tried it using `Marshal.PtrToStructure` and `Marshal.StructuretoPtr` with structs defined with the `` attribute, but get an access violation. Any quick example without the mumbo jumbo MSDN gave me? :D – Toby Apr 11 '17 at 14:36
  • I don't think this has any advantage over what's already exposed in .NET. Setting `MaximumSize` fills the values that will be reported from the `WM_GETMINMAXINFO` handler, and `WM_WINDOWPOSCHANGING` is not really useful because you don't need it if you can provide correct values for `WM_GETMINMAXINFO`. I believe the OP's problem is that they don't know how to calculate the max height, as opposed to not being able to pass it to the windows manager. – GSerg Apr 12 '17 at 06:57
  • Then again, I'm not even sure why the OP even has that problem. If they [provide `int.MaxValue` for the height](http://stackoverflow.com/a/22672691/11683), the windows manager should be able to correctly maximize the window on any screen. – GSerg Apr 12 '17 at 06:59
  • @GSerg, thanks for the info WRT WM_GETMAXINFO, I was beginning to think this too. As regards `int.MaxValue`; this _should_ work, but it does not. – Toby Apr 12 '17 at 08:49
  • 1
    @Toby Actually this [appears to be a problem with Windows 10](https://www.google.com/search?q=windows+10+maximized+window+overlaps+taskbar). Have you tried https://answers.microsoft.com/en-us/windows/forum/windows_7-desktop/my-locked-taskbar-overlaps-maximized-windows/b1c3c76b-71c0-4bdd-9d6a-1520f1ef9f38? – GSerg Apr 12 '17 at 16:20
0

Using this will give you the max height with the taskbar

SystemParameters.WorkArea.Height

Also this post may help full screen mode, but don't cover the taskbar

Community
  • 1
  • 1
AlexVMM
  • 126
  • 4
  • My VS2017 does not seem to recognize `System.Windows.SystemParameters` and it does not show in the frameworks references available to add ... is some added install required? – Toby Apr 11 '17 at 14:14
  • Sorry I don't have VS2017 here [link](https://msdn.microsoft.com/en-us/library/system.windows.systemparameters%28v=vs.110%29.aspx) it says it's part of the PresentationFramework – AlexVMM Apr 11 '17 at 14:38
  • Ah, I am using WinForms, not WPF (as in question title). – Toby Apr 11 '17 at 14:40