在 WPF 应用程序中支持 Windows 11 Snap Layout
Support Windows 11 Snap Layout in WPF app
我想为WPF启用SnapLayout
,因为我使用自定义Window,根据documentation,我必须自己做。
For Win32 apps, make sure you are responding appropriately to
WM_NCHITTEST (with a return value of HTMAXBUTTON for
the maximize/restore button).
我使用了下面的代码
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
显示良好但是最大化按钮不起作用,如果我点击它,旁边会创建一个按钮。我该如何解决这个问题?
更新:
这是完整的代码并且工作正常(没有任何问题(鼠标悬停、单击、...))
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;
}
您需要定义 OtherButtonHoverBackground 和 OtherButtonBackground 或替换为 SolidColorBrush。
我想为WPF启用SnapLayout
,因为我使用自定义Window,根据documentation,我必须自己做。
For Win32 apps, make sure you are responding appropriately to WM_NCHITTEST (with a return value of HTMAXBUTTON for the maximize/restore button).
我使用了下面的代码
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
显示良好但是最大化按钮不起作用,如果我点击它,旁边会创建一个按钮。我该如何解决这个问题?
更新: 这是完整的代码并且工作正常(没有任何问题(鼠标悬停、单击、...))
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;
}
您需要定义 OtherButtonHoverBackground 和 OtherButtonBackground 或替换为 SolidColorBrush。