1

如果其 IpszDeviceName 参数为空,则 EnumDisplaySettings() 有效,但如果它是设备名称,则返回 0。

这是下面代码的输出。

devNum =0

cb =424

DeviceID =PCI\VEN_10DE&DEV_0402&SUBSYS_0440196E&REV_A1

DeviceKey =\Registry\Machine\System\CurrentControlSet\Control\Video\{B757E378-AF2E-4826-BA9E-927C5B81B139}\0000

DeviceName =\\.\DISPLAY1

DeviceString =NVIDIA GeForce 8600 GT

Monitor name =Generic PnP Monitor

>>> EnumDisplaySettings RETURNED 0. <<<<<<<<<<<<<<

devNum =1

cb =424

DeviceID =PCI\VEN_10DE&DEV_0402&SUBSYS_0440196E&REV_A1

DeviceKey =\Registry\Machine\System\CurrentControlSet\Control\Video\{B757E378-AF2E-4826-BA9E-927C5B81B139}\0001

DeviceName =\\.\DISPLAY2

DeviceString =NVIDIA GeForce 8600 GT

Monitor name =Generic PnP Monitor

>>> EnumDisplaySettings RETURNED 0. <<<<<<<<<<<<<<

这是源代码。

        public static void show_display_devices()
    {
        DISPLAY_DEVICE lpDisplayDevice = new DISPLAY_DEVICE(0);     // OUT
            DISPLAY_DEVICE monitor_name = new DISPLAY_DEVICE(0);        // OUT
        DEVMODE mode = new DEVMODE();

        int devNum = 0;
        while (EnumDisplayDevices(null, devNum, ref lpDisplayDevice, 0))
        {

            Console.WriteLine("\ndevNum =" + devNum);
            Console.WriteLine("cb =" + lpDisplayDevice.cb);
            Console.WriteLine("DeviceID =" + lpDisplayDevice.DeviceID);
            Console.WriteLine("DeviceKey =" + lpDisplayDevice.DeviceKey);
            Console.WriteLine("DeviceName =" + lpDisplayDevice.DeviceName.Trim());
            Console.WriteLine("DeviceString =" + lpDisplayDevice.DeviceString.Trim());
            // Show monitor name:



            EnumDisplayDevices( lpDisplayDevice.DeviceName, 0, ref monitor_name, 0);
            Console.WriteLine("Monitor name =" + monitor_name.DeviceString.Trim());

            // Show the device's settings:
            if (EnumDisplaySettings(lpDisplayDevice.DeviceName,
                    ENUM_CURRENT_SETTINGS,
                    ref mode) == true) // Succeeded
            {
                Console.WriteLine("Current Mode:\n\t" +
                    "{0} by {1}, " +
                    "{2} bit, " +
                    "{3} degrees, " +
                    "{4} hertz",
                    mode.dmPelsWidth,
                    mode.dmPelsHeight,
                    mode.dmBitsPerPel,
                    mode.dmDisplayOrientation * 90,
                    mode.dmDisplayFrequency);
            }
            else
            {
                Console.WriteLine(">>>  EnumDisplaySettings  RETURNED 0.  <<<<<<<<<<<<<<");
            }
            ++devNum;
        }
    }

    [DllImport("User32.dll")]
    private static extern bool EnumDisplayDevices(
        string lpDevice, int iDevNum,
        ref DISPLAY_DEVICE lpDisplayDevice, int dwFlags);


          [DllImport("User32.dll", SetLastError=true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern Boolean EnumDisplaySettings(
        [param: MarshalAs(UnmanagedType.LPTStr)]
        string lpszDeviceName,
        [param: MarshalAs(UnmanagedType.U4)]
        int iModeNum,
        [In, Out]
        ref DEVMODE lpDevMode);
4

1 回答 1

1

您需要将 lpDisplayDevice.DeviceName 转换为EnumDisplaySettings函数可以理解的字节数组。最好使用String 类的扩展方法来完成:

public static class StringExtensions
{
    public static byte[] ToLPTStr(this string str)
    {
        var lptArray = new byte[str.Length+1];

        var index = 0;
        foreach (char c in str.ToCharArray())
            lptArray[index++] = Convert.ToByte(c);

        lptArray[index] = Convert.ToByte('\0');

        return lptArray;
    }
}

然后,将 EnumDisplaySettings extern 声明的签名更改为采用 lpszDeviceName 的字节数组:

    [DllImport("User32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern Boolean EnumDisplaySettings(
        byte[] lpszDeviceName,
        [param: MarshalAs(UnmanagedType.U4)]
        int iModeNum,
         [In, Out]
        ref DEVMODE lpDevMode);

然后,您可以像这样调用 EnumDisplaySettings:

EnumDisplayDevices(lpDisplayDevice.DeviceName.ToLPTStr(), 0, ref monitor_name, 0);
于 2014-06-19T19:13:39.537 回答