简体   繁体   English

使用Win32 API获取桌面工作区矩形

[英]Using Win32 API to get desktop work area rectangle

I Want SystemParametersInfoA to return a System.Drawing.Rectangle but i have no idea how to proceed.我希望 SystemParametersInfoA 返回一个 System.Drawing.Rectangle 但我不知道如何继续。

Here is my code so far:到目前为止,这是我的代码:

[DllImport("user32.dll")]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, out IntPtr pvParam, uint fWinIni);
const uint SPI_GETWORKAREA = 0x0030;

void GetRect()
{
    IntPtr WorkAreaRect;
    SystemParametersInfo(SPI_GETWORKAREA, 0, out WorkAreaRect, 0);
}

Per the SPI_GETWORKAREA documentation:根据SPI_GETWORKAREA文档:

The pvParam parameter must point to a RECT structure that receives the coordinates of the work area, expressed in physical pixel size. pvParam参数必须指向一个接收工作区域坐标的RECT结构,以物理像素大小表示。

The pointer in question is not an out value.有问题的指针不是out值。 It is an in value.in一个价值。 You are supposed to pass in your own pointer to an existing RECT instance, which SPI_GETWORKAREA will then simply fill in.您应该将自己的指针传递给现有的RECT实例,然后SPI_GETWORKAREA将简单地填充该实例。

You can use Marshal.AllocHGlobal() to allocate memory for a RECT , and then use Marshal.PtrToStructure() to extract the populated RECT from the memory.您可以使用Marshal.AllocHGlobal()RECT分配 memory,然后使用Marshal.PtrToStructure()从 memory 中提取填充的RECT

Try this:尝试这个:

[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni);
const uint SPI_GETWORKAREA = 0x0030;

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left, Top, Right, Bottom;
}

void GetRect()
{
    IntPtr mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(RECT)));
    SystemParametersInfo(SPI_GETWORKAREA, 0, mem, 0);
    RECT r = new RECT;
    Marshal.PtrToStructure(mem, r);
    Rectangle WorkAreaRect = new Rectangle(r.Left, r.Top, r.Width, r.Height);
    Marshal.FreeHGlobal(mem);
}

As mentioned, you need to pass a buffer variable in.如前所述,您需要传入一个缓冲区变量。

But you don't need to manually allocate it.但是您不需要手动分配它。 You can just use an out variable.您可以只使用out变量。

[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(uint uiAction, uint uiParam, out RECT pvParam, uint fWinIni);
const uint SPI_GETWORKAREA = 0x0030;

[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
    public int Left, Top, Right, Bottom;
}

Rectangle GetRect()
{
    if(!SystemParametersInfo(SPI_GETWORKAREA, 0, out var r, 0))
        throw new Win32Exception(Marshal.GetLastWin32Error());
    return new Rectangle(r.Left, r.Top, r.Width, r.Height);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM