Problems with GetMonitorInfoEx Structure

  • Thread starter Thread starter JackRazz
  • Start date Start date
J

JackRazz

I'm having problems trying to call GetMonitorInfo. I believe the problem has
something to do with the szDeviceName. Passing a MonitorInfo struct works fine. I
added the szDeviceName and the struct is filled with garbage. What am I doing
wrong??

Thanks - JackRazz


Pretty version of this snippet is here: http://rafb.net/paste/results/M3114698.html

private const int CCHDEVICENAME = 32;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class MonitorInfoEx {
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public UInt32 dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
public string szDeviceName;
}


[DllImport("user32")]
internal static extern bool GetMonitorInfo( IntPtr hMonitor, [Out]
MonitorInfoEx lpmi );


MonitorInfoEx mi = new MonitorInfoEx();
mi.cbSize =(uint) Marshal.SizeOf(mi);

bool result = GetMonitorInfo( hMonitor, mi ) ;
if ( result ) {
Mon.MonitorArea= mi.rcMonitor;
Mon.WorkArea= mi.rcWork;
Mon.Flags = (int) mi.dwFlags;
Mon.hMonitor = hMonitor;
//Mon.deviceName=mi.szDeviceName;
}
else {
Console.WriteLine("Call to GetMonitorInfo failed");
}
 
[DllImport("user32")]
internal static extern bool GetMonitorInfo( IntPtr hMonitor, [Out]
MonitorInfoEx lpmi );

Add CharSet=CharSet.Auto to the DllImport attribute.



Mattias
 
Add CharSet=CharSet.Auto to the DllImport attribute.


Mattias,
First, thanks for the reply. It didn't work. I worked on it last night to capture
the LastError, which is 127 - 'The parameter is incorrect.' Any other suggestions.
I've updated the listing to show your suggested change with the full callback
procedure.



-------------------------------------------------------------------------------------
----
Pretty print version here --> http://rafb.net/paste/results/p3091664.html


//I'm having problems trying to call GetMonitorInfo. I believe the problem has
//something to do with szDeviceName. Passing a MonitorInfo struct works fine. I
//added the szDeviceName and the struct is filled with garbage.

[DllImport("user32", CharSet = CharSet.Auto, SetLastError=true)]
internal static extern bool GetMonitorInfo( IntPtr hMonitor, [Out] MonitorInfoEx
lpmi );

private const int CCHDEVICENAME = 32;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal class MonitorInfoEx {
public uint cbSize;
public RECT rcMonitor;
public RECT rcWork;
public UInt32 dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
public string szDeviceName;
}


public bool MonitorEnumCallback( IntPtr hMonitor, IntPtr hDC,ref RECT lprcMonitor,
object dwData ) {

CMonitor Mon = new CMonitor();
MonitorInfoEx mi = new MonitorInfoEx();
mi.cbSize =(uint) Marshal.SizeOf(mi);

bool result = GetMonitorInfo( hMonitor, mi ) ;
if ( result ) {
Mon.MonitorArea= mi.rcMonitor;
Mon.WorkArea= mi.rcWork;
Mon.Flags = (int) mi.dwFlags;
Mon.hMonitor = hMonitor;
//Mon.deviceName=mi.szDeviceName;
}
else {
//throw new Win32Exception(Marshal.GetLastWin32Error());
Win32Exception myEx = new Win32Exception(Marshal.GetLastWin32Error());
Console.WriteLine(myEx.ErrorCode);
Console.WriteLine(myEx.Message);
}

mMonitors.Add(Mon);
return result;
}
 
How does RECT looks like?
It's always good to post complete reproducible code snippets.

Willy.
 
GetMonitorInfo take a handle to a monitor as first argument not a DC handle.
So you nee to call MonitorFromWindow to get this handle.

[DllImport("User32")]
public static extern IntPtr MonitorFromWindow( IntPtr hWnd, int dwFlags );

const int MONITOR_DEFAULTTOPRIMARY = 1;
.....
result = GetMonitorInfoEx( MonitorFromWindow( IntPtr.Zero,
MONITOR_DEFAULTTOPRIMARY) , ref mi );
if ( result ) {
.....

Willy.
 
Forgot the most important, change MonitorInfoEx and RECT into a struct i.s.o
a class....

Here is a working console sample.

using System;
using System.Runtime.InteropServices;

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


[DllImport("User32")]
public static extern IntPtr MonitorFromWindow( IntPtr hWnd, int dwFlags );

[DllImport("user32",EntryPoint="GetMonitorInfo", CharSet = CharSet.Auto,
SetLastError=true)]
internal static extern bool GetMonitorInfoEx( IntPtr hMonitor, ref
MonitorInfoEx lpmi );

private const int CCHDEVICENAME = 32;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
internal struct MonitorInfoEx {
public int cbSize;
public RECT rcMonitor;
public RECT rcWork;
public UInt32 dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=CCHDEVICENAME)]
public string szDeviceName;
}

static void Main()
{
const int MONITOR_DEFAULTTOPRIMARY = 1;
bool result;
MonitorInfoEx mi = new MonitorInfoEx();
mi.cbSize = Marshal.SizeOf(mi);
result = GetMonitorInfoEx( MonitorFromWindow(
IntPtr.Zero,MONITOR_DEFAULTTOPRIMARY) , ref mi );
if ( result ) {
Console.WriteLine(mi.rcMonitor.left);
Console.WriteLine(mi.rcMonitor.right);
Console.WriteLine(mi.dwFlags.ToString());
Console.WriteLine(mi.szDeviceName);
}
else {
Console.WriteLine(Marshal.GetLastWin32Error());

}
}
}

Willy.
 
Back
Top