gpt4 book ai didi

c# - 挂接到 WPF 窗口中的 Windows 消息循环会在内部添加白色边框

转载 作者:可可西里 更新时间:2023-11-01 03:10:14 25 4
gpt4 key购买 nike

我正在尝试创建一个带有 WindowStyle="None" 的 WPF 窗口(用于自定义按钮,没有标题),无法调整大小。将 ResizeMode 设置为 NoResize 会删除我想要保留的航空边框。

我可以设置最小/最大大小属性并完成它,除了:

  1. 调整光标仍然可见,并且
  2. 显示窗口是为了响应用户操作并适合其内容。它显示图像,因此大小会发生变化。

所以,我有一个简单的方案,可以让我完成 99% 的工作:

public class BorderedWindowNoResize : Window
{
[DllImport( "DwmApi.dll" )]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hwnd,
ref MARGINS pMarInset );

[DllImport( "user32.dll", CharSet = CharSet.Auto )]
public static extern IntPtr DefWindowProc(
IntPtr hWnd,
int msg,
IntPtr wParam,
IntPtr lParam );

public BorderedWindowNoResize()
{
Loaded += BorderedWindowNoResize_Loaded;
}

private void BorderedWindowNoResize_Loaded( object sender, RoutedEventArgs e )
{
IntPtr mainWindowPtr = new WindowInteropHelper( this ).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd( mainWindowPtr );
mainWindowSrc.AddHook( WndProc );
}

private IntPtr WndProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
{
var htLocation = DefWindowProc( hwnd, msg, wParam, lParam ).ToInt32();

if( msg == (uint)WM.NCHITTEST )
{
handled = true;
switch( htLocation )
{
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
}

return new IntPtr( htLocation );
}
}

基本上;

  1. 覆盖窗口过程。
  2. 调用默认窗口过程。
  3. 如果消息是 WM_NCHITTEST,检查边框结果。
  4. 如果是边框,返回常规的HTBORDER

这可以让我保留 aero 窗口边框并隐藏调整大小的光标,但它会在我的窗口内部添加一个约 5 像素的白色边框。

事实上,即使我在 WndPrc 的顶部返回默认的 Windows 过程结果并且什么都不做,边框仍然在那里。我的窗口需要不同的背景颜色,所以这对我不起作用。

有什么想法吗?一如既往地提前致谢。

最佳答案

当你添加你的钩子(Hook)时,你应该只处理你需要的消息,而忽略其他的。我相信您正在处理某些消息两次,因为您调用了 DefWindowProc,但从未将 handled 参数设置为 true。

所以在你的情况下,你会使用:

private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) {

if (msg == (uint)WM.NCHITTEST) {
handled = true;
var htLocation = DefWindowProc(hwnd, msg, wParam, lParam).ToInt32();
switch (htLocation) {
case (int)HitTestResult.HTBOTTOM:
case (int)HitTestResult.HTBOTTOMLEFT:
case (int)HitTestResult.HTBOTTOMRIGHT:
case (int)HitTestResult.HTLEFT:
case (int)HitTestResult.HTRIGHT:
case (int)HitTestResult.HTTOP:
case (int)HitTestResult.HTTOPLEFT:
case (int)HitTestResult.HTTOPRIGHT:
htLocation = (int)HitTestResult.HTBORDER;
break;
}
return new IntPtr(htLocation);
}

return IntPtr.Zero;
}

此外,我可能会在 OnSourceInitialized 中添加钩子(Hook)覆盖,像这样:

protected override void OnSourceInitialized(EventArgs e) {
base.OnSourceInitialized(e);

IntPtr mainWindowPtr = new WindowInteropHelper(this).Handle;
HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
mainWindowSrc.AddHook(WndProc);
}

关于c# - 挂接到 WPF 窗口中的 Windows 消息循环会在内部添加白色边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6365813/

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