我想将表单放置在屏幕的左上角。
我试过 this.Location = new Point(0,0)
但窗口位于 (7,0) - 窗口顶部在屏幕顶部但左侧是 7距屏幕边缘的像素。
我创建了新的 WinForms 应用程序进行测试并仅添加了以下代码:
private void Form1_Load(object sender, EventArgs e)
{
Point p = new Point(0, 0);
WindowState = FormWindowState.Maximized;
Debug.WriteLine("\nMaximized");
Debug.WriteLine("Location: " + Location);
Debug.WriteLine("Size: " + Size);
Debug.WriteLine("PointToScreen(0,0): " + PointToScreen(p));
WindowState = FormWindowState.Normal;
Location = p;
Debug.WriteLine("\nNormal");
Debug.WriteLine("Location: " + Location);
Debug.WriteLine("Size: " + Size);
Debug.WriteLine("PointToScreen(0,0): " + PointToScreen(p));
Debug.Write("\nScreen.PrimaryScreen.WorkingArea: ");
Debug.WriteLine(Screen.PrimaryScreen.WorkingArea);
}
输出是:
Maximized
Location: {X=-8,Y=-8}
Size: {Width=1936, Height=1056}
PointToScreen(0,0): {X=0,Y=23}
Normal
Location: {X=0,Y=0}
Size: {Width=300, Height=300}
PointToScreen(0,0): {X=8,Y=31}
Screen.PrimaryScreen.WorkingArea: {X=0,Y=0,Width=1920,Height=1040}
为什么 Location = new Point(0,0)
不在 (0,0) 上定位表格?
这是由于我的系统上的某些东西吗?我有 Win10 和 VS2015。任务栏在底部,我的桌面左侧什么也没有。
为了将它定位在 (0,0) 上,我实际上必须将它定位在 (-7,0) 上。此外,报告的最大化形式的宽度比屏幕宽度大 16 个像素。我知道由于窗口边缘、标题栏等原因,客户区大小和表单大小之间存在差异,但事实并非如此。当表单最大化时没有左右边缘(客户区宽度=桌面宽度)但表单宽度为+16px。表单的 4 个边各有 +8px,但 Y 位置没问题。为什么 Y 位置可以,而 X 位置不行?
最佳答案
感谢Uwe Keim和他自己的answer到他的question ,我已经创建了 MoveForm
函数来计算偏移量并正确设置表单的位置,无论 Windows 版本如何(即边框大小):
void MoveForm(Point p) // Move form to point 'p'
{
this.WindowState = FormWindowState.Normal;
this.Location = new Point(0, 0);
Rectangle rec = WindowHelper.GetWindowRectangle(this.Handle);
p.Offset(-rec.Location.X, -rec.Location.Y);
this.Location = p;
}
MoveForm
函数使用来自 Uwe Keim 的 WindowHelper
类的 post :
public static class WindowHelper
{
// https://code.google.com/p/zscreen/source/browse/trunk/ZScreenLib/Global/GraphicsCore.cs?r=1349
/// <summary>
/// Get real window size, no matter whether Win XP, Win Vista, 7 or 8.
/// </summary>
public static Rectangle GetWindowRectangle(IntPtr handle)
{
if (Environment.OSVersion.Version.Major < 6)
{
return GetWindowRect(handle);
}
else
{
Rectangle rectangle;
return DWMWA_EXTENDED_FRAME_BOUNDS(handle, out rectangle) ? rectangle : GetWindowRect(handle);
}
}
[DllImport(@"dwmapi.dll")]
private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rect pvAttribute, int cbAttribute);
private enum Dwmwindowattribute
{
DwmwaExtendedFrameBounds = 9
}
[Serializable, StructLayout(LayoutKind.Sequential)]
private struct Rect
{
// ReSharper disable MemberCanBePrivate.Local
// ReSharper disable FieldCanBeMadeReadOnly.Local
public int Left;
public int Top;
public int Right;
public int Bottom;
// ReSharper restore FieldCanBeMadeReadOnly.Local
// ReSharper restore MemberCanBePrivate.Local
public Rectangle ToRectangle()
{
return Rectangle.FromLTRB(Left, Top, Right, Bottom);
}
}
private static bool DWMWA_EXTENDED_FRAME_BOUNDS(IntPtr handle, out Rectangle rectangle)
{
Rect rect;
var result = DwmGetWindowAttribute(handle, (int)Dwmwindowattribute.DwmwaExtendedFrameBounds,
out rect, Marshal.SizeOf(typeof(Rect)));
rectangle = rect.ToRectangle();
return result >= 0;
}
[DllImport(@"user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect);
private static Rectangle GetWindowRect(IntPtr handle)
{
Rect rect;
GetWindowRect(handle, out rect);
return rect.ToRectangle();
}
}
关于c# - 表单位置和大小行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39602218/