c# - मेरे विंडोज़ फॉर्म ऐप को किनारों पर स्क्रीन करने के लिए कैसे स्नैप करें?




windows winforms (4)

बस उस मॉनीटर की वर्तमान पिक्सेल ऊंचाई / चौड़ाई को पुनः प्राप्त करें ...

वर्तमान कर्सर स्थान की सक्रिय मॉनीटर कैसे निर्धारित करें

... और स्थान को बदलने के लिए स्थानांतरित / स्थानांतरित घटनाओं को संसाधित करें। जब आप भीतर आते हैं, तो 25 पिक्सेल या किनारे के किनारे (अपने मुख्य रूप का स्थान। लेफ्ट + फॉर्म चौड़ाई) या ऊंचाई (अपना मुख्य रूप का स्थान। टॉप + फॉर्म ऊंचाई) कहें, फिर आगे बढ़ें और। सेट करें और टैप गुण ताकि आपके आवेदन कोनों में "डॉक्स" हो।

संपादित करें: एक अन्य नोट - जब आप वास्तव में "स्नैपिंग" करते हैं तो आप कर्सर स्थिति को सापेक्ष दूरी को विंडो बार पर उसी बिंदु पर रहने के लिए भी ले जा सकते हैं। अन्यथा आपका फॉर्म कर्सर की स्थिति और आपकी "स्नैपी" कार्यक्षमता के बीच एक विशाल पिंग पोंग बॉल बन सकता है जैसे माउसमोव और फॉर्म लोकेशन एक दूसरे के खिलाफ लड़ाई लड़ते हैं।

वहाँ कोई भी जानता है कि कैसे अपने .NET विंडोज़ फॉर्म ऐप चिपचिपा / Winamp की तरह snappy बनाने के लिए यह स्क्रीन के किनारों पर snaps?

लक्ष्य ढांचा VS08 का उपयोग कर सी # में लिखा गया .NET 2.0 विंडोज फॉर्म होगा। मैं इस कार्यक्षमता को कस्टम उपयोगकर्ता नियंत्रण में जोड़ना चाहता हूं, लेकिन मुझे लगा कि अधिक लोगों को एप्लिकेशन और उसके मुख्य रूप के लिए वर्णित होने से फायदा होगा।

धन्यवाद।


मुझे नहीं पता कि आपको अपना समाधान मिला है, लेकिन मैंने इसके लिए एक छोटा सा घटक बनाया है: http://www.formsnapper.net - यह प्रक्रिया सीमाओं में फैलता है!


