1
votes

I have a WPF window which has these properties:

-ResizeMode=NoResize

-WindowStyle=None

I made every functionality of a normal window but i can't figure out how can i make window auto resize itself(when it's maximized) when taskbar's height changes. (Like Microsoft Visual Studio 2017 Window).

I can manually maximize my window but if I hide taskbar there is an empty space between my window and bottom of screen.

Is there any event fired when working area changes?

2

2 Answers

1
votes

For your problem you can use SystemParameters.WorkArea. Initially set the MaxHeight of your MainWindow.

MaxHeight="{Binding Height, Source={x:Static SystemParameters.WorkArea}}"

Register to the SystemParameters.StaticPropertyChanged in the codebehind of the MainWindow to receive changes and update your window size.

SystemParameters.StaticPropertyChanged += (sender, args) =>
{
    if (args.PropertyName == nameof(SystemParameters.WorkArea))
    {
         this.Dispatcher.Invoke(() =>
         {
             MaxHeight = SystemParameters.WorkArea.Height;
             Height = SystemParameters.WorkArea.Height;
             WindowState = WindowState.Normal;  // Updates the windows new sizes
             WindowState = WindowState.Maximized;
         });
    }
};
0
votes

Handle the WM_GETMINMAXINFO message for your window, and do whatever re-sizing you need to do

    public MainWindow()
    {
        InitializeComponent();
        SourceInitialized += new EventHandler(win_SourceInitialized);
    }

    private void win_SourceInitialized(object sender, EventArgs e)
    {
        System.IntPtr handle = (new WinInterop.WindowInteropHelper(this)).Handle;
        WinInterop.HwndSource.FromHwnd(handle).AddHook(new WinInterop.HwndSourceHook(WindowProc));
    }

    private const int WM_GETMINMAXINFO = 0x0024;
    private static System.IntPtr WindowProc(
          System.IntPtr hwnd,
          int msg,
          System.IntPtr wParam,
          System.IntPtr lParam,
          ref bool handled)
    {
        switch (msg)
        {
            case WM_GETMINMAXINFO: //https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-getminmaxinfo
                WmGetMinMaxInfo(hwnd, lParam); // <------  Do what you need to here   ---------->
                handled = true;
                break;
        }

        return (System.IntPtr)0;
    }

Note that if you are a borderless, not-resizable window, you may also need to get the monitor info (via the Win32 GetMonitorInfo) and restrict your application to the work area of the monitor it is on. On our systems, windows does not correctly size the window for 1900x1200 monitors (it makes it too tall, so we have to set the MaxHeight based on the Monitor Info, and pay attention for that to change if the taskbar is resized by continuing to watch the WM_GETMINMAXINFO messages).

This blog can probably help with that if you have those issues as well:

https://blogs.msdn.microsoft.com/llobo/2006/08/01/maximizing-window-with-windowstylenone-considering-taskbar/