Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LocationChanged is not reliably called when Window is being dragged

Tags:

c#

wpf

To implement docking I was relying on listening to the Window.LocationChanged event to detect the changing position of a window being dragged around the screen. But a user reported that docking was not working on their machine.

Turns out they had disabled "Show window contents while dragging" in Windows performance options and as a result the LocationChanged event is only fired once the window is moved to it's final position, not while the window is in mid-flight.

I was wondering if there was an alternative way to detect window moves, a nice way. I know I could pinvoke, or wire up some horrific timer, but I was hoping for a better way, perhaps there is a reliable event to listen on?

Here's a method to forestall any "you didn't post any code"/"what have you tried" complaints.

protected override void OnLocationChanged(EventArgs e)
{

}
like image 798
Weyland Yutani Avatar asked Oct 20 '22 22:10

Weyland Yutani


1 Answers

Here's my solution,

Excellent work.

class MyWindow : Window
{
    private const int WM_MOVING = 0x0216;
    private HwndSource _hwndSrc;
    private HwndSourceHook _hwndSrcHook;

    public MyWindow()
    {
        Loaded += OnLoaded;
        Unloaded += OnUnloaded;
    }

    void OnUnloaded(object sender, RoutedEventArgs e)
    {
        _hwndSrc.RemoveHook(_hwndSrcHook);
        _hwndSrc.Dispose();
        _hwndSrc = null;
    }

    void OnLoaded(object sender, RoutedEventArgs e)
    {
        _hwndSrc = HwndSource.FromDependencyObject(this) as HwndSource;
        _hwndSrcHook = FilterMessage;
        _hwndSrc.AddHook(_hwndSrcHook);
    }

    private IntPtr FilterMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        switch (msg)
        {
            case WM_MOVING:
                OnLocationChange();
                break;
        }

        return IntPtr.Zero;
    }

    private void OnLocationChange()
    {
        //Do something
    }
}
like image 103
Ya'akov Ofek Avatar answered Oct 22 '22 12:10

Ya'akov Ofek