我使用Microsoft.Windows.Shell
DLL和.NET 4.0在WPF中创建了一个自定义窗口。
问题是如果任务栏设置为自动隐藏并且窗口最大化,则窗口完全覆盖任务栏。我尝试了几种不同的解决方案(前几个谷歌搜索结果),但没有一个真正有用。
如果任务栏不自动隐藏,MahApps.Metro
包使用的方法会将窗口1px设置为偏离屏幕底部。
我需要一个解决方案
答案 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
...这将为您提供定位自定义窗口所需的尺寸,使其尊重状态栏。