防止最大化WPF窗口覆盖任务栏

本文关键字:覆盖 任务栏 窗口 WPF 最大化 | 更新日期: 2023-09-27 18:26:16

我使用Microsoft.Windows.Shell DLL和.NET 4.0在WPF中创建了一个自定义窗口。

问题是,如果任务栏设置为自动隐藏,并且窗口最大化,则窗口会完全覆盖任务栏。我尝试过几种不同的解决方案(最初的几次谷歌搜索结果),但都不起作用。

如果任务栏是而不是自动隐藏的,MahApps.Metro程序包使用的方法会将窗口设置为离屏幕底部1px。

我需要一个的解决方案

  1. 适用于.NET 4.0
  2. 无论任务栏停靠在哪一侧都有效
  3. 当任务栏设置为始终显示和自动隐藏时工作

防止最大化WPF窗口覆盖任务栏

自定义的WPF窗口不尊重任务栏占用的区域。为了做到这一点,您需要Win32 API的支持。

你需要的第一种方法是…

    [DllImport("user32.dll")]
    public static extern IntPtr MonitorFromWindow(IntPtr hwnd, int dwFlags);

MonitorFromWindow函数检索显示监视器的句柄,该句柄与指定窗口的边界矩形相交面积最大。http://msdn.microsoft.com/en-us/library/windows/desktop/dd145064(v=vs.85).aspx

设置dwFlags=2

下一个是…

    [DllImport("user32.dll")]
    public static extern bool GetMonitorInfo(HandleRef hmonitor, 
                       [In, Out] MonitorInfoEx monitorInfo);

GetMonitorInfo函数用于检索有关显示监视器的信息。http://msdn.microsoft.com/en-us/library/windows/desktop/dd144901(v=vs.85).aspx

MonitorInfoEx结构看起来像。。。

    [StructLayout(LayoutKind.Sequential)]
    public class MonitorInfoEx
    {
        public int cbSize;
        public Rect rcMonitor;     
        public Rect rcWork;        
        public int dwFlags;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x20)]
        public char[] szDevice;
    }

MONITORINFOEX结构包含有关显示监视器的信息。http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066(v=vs.85).aspx

正在通过的Rect是…

    [StructLayout(LayoutKind.Sequential)]
    public struct Rect
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

这里特别感兴趣的是,您正在以DPI的当前分辨率获取工作区域

最后,您需要PresentationCore(WPF)的Interop命名空间中的HwndSource.FromHwnd方法

将所有信息汇总在一起后,可以使用CompositionTarget.TransformFromDevice…获取一个矩阵,该矩阵可用于将坐标从渲染目标设备转换为此目标。http://msdn.microsoft.com/en-us/library/system.windows.media.compositiontarget.transformfromdevice.aspx

这将为您提供定位自定义窗口所需的尺寸,使其尊重状态栏。