20

In wpf how can i prevent user from moving the windows by dragging the title bar?

naeron84
  • 2,955
  • 3
  • 30
  • 37

2 Answers2

42

Since you can't define a WndProc directly in WPF, you need to obtain a HwndSource, and add a hook to it :

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;
}
Thomas Levesque
  • 286,951
  • 70
  • 623
  • 758
  • What should WndProc return? IntPtr.Zero? – naeron84 Mar 08 '10 at 12:09
  • It's working, return value doesn't matter. So IntPrt.Zero is just fine. – naeron84 Mar 08 '10 at 12:30
  • 1
    Yes, I forgot the return value... According to the documentation of WM_SYSCOMMAND : "An application should return zero if it processes this message" – Thomas Levesque Mar 08 '10 at 12:45
  • This is brilliant! Thanks for posting it. One comment though, and that is that this makes the child window appear above EVERY other window on the machine. Is it possible to make it so that it's only above the parent? – Avrohom Yisroel May 29 '13 at 16:44
  • @AvrohomYisroel, this code merely prevents the window from being moved by the user. Perhaps your problem is caused by something else in your code... – Thomas Levesque May 29 '13 at 17:38
  • Ah, stupid me! I was combining the code from two posts, and commented on the wrong one! Thanks again :) – Avrohom Yisroel May 29 '13 at 17:51
  • Thanks, this is working for .Net Framework 4.8, just don't forget to add the SourceInitialized event in the window you want to lock. – B. Amine Nov 13 '20 at 14:52
2

Really old thread and other techniques like UWP and WinUI3 are out there but maybe my suggestions are helpful to others.

I achieve the goal by setting

WindowStyle="None"

Add a button to the window and set

IsCancel="True"

That's it. No need for interop code. Minimized code.

Anzu
  • 21
  • 1