WPF禁止窗口移动

20

在wpf中,我如何防止用户通过拖动标题栏移动窗口?

2个回答

42

由于在WPF中无法直接定义 WndProc,您需要获取一个 HwndSource,并向其添加钩子:

public Window1()
{
    InitializeComponent();

    this.SourceInitialized += Window1_SourceInitialized;
}

private void Window1_SourceInitialized(object sender, EventArgs e)
{
    WindowInteropHelper helper = new WindowInteropHelper(this);
    HwndSource source = HwndSource.FromHwnd(helper.Handle);
    source.AddHook(WndProc);    
}

const int WM_SYSCOMMAND = 0x0112;
const int SC_MOVE = 0xF010;

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

   switch(msg)
   {
      case WM_SYSCOMMAND:
          int command = wParam.ToInt32() & 0xfff0;
          if (command == SC_MOVE)
          {
             handled = true;
          }
          break;
      default:
          break;
   }
   return IntPtr.Zero;
}

WndProc 应该返回什么?IntPtr.Zero 吗? - naeron84
1
是的,我忘记了返回值...根据 WM_SYSCOMMAND 的文档:“如果应用程序处理此消息,则应返回零”。 - Thomas Levesque
这太棒了!感谢您的发布。不过,我有一个评论,就是这会使子窗口出现在机器上的每个其他窗口之上。是否可能使其仅出现在父窗口之上? - Avrohom Yisroel
@AvrohomYisroel,这段代码仅仅防止用户移动窗口。也许你的问题是由代码中其他部分引起的... - Thomas Levesque
啊,我真笨!我把两篇帖子的代码结合在一起了,还在错误的帖子上留言了!再次感谢 :) - Avrohom Yisroel
显示剩余2条评论

3

这是一个很老的帖子,虽然现在也有其他技术如UWP和WinUI3,但我的建议或许对其他人也有所帮助。

我通过设置来达到目标:

WindowStyle="None"

在窗口中添加一个按钮并设置:
IsCancel="True"

就是这样,不需要互操作代码。最小化的代码。


为什么这个能够运行?我不明白。 - chris84948
因为没有可见的空间来放置鼠标以拖动它。窗口没有边框或标题..工作完成。 - Boppity Bop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接