我正在开发一个WPF应用程序。我完全摆脱了标准的Windows边框,并通过将WindowStyle设置为None并将allowsTransparency设置为true来创建我自己的边框。唯一的问题是,当窗口最大化时,它会填满整个屏幕,覆盖任务栏。有没有办法在没有这种情况下创建自己的边界?
答案 0 :(得分:1)
使用方法CompatibilityMaximizedNoneWindow。
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using Point = System.Drawing.Point;
internal static class WindowExtensions
{
public static PointF StandartDPI = new PointF(96f, 96f);
private static PointF? currentDpi = null;
public static float WidthZoom {get{return CurrentDPI.X/ StandartDPI.X; } }
public static float HeigthZoom { get { return CurrentDPI.Y / StandartDPI.Y; } }
public static PointF CurrentDPI
{
get
{
if (!currentDpi.HasValue)
{
var wiHelper = new WindowInteropHelper(App.Current.MainWindow);
Graphics g = Graphics.FromHwnd(wiHelper.Handle);
try
{
currentDpi = new PointF(g.DpiX, g.DpiY);
}
catch
{
currentDpi = StandartDPI;
}
finally
{
g.Dispose();
}
}
return currentDpi.Value;
}
}
public static Window GetWindowFromTemplate(this object templateFrameworkElement)
{
var window = ((FrameworkElement)templateFrameworkElement).TemplatedParent as Window;
return window;
}
private static int minWidth;
private static int minHeight;
public static void CompatibilityMaximizedNoneWindow(this Window window)
{
var wiHelper = new WindowInteropHelper(window);
minHeight = (int)window.MinHeight;
minWidth = (int)window.MinWidth;
var handle = wiHelper.Handle;
var hwndSource = HwndSource.FromHwnd(handle);
if (hwndSource != null)
{
hwndSource.AddHook(CompatibilityMaximizedNoneWindowProc);
}
}
[DllImport("user32")]
private static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);[DllImport("user32")]
private static extern IntPtr MonitorFromWindow(IntPtr handle, int flags);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
private class MONITORINFO
{
public int cbSize = Marshal.SizeOf(typeof(MONITORINFO));
public RECT rcMonitor = new RECT();
public RECT rcWork = new RECT();
public int dwFlags = 0;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int x;
public int y;
public POINT(int x, int y)
{
this.x = x; this.y = y;
}
}
[StructLayout(LayoutKind.Sequential)]
private struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
private static IntPtr CompatibilityMaximizedNoneWindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
const int WM_GETMINMAXINFO = 0x0024;
const int MONITOR_DEFAULTTONEAREST = 0x00000002;
switch (msg)
{
case WM_GETMINMAXINFO:
var mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
var monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitor != IntPtr.Zero)
{
var monitorInfo = new MONITORINFO();
GetMonitorInfo(monitor, 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);
//Hack для ограничения минимальных размеров окна
mmi.ptMinTrackSize.x = (int)(minWidth*WidthZoom);
mmi.ptMinTrackSize.y = (int)(minHeight*HeigthZoom);
//Hack для нормальной работы всплывающей панели задач
var taskbar = new TaskbarInfo();
if (taskbar.AutoHide)
{
switch (taskbar.Position)
{
case TaskbarInfo.TaskbarPosition.Top:
mmi.ptMaxPosition.y++;
mmi.ptMaxSize.y--;
break;
case TaskbarInfo.TaskbarPosition.Bottom:
mmi.ptMaxPosition.y--;
mmi.ptMaxSize.y--;
break;
case TaskbarInfo.TaskbarPosition.Left:
mmi.ptMaxPosition.x++;
mmi.ptMaxSize.x--;
break;
case TaskbarInfo.TaskbarPosition.Right:
mmi.ptMaxPosition.x--;
mmi.ptMaxSize.x--;
break;
}
}
}
Marshal.StructureToPtr(mmi, lParam, true); handled = true; break;
}
return (IntPtr)0;
}
}
答案 1 :(得分:1)
更简单的方法,在你的窗口构造函数中设置
this.MaxHeight = SystemParameters.MaximizedPrimaryScreenHeight;
并且窗口不会覆盖任务栏。
答案 2 :(得分:0)
看看Microsoft.Windows.Shell。它为你做了所有这一切。追踪它有点令人沮丧。我认为最好使用的是latest ribbon control附带的内容。