1

I have a wpf application and I manage max sizing with WmGetMinMaxInfo:

private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
    MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
    IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

    if (monitorContainingApplication != System.IntPtr.Zero)
    {
        MONITORINFO monitorInfo = new MONITORINFO();
        GetMonitorInfo(monitorContainingApplication, monitorInfo);
        RECT rcWorkArea = monitorInfo.rcWork;
        RECT rcMonitorArea = monitorInfo.rcMonitor;

        mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
        mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);

        mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
        mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);

        mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;
        mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;
        
    }

    Marshal.StructureToPtr(mmi, lParam, true);
}

My window are set to :

WindowStyle="None"
ResizeMode="CanResizeWithGrip" 
AllowsTransparency="True"

I have an wierd issue when I minimized the app at maximized state and when click for return at the taskbar icon to come back on the maximized window app.

It don't take the full screen, It's seems to take the primary screen resolution. I got that case when I don't have the same resolution between primary and secondary screen (Obviously my secondary are bigger than the first one).

Do you have any ideas where is the issue ? Windows features ? There is any work around ?

SOLUTION: I have solved my issue with the idea of Keithernet to not recalculate when the windowState are minimized. Thank !

private static void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
    MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
    IntPtr monitorContainingApplication = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);

    if (monitorContainingApplication != System.IntPtr.Zero)
    {
        MONITORINFO monitorInfo = new MONITORINFO();
        GetMonitorInfo(monitorContainingApplication, monitorInfo);
        RECT rcWorkArea = monitorInfo.rcWork;
        RECT rcMonitorArea = monitorInfo.rcMonitor;

        if (Application.Current.MainWindow.WindowState != WindowState.Minimized)
        {
            mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.left - rcMonitorArea.left);
            mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.top - rcMonitorArea.top);

            mmi.ptMaxSize.x = Math.Abs(rcWorkArea.right - rcWorkArea.left);
            mmi.ptMaxSize.y = Math.Abs(rcWorkArea.bottom - rcWorkArea.top);

            mmi.ptMaxTrackSize.x = mmi.ptMaxSize.x;
            mmi.ptMaxTrackSize.y = mmi.ptMaxSize.y;
            lastGoodMaxTrackSize = mmi.ptMaxTrackSize;
            lastGoodMaxPosition = mmi.ptMaxPosition;
            lastGoodMaxSize = mmi.ptMaxSize;
        }
        else
        {
            mmi.ptMaxPosition = lastGoodMaxPosition;
            mmi.ptMaxSize = lastGoodMaxSize;
            mmi.ptMaxTrackSize = lastGoodMaxTrackSize;
        }
        mmi = AdjustWorkingAreaForAutoHide(monitorContainingApplication, mmi);
    }

    Marshal.StructureToPtr(mmi, lParam, true);
}
mt-pile
  • 13
  • 7
  • Can you post your code for WmGetMinMaxInfo? – Keithernet Jul 14 '20 at 18:36
  • WindowStyle="None" WindowState="Maximized" ResizeMode="NoResize" follow the link https://stackoverflow.com/questions/35009880/how-to-make-full-screen-mode-without-covering-the-taskbar-using-wpf-c-sharp/35010001 – LDS Jul 14 '20 at 18:59
  • I have just edit that @Keithernet and NoResize parameter don't change the issue unfortunately – mt-pile Jul 16 '20 at 09:21

1 Answers1

1

I have a custom window control that I wrote many years ago. It is still being used actively. Windows are handled properly no matter which display they are on and what the individual DPI is.

Here is my implementation of WmGetMinMaxInfo.

I hope this is helpful.

private void WmGetMinMaxInfo(IntPtr hwnd, IntPtr lParam)
{
    var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
    var hMonitor = Win32.MonitorFromWindow(hwnd, 1);
    
    if (hMonitor != IntPtr.Zero)
    {
        var monitorInfo = new Win32.MONITORINFO();
        
        Win32.GetMonitorInfo(hMonitor, monitorInfo);
        
        var rcWorkArea = monitorInfo.rcWork;
        var rcMonitorArea = monitorInfo.rcMonitor;
        
        mmi.ptMaxPosition.x = Math.Abs(rcWorkArea.Left - rcMonitorArea.Left);
        mmi.ptMaxPosition.y = Math.Abs(rcWorkArea.Top - rcMonitorArea.Top);
        
        mmi.ptMaxSize.x = Math.Abs(rcWorkArea.Right - rcWorkArea.Left);
        mmi.ptMaxSize.y = Math.Abs(rcWorkArea.Bottom - rcWorkArea.Top);
        
        mmi.ptMinTrackSize.x = (int)(minWidth * hidpiX);
        mmi.ptMinTrackSize.y = (int)(minHeight * hidpiY);

        var window = (Window)HwndSource.FromHwnd(hwnd)?.RootVisual;

        if (window != null)
        {
            if (window.WindowState != WindowState.Minimized)
            {
                mmi.ptMaxTrackSize.x = Win32.GetSystemMetrics(Win32.SystemMetric.SM_CXVIRTUALSCREEN);
                mmi.ptMaxTrackSize.y = Win32.GetSystemMetrics(Win32.SystemMetric.SM_CYVIRTUALSCREEN);
                
                lastGoodMaxTrackSize = mmi.ptMaxTrackSize;
            }
            else if (lastGoodMaxTrackSize.x > 0 && lastGoodMaxTrackSize.y > 0)
            {
                mmi.ptMaxTrackSize = lastGoodMaxTrackSize;
            }
        }
    
        mmi = AdjustWorkingAreaForAutoHide(hMonitor, mmi);
    }

    Marshal.StructureToPtr(mmi, lParam, true);
}

For hidpiX and hidpiY, I get those in a handler for the OnSourceInitialized event.

private void OnSourceInitialized(object sender, EventArgs e)
{
    ...

    var source = PresentationSource.FromVisual((Visual)sender);

    if (source == null) return;

    // Get the X and Y HiDPI factors from the media matrix
    if (source.CompositionTarget != null)
    {
        hidpiX = source.CompositionTarget.TransformToDevice.M11;
        hidpiY = source.CompositionTarget.TransformToDevice.M22;
    }

    ...
}

Keithernet
  • 2,349
  • 1
  • 10
  • 16
  • Hi Keithernet, Just tried your solution and the issue is always here. When I maximize the window on the secondary screen, It'll take all the screen and not only the secondary resolution because we use virtualscreen. When you use my solution it's work on the secondary screen. But when you click on taskbar icon for minimize and click again on the icon. The window don't back up with maximized size. just with fixed width and height. – mt-pile Jul 29 '20 at 13:13
  • I have solve my issue and edited my question up there. Thank for your support @Keithernet. – mt-pile Jul 29 '20 at 15:17
  • Hi @Keithernet, I'm just adapt my solution (for HiDpi) with yours and it's work fine now. Thank to you – mt-pile Nov 30 '20 at 15:59