在WPF应用程序中支持Windows 11 Snap布局

c90pui9n  于 12个月前  发布在  Windows
关注(0)|答案(1)|浏览(120)

我想为WPF启用SnapLayout,因为我使用自定义窗口,根据documentation,我必须自己做。
对于Win32应用程序,请确保您对WM_NCHITTEST进行了适当的响应(最大化/恢复按钮的返回值为HTMAXBUTTON)。   
我使用了以下代码

private const int HTMAXBUTTON = 9;
private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wparam,
    IntPtr lparam, ref bool handled)
{
    switch (msg)
    {
        case InteropValues.WM_NCHITTEST:
        try
        {
            int x = lparam.ToInt32() & 0xffff;
            int y = lparam.ToInt32() >> 16;
            var rect = new Rect(_ButtonMax.PointToScreen(
                new Point()),
                new Size(_ButtonMax.Width, _ButtonMax.Height));
            if (rect.Contains(new Point(x, y)))
            {
                handled = true;
            }
            return new IntPtr(HTMAXBUTTON);
        }
        catch (OverflowException)
        {
            handled = true;
        }
        break;
    }
    return IntPtr.Zero;
}

字符串
SnapLayout显示得很好,但是最大化按钮不起作用,如果我点击它,它旁边会创建一个按钮。我如何解决这个问题?
x1c 0d1x的数据

nzrxty8p

nzrxty8p1#

更新:这是完整的代码,工作正常(没有任何问题(鼠标悬停,点击,.))

private const double DPI_SCALE = 1.5;
private const int HTMAXBUTTON = 9;

private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam, ref bool handled)
{
    switch (msg)
    {
        
        case 0x0084:
            try
            {
                int x = lparam.ToInt32() & 0xffff;
                    int y = lparam.ToInt32() >> 16;
                    Button _button;
                    if (WindowState == WindowState.Maximized)
                    {
                        _button = _ButtonRestore;
                    }
                    else
                    {
                        _button = _ButtonMax;
                    }
                    var rect = new Rect(_button.PointToScreen(
                        new Point()),
                        new Size(_button.Width * DPI_SCALE, _button.Height * DPI_SCALE));
                    if (rect.Contains(new Point(x, y)))
                    {
                        handled = true;
                        _button.Background = OtherButtonHoverBackground;
                    }
                    else
                    {
                        _button.Background = OtherButtonBackground;
                    }
                    return new IntPtr(HTMAXBUTTON);
            }
            catch (OverflowException)
            {
                handled = true;
            }
            break;
        case 0x00A1:
                int x = lparam.ToInt32() & 0xffff;
                int y = lparam.ToInt32() >> 16;
                Button _button;
                if (WindowState == WindowState.Maximized)
                {
                    _button = _ButtonRestore;
                }
                else
                {
                    _button = _ButtonMax;
                }
                var rect = new Rect(_button.PointToScreen(
                    new Point()),
                    new Size(_button.Width * DPI_SCALE, _button.Height * DPI_SCALE));
                if (rect.Contains(new Point(x, y)))
                {
                    handled = true;
                    IInvokeProvider invokeProv = new ButtonAutomationPeer(_button).GetPattern(PatternInterface.Invoke) as IInvokeProvider;
                    invokeProv?.Invoke();
                }
            break;
        default:
            handled = false;
            break;
    }

    return IntPtr.Zero;
}

字符串
您需要定义ButtonHoverBackgroundButtonHoverBackground或替换为SolidColorBrush。

相关问题