未知功能的名称/术语

本文关键字:术语 功能 未知 | 更新日期: 2023-09-27 18:22:37

我想在我的应用程序中实现一个功能,问题是我不知道在哪里搜索,因为我不知道这个功能的名称/术语。

在某些应用程序中,当您将窗体移动到屏幕的边框/角附近时,应用程序会自动粘附到该边框上,直到您将窗体拖动到远离边框的位置。

我没有任何使用此功能的应用程序示例,对此感到抱歉。

有人可以向我解释这个功能的名称/术语,以及我在哪里可以找到一个来源来检查用于实现这个功能的技术(在WinForms中)?。

未知功能的名称/术语

该功能有时被称为"捕捉"、"粘性"或"磁性"窗口,就像WinAmp中使用的一样。一个示例实现可以在CodeProject:A.NETSnapToScreen Form.中找到

C#版本可以归结为:

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPOS
{
    public IntPtr hwnd;
    public IntPtr hwndInsertAfter;
    public int x;
    public int y;
    public int cx;
    public int cy;
    public int flags;
}
public partial class Form1 : Form
{
    private const int SnapOffset = 35;
    private const int WM_WINDOWPOSCHANGING = 70;
    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_WINDOWPOSCHANGING)
        {
            SnapToDesktopBorder(this, m.LParam, 0);
        }
        base.WndProc(ref m);
    }
    private void SnapToDesktopBorder(Form clientForm, IntPtr intPtr, int widthAdjustment)
    {
        var newPosition = new WINDOWPOS();
        newPosition = (WINDOWPOS)System.Runtime.InteropServices.Marshal.PtrToStructure(intPtr, typeof(WINDOWPOS));
        if (newPosition.y == 0 || newPosition.x == 0)
        {
            return;
            // Nothing to do!
        }
        // Adjust the client size for borders and caption bar
        Rectangle ClientRect = clientForm.RectangleToScreen(clientForm.ClientRectangle);
        ClientRect.Width += (SystemInformation.FrameBorderSize.Width * 2) - widthAdjustment;
        ClientRect.Height += (SystemInformation.FrameBorderSize.Height * 2) + SystemInformation.CaptionHeight;
        // Now get the screen working area (without taskbar)
        Rectangle WorkingRect = Screen.FromControl(clientForm).WorkingArea;
        // Left border
        if (newPosition.x >= WorkingRect.X - SnapOffset && newPosition.x <= WorkingRect.X + SnapOffset)
        {
            newPosition.x = WorkingRect.X;
        }
        // Get screen bounds and taskbar height
        // (when taskbar is horizontal)
        Rectangle ScreenRect = Screen.FromControl(clientForm).Bounds;
        int TaskbarHeight = ScreenRect.Height - WorkingRect.Height;
        // Top border (check if taskbar is on top
        // or bottom via WorkingRect.Y)
        if (newPosition.y >= -SnapOffset && (WorkingRect.Y > 0 && newPosition.y <= (TaskbarHeight + SnapOffset)) || (WorkingRect.Y <= 0 && newPosition.y <= (SnapOffset)))
        {
            if (TaskbarHeight > 0)
            {
                newPosition.y = WorkingRect.Y;
                // Horizontal Taskbar
            }
            else
            {
                newPosition.y = 0;
                // Vertical Taskbar
            }
        }
        // Right border
        if (newPosition.x + ClientRect.Width <= WorkingRect.Right + SnapOffset && newPosition.x + ClientRect.Width >= WorkingRect.Right - SnapOffset)
        {
            newPosition.x = WorkingRect.Right - (ClientRect.Width + SystemInformation.FrameBorderSize.Width);
        }
        // Bottom border
        if (newPosition.y + ClientRect.Height <= WorkingRect.Bottom + SnapOffset && newPosition.y + ClientRect.Height >= WorkingRect.Bottom - SnapOffset)
        {
            newPosition.y = WorkingRect.Bottom - (ClientRect.Height + SystemInformation.FrameBorderSize.Height);
        }
        // Marshal it back
        System.Runtime.InteropServices.Marshal.StructureToPtr(newPosition, intPtr, true);
    }
}

但是代码似乎有点臃肿,我认为它可以大大简化。它也只适用于桌面边框,而不适用于其他窗口。

另请参阅熟悉Winforms的"粘性窗口"库的人吗?,这两个答案都链接到其他CodeProject解决方案:SnapFormExtender-吸引MDI子窗体的磁铁(2004年)和Sticky Windows-如何使您的(顶级)窗体相互粘贴或粘贴到屏幕上,也是从2004年开始。