Per the SPI_GETWORKAREA
documentation:
The pvParam
parameter must point to a RECT
structure that receives the coordinates of the work area, expressed in physical pixel size.
The pointer in question is not an out
value. It is an in
value. You are supposed to pass in your own pointer to an existing RECT
instance, which SPI_GETWORKAREA
will then simply fill in.
You can use Marshal.AllocHGlobal()
to allocate memory for a RECT
, and then use Marshal.PtrToStructure()
to extract the populated RECT
from the memory.
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);
}