我想在我的應用程序中實現一個功能,問題是我不知道在哪裏搜索,因爲我不知道此功能的名稱/術語。未知功能的名稱/期限
在某些應用程序中,當您將窗體移動到屏幕的邊界/角落附近時,應用程序會自動自動粘貼到該邊框,直到您將窗體拖到邊界以外爲止。
我沒有任何應用程序示例顯示使用此功能,對此感到抱歉。
有人可以解釋我是哪個名稱/這個特性的術語,在哪裏我可以找到一個來源來檢查用於實現此功能的技術(在WinForms中)?
我想在我的應用程序中實現一個功能,問題是我不知道在哪裏搜索,因爲我不知道此功能的名稱/術語。未知功能的名稱/期限
在某些應用程序中,當您將窗體移動到屏幕的邊界/角落附近時,應用程序會自動自動粘貼到該邊框,直到您將窗體拖到邊界以外爲止。
我沒有任何應用程序示例顯示使用此功能,對此感到抱歉。
有人可以解釋我是哪個名稱/這個特性的術語,在哪裏我可以找到一個來源來檢查用於實現此功能的技術(在WinForms中)?
該功能有時被稱爲「貼緊」,「粘滯」或「磁性」窗口,就像在WinAmp中使用的一樣。一個示例實現可以在CodeProject: A .NET Snap To Screen 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);
}
}
但代碼看起來有點臃腫,我認爲它可以大大簡化。它也只適用於桌面邊界,而不適用於其他窗口。
又見Anyone familiar with a good 「sticky windows」 library for Winforms?,兩個答案鏈接到其他CodeProject上的解決方案:SnapFormExtender - a magnet for your MDI child forms(2004年)和Sticky Windows - How to make your (top-level) forms to stick one to the other or to the screen,也從2004年
我注意到,當它在屏幕的右側/底部(任務欄)邊緣上貼着時,它會吃掉應用程序的右側/底部邊界(非客戶端區域)。 – ElektroStudios 2014-09-18 20:51:25
不要指望我支持它,我只是報告我發現的內容。 ;)它給你一個如何完成的想法,隨時爲CodeProject提供修復或編輯這篇文章。我想,例如你需要做'SystemInformation.FrameBorderSize.Width'和'Height'兩次而不是一次。編輯:從頭開始,這完全是他正在使用的錯誤屬性,因爲它_「獲取圍繞正在拖動調整大小的窗口周圍繪製的調整邊框的大小(以像素爲單位)**」_。這不是窗口鉻大小,它是調整大小時看到的灰色邊框。此代碼已損壞。 – CodeCaster 2014-09-18 20:53:32
我用'this.Width'和'this.Height'替換了邊界測量邏輯(似乎不需要),現在它按預期工作,謝謝你的時間。 – ElektroStudios 2014-09-18 21:04:37
你的意思是像Windows 7呢? – OneFineDay 2014-09-18 20:30:48
如果您的意思是應用程序的窗口彼此咬合,那麼有時稱爲「磁性」。 – CodeCaster 2014-09-18 20:32:30
@OneFineDay謝謝,但我不確定你在說什麼,我沒有看到Windows 7 shell(瀏覽器)這樣做。 – ElektroStudios 2014-09-18 20:37:10