MoveWindow 和 SetWindowPos 都会导致窗口位置/大小不正确

问题描述 投票:0回答:1

我想移动应用程序的窗口并调整其大小(例如:记事本)。 我尝试了

MoveWindow
SetWindowPos
,两者都有完全相同的问题。新的位置/尺寸总是不准确。

MoveWindow(handle, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, true);
SetWindowPos(handle, IntPtr.Zero, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height, 0);

我在不同的电脑(均运行 Windows 10)上对此进行了测试,我注意到了一个模式。在第一台 PC 上,“漂移”为 X:+7、Y:0、W: -14、H: -7。在第二台 PC 上,“漂移”为 X:+8、Y:0、W:-16、H-8。

我确实在第三台电脑上进行了测试,但结果更糟糕,我猜这与它有 2 个显示器有关。

我可以亲眼看到“漂移”,当我喂它X:0和Y:0时尤其清晰。我不明白为什么会发生这种情况,也不明白如何解决它。

这是我用来获取窗口的(例如:记事本)位置和尺寸的函数:

public static Rectangle GetWindowRectangle(IntPtr handle)
{
    Rect rect = new Rect();
    if (Environment.OSVersion.Version.Major >= 6)
    {
        int size = Marshal.SizeOf(typeof(Rect));
        DwmGetWindowAttribute(handle, (int)DwmWindowAttribute.DWMWA_EXTENDED_FRAME_BOUNDS, out rect, size);
    }
    else if (Environment.OSVersion.Version.Major < 6 || rect.ToRectangle().Width == 0)
    {
        GetWindowRect(handle, out rect);
    }

    return rect.ToRectangle();
}
c# winforms winapi
1个回答
5
投票

你忽略了窗户的阴影。在win10中,您将在

DwmGetWindowAttribute
中使用
DWMWA_EXTENDED_FRAME_BOUNDS
+
GetWindowRectangle
,根据文档,这将获得不包括阴影的窗口边界。

在 Windows Vista 及更高版本中,窗口矩形现在包括阴影占用的区域。因此,函数

MoveWindow
SetWindowPos
认为您传递的位置/大小包括阴影。

如果你想移动和调整不包括阴影的区域的大小,那么你需要首先计算阴影的大小(C++示例):

RECT exclude_shadow = {}, include_shadow = {};
GetWindowRectangle(hwnd,&exclude_shadow);
GetWindowRect(hwnd, &include_shadow);
RECT shadow = {};
shadow.left = include_shadow.left - exclude_shadow.left; // -7
shadow.right = include_shadow.right - exclude_shadow.right; // +7
shadow.top = include_shadow.top - exclude_shadow.top; //0
shadow.bottom = include_shadow.bottom - exclude_shadow.bottom; // +7

LONG Width = include_shadow.right - include_shadow.left;
LONG Height = include_shadow.bottom - include_shadow.top;

//SetWindowPos(hwnd, NULL, 0 + shadow.left, 0 + shadow.top, Width, Height, 0);
SetWindowPos(hwnd, NULL, 0 + shadow.left, 0 + shadow.top, 0, 0, SWP_NOSIZE); // use SWP_NOSIZE if you want to keep the size.
© www.soinside.com 2019 - 2024. All rights reserved.