未知功能的名称/术语
本文关键字:术语 功能 未知 | 更新日期: 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年开始。