private void OwnedForm_Moving(object sender, MoveResizeEventArgs e) { if (m_snapGrid != null) { m_snapGrid.SnapWhileMoving(e, ref m_rectangleBeforeSizeMove, MaxSnapDistance, InsensitiveBorderEndLength); } }
private void MdiChild_Moving(object sender, MoveResizeEventArgs e) { if (m_snapGrid != null) { // Check if the MDI client rectangle changed during move/resize, because the client area may show or hide scrollbars during sizing/moving of the window. CheckUpdateSizeMove(); m_snapGrid.SnapWhileMoving(e, ref m_rectangleBeforeSizeMove, MaxSnapDistance, InsensitiveBorderEndLength); } }
protected override void WndProc(ref Message m) { if (m.Msg == WM.SIZING) { // Marshal the size/move rectangle from the message. RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); var e = new ResizeEventArgs(rc, (ResizeMode)m.WParam.ToInt32()); OnResizing(e); // Marshal back the result. Marshal.StructureToPtr(e.MoveResizeRect, m.LParam, true); } else if (m.Msg == WM.MOVING) { // Marshal the size/move rectangle from the message. RECT rc = (RECT)Marshal.PtrToStructure(m.LParam, typeof(RECT)); // Add displacement resulting from continuous updates by OnMoving(). rc.Left += m_displacement.X; rc.Top += m_displacement.Y; rc.Right += m_displacement.X; rc.Bottom += m_displacement.Y; var e = new MoveResizeEventArgs(rc); OnMoving(e); // Calculate new displacement for the next WndProc() iteration. m_displacement.X = rc.Left - e.MoveResizeRect.Left; m_displacement.Y = rc.Top - e.MoveResizeRect.Top; // Marshal back the result. Marshal.StructureToPtr(e.MoveResizeRect, m.LParam, true); } base.WndProc(ref m); }
/// <summary> /// Modifies a <see cref="MoveResizeEventArgs"/> so a window will snap to segments /// defined in this <see cref="SnapGrid"/> while it's being moved. /// </summary> /// <param name="e"> /// The <see cref="MoveResizeEventArgs"/> to modify. /// </param> /// <param name="rectangleBeforeSizeMove"> /// The bounds of the rectangle of the window before it was being moved. /// </param> /// <param name="maxSnapDistance"> /// The maximum distance from a line segment within which the window will snap to a line segment. /// </param> /// <param name="cutoff"> /// The length to cut off both ends of line segments representing the edges of the window being moved. /// </param> public void SnapWhileMoving(MoveResizeEventArgs e, ref Rectangle rectangleBeforeSizeMove, int maxSnapDistance, int cutoff) { // Evaluate left/right borders, then top/bottom borders. // Create line segments for each border of the rectangle. LineSegment leftBorder = LeftEdge(ref e.MoveResizeRect, cutoff); LineSegment rightBorder = RightEdge(ref e.MoveResizeRect, cutoff); if (null != leftBorder && null != rightBorder) { // Initialize snap threshold. int snapThresholdX = maxSnapDistance + 1; // Preserve original width of the rectangle. int originalWidth = rectangleBeforeSizeMove.Width; // Check vertical segments to snap against. foreach (LineSegment verticalSegment in VerticalSegments) { if (leftBorder.SnapSensitive(ref snapThresholdX, verticalSegment)) { // Snap left border, preserve original width. e.MoveResizeRect.Left = verticalSegment.Position; e.MoveResizeRect.Right = verticalSegment.Position + originalWidth; } if (rightBorder.SnapSensitive(ref snapThresholdX, verticalSegment)) { // Snap right border, preserve original width. e.MoveResizeRect.Left = verticalSegment.Position - originalWidth; e.MoveResizeRect.Right = verticalSegment.Position; } } } // Create line segments for each border of the rectangle. LineSegment topBorder = TopEdge(ref e.MoveResizeRect, cutoff); LineSegment bottomBorder = BottomEdge(ref e.MoveResizeRect, cutoff); if (null != topBorder && null != bottomBorder) { // Initialize snap threshold. int snapThresholdY = maxSnapDistance + 1; // Preserve original height of the rectangle. int originalHeight = rectangleBeforeSizeMove.Height; // Check horizontal segments to snap against. foreach (LineSegment horizontalSegment in HorizontalSegments) { if (topBorder.SnapSensitive(ref snapThresholdY, horizontalSegment)) { // Snap top border, preserve original height. e.MoveResizeRect.Top = horizontalSegment.Position; e.MoveResizeRect.Bottom = horizontalSegment.Position + originalHeight; } if (bottomBorder.SnapSensitive(ref snapThresholdY, horizontalSegment)) { // Snap bottom border, preserve original height. e.MoveResizeRect.Top = horizontalSegment.Position - originalHeight; e.MoveResizeRect.Bottom = horizontalSegment.Position; } } } }
/// <summary> /// Raises the <see cref="Moving"/> event. /// </summary> /// <param name="e"> /// The <see cref="MoveResizeEventArgs"/> containing the event data. /// </param> protected virtual void OnMoving(MoveResizeEventArgs e) => Moving?.Invoke(this, e);