protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
((HwndSource)PresentationSource.FromVisual(this)).AddHook(HookProc);
}
public static IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
if (msg == WM_GETMINMAXINFO)
{
// We need to tell the system what our size should be when maximized. Otherwise it will
// cover the whole screen, including the task bar.
MINMAXINFO mmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));
// Adjust the maximized size and position to fit the work area of the correct monitor
IntPtr monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (monitor != IntPtr.Zero)
{
MONITORINFO monitorInfo = new MONITORINFO();
monitorInfo.cbSize = Marshal.SizeOf(typeof(MONITORINFO));
GetMonitorInfo(monitor, ref 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);
}
Marshal.StructureToPtr(mmi, lParam, true);
}
return IntPtr.Zero;
}
private const int WM_GETMINMAXINFO = 0x0024;
private const uint MONITOR_DEFAULTTONEAREST = 0x00000002;
[DllImport("user32.dll")]
private static extern IntPtr MonitorFromWindow(IntPtr handle, uint flags);
[DllImport("user32.dll")]
private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
public RECT(int left, int top, int right, int bottom)
{
this.Left = left;
this.Top = top;
this.Right = right;
this.Bottom = bottom;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MONITORINFO
{
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public uint dwFlags;
}
[Serializable]
[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
public int X;
public int Y;
public POINT(int x, int y)
{
this.X = x;
this.Y = y;
}
}
[StructLayout(LayoutKind.Sequential)]
public struct MINMAXINFO
{
public POINT ptReserved;
public POINT ptMaxSize;
public POINT ptMaxPosition;
public POINT ptMinTrackSize;
public POINT ptMaxTrackSize;
}
6条答案
按热度按时间cpjpxq1n1#
在线上还有其他解决这些问题的方法。但是,它们都没有考虑到解决方案在多显示器设置中的执行情况。特别是如果主显示器不是设置中最左边的。
我设计这段代码时考虑到了单显示器和多显示器的设置。
这个解决方案也不引入Windows.Forms作为参考,它使用非管理调用。
XAML
字符串
代码隐藏
型
kfgdxczn2#
我有一个很好的快速和肮脏的解决方案。尝试以下代码时,最大化你的无边框窗口:
字符串
技巧是将
WindowStyle
设置为SingleBorderWindow
,然后最大化窗口并将其设置回None
。sqserrrh3#
这样一个好代码leebickmtu!
我有一个多个显示器的小问题,在windows 10:因为有一个任务栏在每个屏幕上,如果你最大化你的窗口在辅助屏幕上他的任务栏成为隐藏.
我只是修改了一下这个方法,以便从任何屏幕上获得相对位置:
字符串
希望这对你有帮助…
crcmnpdw4#
leebickmtu的答案基本上是正确的,但有一些无关的代码,并根据光标所在的位置选择监视器,而不是窗口所在的位置。如果鼠标在不同的监视器上,用户按
Win
+Up
来最大化,那么这将产生错误的行为。我们应该使用MonitorFromWindow
来识别要最大化的监视器。在你的窗口代码中添加以下内容:
字符串
unhi4e5o5#
如果只使用一个监视器,另一个简单的方法是设置窗口的最大高度。System.Windows.SystemParameters类提供了一些有用的值,例如PrimaryScreenHeight或MaximizedPrimaryScreenHeight。
在我的示例代码中,我使用MaximizedPrimaryScreenHeight并减去我在WindowChrome中设置的ResizeBorderThickness。
字符串
8fq7wneg6#
基于Dennis的优秀解决方案:
字符串