c# - 表单位置和大小行为

标签 c# .net forms winforms location

我想将表单放置在屏幕的左上角。

我试过 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 KeimWindowHelper 类的 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/

相关文章:

c# - 在 .NET(或一般)中创建文档的正确方法是什么?

c# - 'real'语句存在的 "GOTO"目的是性能提升吗?

javascript - 将动态 HTML 字段数组中的值减少到最紧凑的形式

c# - 将 C# 中的调试器附加到另一个进程

c# - 在 C# 中嵌入一个 xsd 文件

c# - "Unable to find an entry point named"在 c# 中使用 C dll

c# - 使用最小起订量的非虚拟成员的无效设置

c# - 关于 IoC/DI VS CBSE 的信息

php - 将表单数据插入数据库的更短方法?

javascript - 以 Javascript/jQuery 表示的 PHP 表单 : One to many UI relationships,?