gpt4 book ai didi

wpf - 使用 WindowStyle=None 正确最大化 WPF 窗口

转载 作者:行者123 更新时间:2023-12-03 21:04:00 32 4
gpt4 key购买 nike

使用 WindowStyle=None 选项时,WPF 窗口有两个问题。

  • 窗口最大化时覆盖任务栏。
  • 一旦最大化,窗口就不能向下拖动以取消最大化。

  • 如何纠正这些问题?
    最好不使用 Windows.Forms。

    最佳答案

    这些问题网上还有其他答案。然而,他们都没有考虑到该解决方案将如何在具有多个显示器的设置上执行。特别是如果主显示器不是设置中的最左侧。

    我设计此代码时考虑了单显示器和多显示器设置。

    此解决方案也适用 不是 引入 Windows.Forms 作为引用,它使用非托管调用。

    XAML

    <Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Background="AliceBlue" WindowStyle="None" Height="350" Width="525" SourceInitialized="Window_SourceInitialized">
    <Grid>
    <Rectangle Name="rctHeader" Height="40" VerticalAlignment="Top" Fill="CadetBlue" PreviewMouseLeftButtonDown="rctHeader_PreviewMouseLeftButtonDown" PreviewMouseLeftButtonUp="rctHeader_PreviewMouseLeftButtonUp" PreviewMouseMove="rctHeader_PreviewMouseMove"/>
    </Grid>
    </Window>

    隐藏代码
    using System.Runtime.InteropServices;
    using System.Windows.Interop;

    private bool mRestoreIfMove = false;


    public MainWindow()
    {
    InitializeComponent();
    }


    void Window_SourceInitialized(object sender, EventArgs e)
    {
    IntPtr mWindowHandle = (new WindowInteropHelper(this)).Handle;
    HwndSource.FromHwnd(mWindowHandle).AddHook(new HwndSourceHook(WindowProc));
    }


    private static System.IntPtr WindowProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
    switch (msg)
    {
    case 0x0024:
    WmGetMinMaxInfo(hwnd, lParam);
    break;
    }

    return IntPtr.Zero;
    }


    private static void WmGetMinMaxInfo(System.IntPtr hwnd, System.IntPtr lParam)
    {
    POINT lMousePosition;
    GetCursorPos(out lMousePosition);

    IntPtr lPrimaryScreen = MonitorFromPoint(new POINT(0, 0), MonitorOptions.MONITOR_DEFAULTTOPRIMARY);
    MONITORINFO lPrimaryScreenInfo = new MONITORINFO();
    if (GetMonitorInfo(lPrimaryScreen, lPrimaryScreenInfo) == false)
    {
    return;
    }

    IntPtr lCurrentScreen = MonitorFromPoint(lMousePosition, MonitorOptions.MONITOR_DEFAULTTONEAREST);

    MINMAXINFO lMmi = (MINMAXINFO)Marshal.PtrToStructure(lParam, typeof(MINMAXINFO));

    if (lPrimaryScreen.Equals(lCurrentScreen) == true)
    {
    lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcWork.Left;
    lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcWork.Top;
    lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcWork.Right - lPrimaryScreenInfo.rcWork.Left;
    lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcWork.Bottom - lPrimaryScreenInfo.rcWork.Top;
    }
    else
    {
    lMmi.ptMaxPosition.X = lPrimaryScreenInfo.rcMonitor.Left;
    lMmi.ptMaxPosition.Y = lPrimaryScreenInfo.rcMonitor.Top;
    lMmi.ptMaxSize.X = lPrimaryScreenInfo.rcMonitor.Right - lPrimaryScreenInfo.rcMonitor.Left;
    lMmi.ptMaxSize.Y = lPrimaryScreenInfo.rcMonitor.Bottom - lPrimaryScreenInfo.rcMonitor.Top;
    }

    Marshal.StructureToPtr(lMmi, lParam, true);
    }


    private void SwitchWindowState()
    {
    switch (WindowState)
    {
    case WindowState.Normal:
    {
    WindowState = WindowState.Maximized;
    break;
    }
    case WindowState.Maximized:
    {
    WindowState = WindowState.Normal;
    break;
    }
    }
    }


    private void rctHeader_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
    if (e.ClickCount == 2)
    {
    if ((ResizeMode == ResizeMode.CanResize) || (ResizeMode == ResizeMode.CanResizeWithGrip))
    {
    SwitchWindowState();
    }

    return;
    }

    else if (WindowState == WindowState.Maximized)
    {
    mRestoreIfMove = true;
    return;
    }

    DragMove();
    }


    private void rctHeader_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
    mRestoreIfMove = false;
    }


    private void rctHeader_PreviewMouseMove(object sender, MouseEventArgs e)
    {
    if (mRestoreIfMove)
    {
    mRestoreIfMove = false;

    double percentHorizontal = e.GetPosition(this).X / ActualWidth;
    double targetHorizontal = RestoreBounds.Width * percentHorizontal;

    double percentVertical = e.GetPosition(this).Y / ActualHeight;
    double targetVertical = RestoreBounds.Height * percentVertical;

    WindowState = WindowState.Normal;

    POINT lMousePosition;
    GetCursorPos(out lMousePosition);

    Left = lMousePosition.X - targetHorizontal;
    Top = lMousePosition.Y - targetVertical;

    DragMove();
    }
    }

    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool GetCursorPos(out POINT lpPoint);


    [DllImport("user32.dll", SetLastError = true)]
    static extern IntPtr MonitorFromPoint(POINT pt, MonitorOptions dwFlags);

    enum MonitorOptions : uint
    {
    MONITOR_DEFAULTTONULL = 0x00000000,
    MONITOR_DEFAULTTOPRIMARY = 0x00000001,
    MONITOR_DEFAULTTONEAREST = 0x00000002
    }


    [DllImport("user32.dll")]
    static extern bool GetMonitorInfo(IntPtr hMonitor, MONITORINFO lpmi);


    [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;
    };


    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
    public 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)]
    public struct RECT
    {
    public int Left, Top, Right, Bottom;

    public RECT(int left, int top, int right, int bottom)
    {
    this.Left = left;
    this.Top = top;
    this.Right = right;
    this.Bottom = bottom;
    }
    }

    关于wpf - 使用 WindowStyle=None 正确最大化 WPF 窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20941443/

    32 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com