我正在处理一个派生自WPF Window
类的类,该类充当名为AppBarWindow
的应用程序工具栏窗口。我已经能够找到各种WinForms实现,但没有WPF实现。
我有很多代码正在运行,但我需要知道用户何时开始在屏幕上拖动窗口以及何时停止,因为窗口的行为会有所不同。默认的WPF处理不太正确,所以我实现了自己的Window Procedure并使用HwndSource
对象安装它。
我在工作中没有非客户区的应用程序中工作。在这种情况下,有一个LeftMouseButtonDown
事件处理程序将标志设置为true,然后调用拖动窗口的DragMove
方法。当该方法返回时,我将标志设置为false。一切正常。
但我现在正在使用一个不使用DragMove
方法的通用类。我可以为窗口添加另一个LeftMouseButtonDown
处理程序,但如果鼠标位于非客户区域,我不相信会被调用。
我如何检测用户是否在拖动窗口以及何时停止这种情况?
答案 0 :(得分:7)
通过监控从Win32发送到我的窗口的消息,我已经找到了我需要知道的内容。
简而言之,Windows在窗口开始移动时发送以下消息:
WM_ENTERSIZEMOVE
接下来,Windows按顺序将以下消息发送到我的窗口过程:
接下来是一条代码为0xc310的消息。这在任何地方都没有记录,所以我猜这是由.NET / WPF内部使用的。
当鼠标移动时会重复发送这6条消息,然后窗口会跟随它。
最后,当您松开鼠标左键时,Windows会发送:
所以我需要监听WM_ENTERSIZEMOVE和WM_EXITSIZEMOVE消息。
答案 1 :(得分:2)
不会Window.LocationChanged
事件帮助你。
http://msdn.microsoft.com/en-us/library/system.windows.window.locationchanged.aspx
答案 2 :(得分:2)
Tony指出,窗口拖动涉及一些Windows消息。这是一个可能有用的枚举:
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
}