Search code examples
structpinvokemarshalling

How can I tell if cbSize should be int or uint in MonitorInfo?


I'm trying to do some multi-monitor stuff using Platform Invoke. I've been using http://pinvoke.net to get me started but I've hit a problem where definitions don't agree.

In MONITORINFO (user32) (and MONITORINFOEX (user32)), size is defined as:

public int Size;

But in EnumDisplayMonitors (user32), in the sample code which uses MonitorInfo, we see:

mi.size = (uint)Marshal.SizeOf(mi);

Clearly, one of these is less than correct.

In the MSDN docs, MONITORINFO is declared as:

typedef struct tagMONITORINFO {
  DWORD cbSize;
  RECT  rcMonitor;
  RECT  rcWork;
  DWORD dwFlags;
} MONITORINFO, *LPMONITORINFO;

with cbSize defined as:

The size of the structure, in bytes.

Set this member to sizeof ( MONITORINFO ) before calling the GetMonitorInfo function. Doing so lets the function determine the type of structure you are passing to it.

Any idea how I can work out which it should be, int or uint?

Note: I know some of this stuff is available in System.Windows.Forms but I'm trying to do this using P/Invoke in Silverlight 5.


Solution

  • DWORD is an unsigned 32 bit integer, so uint is technically correct.

    The version that uses int was presumably done that way through mild laze. The author presumably wanted not to have to cast the return value of Marshal.SizeOf() to uint.

    In practice it simply does not matter here because the cbSize will never get to the point where the conversion from signed to unsigned makes any difference. However, in some cases it can matter. For example, a variable that held a combination of bit flags.