简体   繁体   English

单击任务栏图标 wpf 时在辅助显示器上正确调整大小

[英]resize correctly on secondary monitor when clicking on taskbar icon wpf

I have a wpf application and I manage max sizing with WmGetMinMaxInfo:我有一个 wpf 应用程序,我使用 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:我的 window 设置为:

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.当我在最大化 state 最小化应用程序时,当我在任务栏图标上单击返回以返回最大化 window 应用程序时,我遇到了一个奇怪的问题。

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? Windows特点? There is any work around?有什么解决办法吗?

SOLUTION: I have solved my issue with the idea of Keithernet to not recalculate when the windowState are minimized.解决方案:我已经用 Keithernet 的想法解决了我的问题,即当 windowState 最小化时不重新计算。 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);
}

I have a custom window control that I wrote many years ago.我有一个多年前编写的自定义 window 控件。 It is still being used actively.它仍在积极使用中。 Windows are handled properly no matter which display they are on and what the individual DPI is. Windows 无论在哪个显示器上以及单个 DPI 是多少,都可以正确处理。

Here is my implementation of WmGetMinMaxInfo .这是我的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.对于 hidpiX 和 hidpiY,我将它们放在OnSourceInitialized事件的处理程序中。

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;
    }

    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM