4

I have a WPF app that handles WM_GETMINMAXINFO in order to customize the Window chrome and still honor the system taskbar. That is, when you maximize the window on the monitor with the taskbar on it, it will not cover the taskbar. This works fine, except the window's frame is still visible when maximized, which is both ugly and useless because the window can't be resized when it's maximized anyway.

To combat this, I figured I need to alter my handling of WM_GETMINMAXINFO to increase the size of the window like this:

var monitorInfo = new SafeNativeMethods.MONITORINFO
    {
        cbSize = Marshal.SizeOf(typeof(SafeNativeMethods.MONITORINFO))
    };
SafeNativeMethods.GetMonitorInfo(monitor, ref monitorInfo);
var workArea = monitorInfo.rcWork;
var monitorArea = monitorInfo.rcMonitor;
minMaxInfo.ptMaxPosition.x = Math.Abs(workArea.left - monitorArea.left);
minMaxInfo.ptMaxPosition.y = Math.Abs(workArea.top - monitorArea.top);
minMaxInfo.ptMaxSize.x = Math.Abs(workArea.right - workArea.left);
minMaxInfo.ptMaxSize.y = Math.Abs(workArea.bottom - workArea.top);

// increase size to account for frame
minMaxInfo.ptMaxPosition.x -= 2;
minMaxInfo.ptMaxPosition.y -= 2;
minMaxInfo.ptMaxSize.x += 4;
minMaxInfo.ptMaxSize.y += 4;

This actually works, but my concern is the last four lines where I assume that the frame width is 2 pixels. Is there a more generic approach to obtaining the frame width so I can accommodate it in my WM_GETMINMAXINFO handler?

Thanks

  • Your assumption of frames not being visible due to being outside of the work area is not correct, this will look horrible with multiple monitors.. – Sertac Akyuz Mar 18 '11 at 19:13
  • @Sertac Akyuz: that is not the case. Even if I greatly exaggerate the values to 20 and 40 respectively, the window does not render across multiple monitors. This is presumably because Windows knows the window is maximized and should not render outside the bounds of a single monitor. All that happens is it acts like a negative margin - 18 pixels of my UI are missing from every side. – cantloginfromwork Mar 21 '11 at 10:12
  • @cantlogin - Ok. I believe what you're looking for is one of the indexes of [GetSystemMetrics](http://msdn.microsoft.com/en-us/library/ms724385%28v=vs.85%29.aspx), possibly SM_CXFRAME/SM_CYFRAME. – Sertac Akyuz Mar 21 '11 at 10:55
  • @Sertac Akyuz: close. I actually needed `SM_CXFIXEDFRAME` / `SM_CYFIXEDFRAME`, since the frame is not resizable. And this corresponds to `SystemParameters.FixedFrameVerticalBorderWidth` and `SystemParameters.FixedFrameHorizontalBorderHeight`, which seems really obvious in hindsight. If you add as an answer I'll mark it accepted. – cantloginfromwork Mar 21 '11 at 11:15
  • @cantlogin - Please provide an answer yourself as I know nothing about wpf, I'll vote for it. :) – Sertac Akyuz Mar 21 '11 at 12:39

1 Answers1

3

Sertac got me off on the right direction by pointing out the GetSystemMetrics Win32 API. This reminded me of WPF's SystemParameters class, in which I found the FixedFrameHorizontalBorderHeight and FixedFrameVerticalBorderWidth properties. These are exactly what I needed:

// increase size to account for frame
minMaxInfo.ptMaxPosition.x -= (int)SystemParameters.FixedFrameVerticalBorderWidth;
minMaxInfo.ptMaxPosition.y -= (int)SystemParameters.FixedFrameHorizontalBorderHeight;
minMaxInfo.ptMaxSize.x += (int)(SystemParameters.FixedFrameVerticalBorderWidth * 2);
minMaxInfo.ptMaxSize.y += (int)(SystemParameters.FixedFrameHorizontalBorderHeight * 2);