WINDOWPLACEMENT 结构的正确长度

Correct length for WINDOWPLACEMENT struct

我正在开发一个需要 get/set Win32 window 放置信息的应用程序。我正在使用 .NET Core 3.1 和 Windows 10 1909。我为 GetWindowPlacement 添加了一个 P/Invoke 方法和结构:

[DllImport("USER32.DLL")]
public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);


[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public long left;
    public long top;
    public long right;
    public long bottom;
}

[StructLayout(LayoutKind.Sequential)]
public struct WINDOWPLACEMENT
{
    public uint length;
    public uint flags;
    public uint showCmd;
    public POINT ptMinPosition;
    public POINT ptMaxPosition;
    public RECT rcNormalPosition;
    public RECT rcDevice;
}

[StructLayout(LayoutKind.Sequential)]
public struct POINT
{
    public long x;
    public long y;
}

然后我这样称呼它:

var placement = new WINDOWPLACEMENT();
placement.length = (uint)Marshal.SizeOf(placement);
if (GetWindowPlacement(hWnd, ref placement))
{
    // do something with placement info
}

Marshall.SizeOf returns 长度为 108 个字节,调用似乎成功,但之后放置结构始终将其 length 值设置为 44,并且 RECT 值都是 0。flagsshowCmdPOINT 值都很好。我已经尝试将 length 硬编码为其他值,如 112 或 120 字节,或 0 字节,但我总是用 length = 44 返回结构并且没有矩形。

我错过了什么?

<Windows.h>中结构定义如下:

typedef struct tagWINDOWPLACEMENT {
    UINT  length;
    UINT  flags;
    UINT  showCmd;
    POINT ptMinPosition;
    POINT ptMaxPosition;
    RECT  rcNormalPosition;
#ifdef _MAC
    RECT  rcDevice;
#endif
} WINDOWPLACEMENT;
typedef WINDOWPLACEMENT *PWINDOWPLACEMENT, *LPWINDOWPLACEMENT;

所以它的大小是 3*sizeof(UINT)+2*sizeof(POINT)+1*sizeof(RECT) 没有定义 _MAC,再加上一个 RECT 有定义 _MAC

所以它是 44,_MAC 是 60(参见 What's with "#ifdef _MAC" in Windows header files?

所以你应该在没有RECT rcDevice

的情况下定义它

另一个错误是C#long是8个字节,你需要intPOINTRECT.

两者都修好,您将得到 44 个。