I'm working on a class derived from the WPF Window
class that behaves as an application toolbar window called AppBarWindow
. I have been able to find various WinForms implementations, but no WPF implementations.
I've got a lot of the code working, but I need to know when the user starts dragging the window around the screen and when they stop, as the window's behavior will differ. The default WPF handling isn't quite right, so I've implemented my own Window Procedure and installed it using an HwndSource
object.
I've got this working in an application at work that does not have a non-client area. In that case, there's a LeftMouseButtonDown
event handler that sets a flag to true, then calls the DragMove
method which drags the window around. When that method returns, I set the flag to false. Everything works.
But I'm working now on a general class that won't use the DragMove
method. I can add another LeftMouseButtonDown
handler for the window, but I don't believe that will get called if the mouse is in the non-client area.
How am I going to detect that the user is dragging the window and when they've stopped in this case?
I've found what I needed to know by monitoring the messages sent to my window from Win32 while dragging it.
In short, Windows sends the following message when the window starts to move:
WM_ENTERSIZEMOVE
Next, Windows sends the following messages to my window procedure in sequence:
These are followed with a message whose code is 0xc310. This is not documented anywhere, so I'm guessing this is used internally by .NET / WPF.
These 6 messages are sent repeatedly as the mouse moves and the window follows after it.
Finally, when you release the left mouse button, Windows sends:
So I need to listen for the WM_ENTERSIZEMOVE and WM_EXITSIZEMOVE messages.
wont Window.LocationChanged
event help you in this case.
http://msdn.microsoft.com/en-us/library/system.windows.window.locationchanged.aspx
As Tony points out, there are a few windows messages involved in window dragging. Here's an enum that might help:
internal enum WindowsMessage
{
/// <summary>Sent after a window has been moved.</summary>
WM_MOVE = 0x0003,
/// <summary>
/// Sent to a window when the size or position of the window is about to change.
/// An application can use this message to override the window's default maximized size and position,
/// or its default minimum or maximum tracking size.
/// </summary>
WM_GETMINMAXINFO = 0x0024,
/// <summary>
/// Sent to a window whose size, position, or place in the Z order is about to change as a result
/// of a call to the SetWindowPos function or another window-management function.
/// </summary>
WM_WINDOWPOSCHANGING = 0x0046,
/// <summary>
/// Sent to a window whose size, position, or place in the Z order has changed as a result of a
/// call to the SetWindowPos function or another window-management function.
/// </summary>
WM_WINDOWPOSCHANGED = 0x0047,
/// <summary>
/// Sent to a window that the user is moving. By processing this message, an application can monitor
/// the position of the drag rectangle and, if needed, change its position.
/// </summary>
WM_MOVING = 0x0216,
/// <summary>
/// Sent once to a window after it enters the moving or sizing modal loop. The window enters the
/// moving or sizing modal loop when the user clicks the window's title bar or sizing border, or
/// when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the wParam
/// parameter of the message specifies the SC_MOVE or SC_SIZE value. The operation is complete
/// when DefWindowProc returns.
/// <para />
/// The system sends the WM_ENTERSIZEMOVE message regardless of whether the dragging of full windows
/// is enabled.
/// </summary>
WM_ENTERSIZEMOVE = 0x0231,
/// <summary>
/// Sent once to a window once it has exited moving or sizing modal loop. The window enters the
/// moving or sizing modal loop when the user clicks the window's title bar or sizing border, or
/// when the window passes the WM_SYSCOMMAND message to the DefWindowProc function and the
/// wParam parameter of the message specifies the SC_MOVE or SC_SIZE value. The operation is
/// complete when DefWindowProc returns.
/// </summary>
WM_EXITSIZEMOVE = 0x0232
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With