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

时间:2013-08-04 21:20:22

标签: c# wpf xaml events taskbar

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

问题是如果任务栏设置为自动隐藏并且窗口最大化,则窗口完全覆盖任务栏。我尝试了几种不同的解决方案(前几个谷歌搜索结果),但没有一个真正有用。

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

我需要一个解决方案

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

1 个答案:

答案 0 :(得分:2)

自定义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

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