C# 未知功能的名称/术语

C# 未知功能的名称/术语,c#,.net,vb.net,winforms,forms,C#,.net,Vb.net,Winforms,Forms,我想在我的应用程序中实现一个功能,问题是我不知道在哪里搜索,因为我不知道这个功能的名称/术语 在某些应用程序中,当您将窗体移到屏幕的边框/角落附近时,应用程序会自动附着到该边框上,直到您将窗体拖到远离边框的位置以取消粘贴为止 我没有任何应用程序示例显示如何使用此功能,对此表示抱歉 有人可以向我解释此功能的名称/术语,以及我在哪里可以找到源代码来检查用于实现此功能(在WinForms中)的技术。此功能有时被称为“捕捉”、“粘性”或“磁性”窗口,就像在WinAmp中使用的一样。示例实现可在中找到 C

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

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

我没有任何应用程序示例显示如何使用此功能,对此表示抱歉


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

此功能有时被称为“捕捉”、“粘性”或“磁性”窗口,就像在WinAmp中使用的一样。示例实现可在中找到

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);
    }
}
[StructLayout(LayoutKind.Sequential)]
公共结构WINDOWPOS
{
公共IntPtr hwnd;
公共IntPtr HwnInsertafter;
公共int x;
公共智力;
公共int cx;
公共关系;
公共国旗;
}
公共部分类Form1:Form
{
私有常量int SnapOffset=35;
私有常量int WM_WINDOWPOSCHANGING=70;
受保护的覆盖无效WndProc(参考消息m)
{
如果(m.Msg==WM_)
{
SnapToDesktopBorder(this,m.LParam,0);
}
基准WndProc(参考m);
}
私有void SnapToDesktopBorder(表单clientForm、IntPtr、intWidthAdjustment)
{
var newPosition=newwindowpos();
newPosition=(WINDOWPOS)System.Runtime.InteropServices.Marshal.PtrToStructure(intPtr,typeof(WINDOWPOS));
if(newPosition.y==0 | | newPosition.x==0)
{
返回;
//无事可做!
}
//调整边框和标题栏的客户端大小
矩形ClientRect=clientForm.RectangleToScreen(clientForm.ClientRectangle);
ClientRect.Width+=(SystemInformation.FrameBorderSize.Width*2)-宽度调整;
ClientRect.Height+=(SystemInformation.FrameBorderSize.Height*2)+SystemInformation.CaptionHeight;
//现在进入屏幕工作区(无任务栏)
矩形WorkingRect=Screen.FromControl(clientForm).WorkingArea;
//左边框

如果(newPosition.x>=WorkingRect.x-SnapOffset&&newPosition.x=-SnapOffset&&newPosition.x=-SnapOffset&&WorkingRect.Y>0&&newPosition.Y,你的意思是像Windows 7那样吗?如果你指的是应用程序的窗口相互捕捉,这有时被称为“磁性”。@一天谢谢,但我不确定你在说什么,我没有看到Windows 7外壳(资源管理器)这样做。@CodeCaster谢谢,我不确定是否可能是这样,也许是的,但我找不到任何与“磁性”边框有关的内容。也可以用Windows任务栏作为例子。它是一个应用程序栏,你可以自己创建。我注意到它会吃掉应用程序的右/下边框(非客户端区域)当在屏幕的右/下(任务栏)边缘捕捉时。不要期望我支持它,我只报告我发现的内容。;)它给了你一个如何做的想法,请随意提供CodeProject的补丁或编辑这篇文章。我想,例如,你需要做两次而不是一次
SystemInformation.FrameBorderSize.Width
Height
。编辑:划掉它,这是他使用的完全错误的属性,因为“获取在拖动调整大小的窗口周长周围绘制的调整大小边框的厚度(以像素为单位)。这不是窗口的大小,而是调整大小时看到的灰色边框。此代码已被破坏。我只是替换了边框测量逻辑(这似乎不是必需的)使用
this.Width
this.Height
,现在它可以正常工作了,谢谢您的时间。