我想为WPF启用
SnapLayout
,因为我使用自定义窗口,根据文档,我必须自己做。
对于 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
显示良好,但最大化按钮不起作用,如果我单击它,旁边会创建一个按钮。我该如何解决这个问题?
更新: 这是完整的代码并且工作正常(没有任何问题(鼠标悬停,单击,...))
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。
我建议使用ControlzEx WindowChromeBehavior,它就像一个魅力,完全支持对齐布局。
我还创建了一个基于 ControlzEx 的完全工作的自定义窗口标题栏示例。 代码示例