c#的EnumDisplaySettings不能为lpszDeviceName工作

本文关键字:lpszDeviceName 工作 不能 EnumDisplaySettings | 更新日期: 2023-09-27 18:10:43

EnumDisplaySettings()如果它的IpszDeviceName参数为空则工作,但如果它是设备名称则返回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);

c#的EnumDisplaySettings不能为lpszDeviceName工作

您需要转换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);