स्वीकार्य उत्तर केवल ड्रैग को खत्म करने के बाद विंडो को स्नैप करता है, जबकि मैं ड्रैग करते समय फॉर्म को स्क्रीन किनारों पर लगातार स्नैप करना चाहता था। यहां मेरा समाधान है, जो पेंट.नेट स्रोत कोड से कम है :

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Whatever
{
    /// <summary>
    /// Managed equivalent of the Win32 <code>RECT</code> structure.
    /// </summary>
    [StructLayout(LayoutKind.Sequential)]
    public struct LtrbRectangle
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;

        public LtrbRectangle(int left, int top, int right, int bottom)
        {
            Left = left;
            Top = top;
            Right = right;
            Bottom = bottom;
        }

        public Rectangle ToRectangle()
        {
            return Rectangle.FromLTRB(Left, Top, Right, Bottom);
        }

        public static LtrbRectangle FromRectangle(Rectangle rect)
        {
            return new LtrbRectangle(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
        }

        public override string ToString()
        {
            return "{Left=" + Left + ",Top=" + Top + ",Right=" + Right + ",Bottom=" + Bottom + "}";
        }
    }

    /// <summary>
    /// A form that "snaps" to screen edges when moving.
    /// </summary>
    public class AnchoredForm : Form
    {
        private const int WmEnterSizeMove = 0x0231;
        private const int WmMoving = 0x0216;
        private const int WmSize = 0x0005;

        private SnapLocation _snapAnchor;
        private int _dragOffsetX;
        private int _dragOffsetY;

        /// <summary>
        /// Flags specifying which edges to anchor the form at.
        /// </summary>
        [Flags]
        public enum SnapLocation
        {
            None = 0,
            Left = 1 << 0,
            Top = 1 << 1,
            Right = 1 << 2,
            Bottom = 1 << 3,
            All = Left | Top | Right | Bottom
        }

        /// <summary>
        /// How far from the screen edge to anchor the form.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(10)]
        [Description("The distance from the screen edge to anchor the form.")]
        public virtual int AnchorDistance { get; set; } = 10;

        /// <summary>
        /// Gets or sets how close the form must be to the
        /// anchor point to snap to it. A higher value gives
        /// a more noticable "snap" effect.
        /// </summary>
        [Browsable(true)]
        [DefaultValue(20)]
        [Description("The maximum form snapping distance.")]
        public virtual int SnapDistance { get; set; } = 20;

        /// <summary>
        /// Re-snaps the control to its current anchor points.
        /// This can be useful for re-positioning the form after
        /// the screen resolution changes.
        /// </summary>
        public void ReSnap()
        {
            SnapTo(_snapAnchor);
        }

        /// <summary>
        /// Forces the control to snap to the specified edges.
        /// </summary>
        /// <param name="anchor">The screen edges to snap to.</param>
        public void SnapTo(SnapLocation anchor)
        {
            Screen currentScreen = Screen.FromPoint(Location);
            Rectangle workingArea = currentScreen.WorkingArea;
            if ((anchor & SnapLocation.Left) != 0)
            {
                Left = workingArea.Left + AnchorDistance;
            }
            else if ((anchor & SnapLocation.Right) != 0)
            {
                Left = workingArea.Right - AnchorDistance - Width;
            }
            if ((anchor & SnapLocation.Top) != 0)
            {
                Top = workingArea.Top + AnchorDistance;
            }
            else if ((anchor & SnapLocation.Bottom) != 0)
            {
                Top = workingArea.Bottom - AnchorDistance - Height;
            }
            _snapAnchor = anchor;
        }

        private bool InSnapRange(int a, int b)
        {
            return Math.Abs(a - b) < SnapDistance;
        }

        private SnapLocation FindSnap(ref Rectangle effectiveBounds)
        {
            Screen currentScreen = Screen.FromPoint(effectiveBounds.Location);
            Rectangle workingArea = currentScreen.WorkingArea;
            SnapLocation anchor = SnapLocation.None;
            if (InSnapRange(effectiveBounds.Left, workingArea.Left + AnchorDistance))
            {
                effectiveBounds.X = workingArea.Left + AnchorDistance;
                anchor |= SnapLocation.Left;
            }
            else if (InSnapRange(effectiveBounds.Right, workingArea.Right - AnchorDistance))
            {
                effectiveBounds.X = workingArea.Right - AnchorDistance - effectiveBounds.Width;
                anchor |= SnapLocation.Right;
            }
            if (InSnapRange(effectiveBounds.Top, workingArea.Top + AnchorDistance))
            {
                effectiveBounds.Y = workingArea.Top + AnchorDistance;
                anchor |= SnapLocation.Top;
            }
            else if (InSnapRange(effectiveBounds.Bottom, workingArea.Bottom - AnchorDistance))
            {
                effectiveBounds.Y = workingArea.Bottom - AnchorDistance - effectiveBounds.Height;
                anchor |= SnapLocation.Bottom;
            }
            return anchor;
        }

        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WmEnterSizeMove:
                case WmSize:
                    // Need to handle window size changed as well when
                    // un-maximizing the form by dragging the title bar.
                    _dragOffsetX = Cursor.Position.X - Left;
                    _dragOffsetY = Cursor.Position.Y - Top;
                    break;
                case WmMoving:
                    LtrbRectangle boundsLtrb = Marshal.PtrToStructure<LtrbRectangle>(m.LParam);
                    Rectangle bounds = boundsLtrb.ToRectangle();
                    // This is where the window _would_ be located if snapping
                    // had not occurred. This prevents the cursor from sliding
                    // off the title bar if the snap distance is too large.
                    Rectangle effectiveBounds = new Rectangle(
                        Cursor.Position.X - _dragOffsetX,
                        Cursor.Position.Y - _dragOffsetY,
                        bounds.Width,
                        bounds.Height);
                    _snapAnchor = FindSnap(ref effectiveBounds);
                    LtrbRectangle newLtrb = LtrbRectangle.FromRectangle(effectiveBounds);
                    Marshal.StructureToPtr(newLtrb, m.LParam, false);
                    m.Result = new IntPtr(1);
                    break;
            }
            base.WndProc(ref m);
        }
    }
}

और यहां यह कैसा दिखता है:


https://github.com/stax76/staxrip

Protected Overrides Sub WndProc(ByRef m As Message)
    Snap(m)
    MyBase.WndProc(m)
End Sub

Private IsResizing As Boolean

Sub Snap(ByRef m As Message)
    Select Case m.Msg
        Case &H214 'WM_SIZING
            IsResizing = True
        Case &H232 'WM_EXITSIZEMOVE
            IsResizing = False
        Case &H46 'WM_WINDOWPOSCHANGING
            If Not IsResizing Then Snap(m.LParam)
    End Select
End Sub

Sub Snap(handle As IntPtr)
    Dim workingArea = Screen.FromControl(Me).WorkingArea
    Dim newPos = DirectCast(Marshal.PtrToStructure(handle, GetType(WindowPos)), WindowPos)
    Dim snapMargin = Control.DefaultFont.Height
    Dim border As Integer
    If OSVersion.Current >= OSVersion.Windows8 Then border = (Width - ClientSize.Width) \ 2 - 1

    If newPos.Y <> 0 Then
        If Math.Abs(newPos.Y - workingArea.Y) < snapMargin AndAlso Top > newPos.Y Then
            newPos.Y = workingArea.Y
        ElseIf Math.Abs(newPos.Y + Height - (workingArea.Bottom + border)) < snapMargin AndAlso Top < newPos.Y Then
            newPos.Y = (workingArea.Bottom + border) - Height
        End If
    End If

    If newPos.X <> 0 Then
        If Math.Abs(newPos.X - (workingArea.X - border)) < snapMargin AndAlso Left > newPos.X Then
            newPos.X = workingArea.X - border
        ElseIf Math.Abs(newPos.X + Width - (workingArea.Right + border)) < snapMargin AndAlso Left < newPos.X Then
            newPos.X = (workingArea.Right + border) - Width
        End If
    End If

    Marshal.StructureToPtr(newPos, handle, True)
End Sub




.net-2.0