How get monitor's friendly name with winapi?
Asked Answered
P

2

2

I use Win32_DesktopMonitor class of wmi. But this not return monitor name. But when i use Everest(Aida64) this show me it. I think this app's work with winapi. I find method GetMonitorInfo, but not understand how use it to get monitor name.

edited excuse me for worst question. I want friend name of monitor with win api. I watch this thread url msdn but find solution only in c language.

enter image description here

The image on the left shows what I am looking for. The image on the right shows the device name retrieved from GetMonitorInfo.

Pirri answered 16/10, 2014 at 12:53 Comment(3)
msdn.microsoft.com/de-de/library/…Shanda
this code not return name of monitor. joxi.ru/jgmvRYbotvVJmaPirri
Does this answer your question? How do I get the actual Monitor name? as seen in the resolution dialogEntanglement
A
18

This program shows how to call GetMonitorInfo using p/invoke and then extract the device name.

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    class Program
    {
        [StructLayout(LayoutKind.Sequential)]
        struct RECT
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        struct MONITORINFOEX
        {
            public int Size;
            public RECT Monitor;
            public RECT WorkArea;
            public uint Flags;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string DeviceName;
        }

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX lpmi);

        delegate bool MonitorEnumDelegate(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData);

        [DllImport("user32.dll")]
        static extern bool EnumDisplayMonitors(IntPtr hdc, IntPtr lprcClip, MonitorEnumDelegate lpfnEnum, IntPtr dwData);

        static bool MonitorEnumProc(IntPtr hMonitor, IntPtr hdcMonitor, ref RECT lprcMonitor, IntPtr dwData)
        {
            MONITORINFOEX mi = new MONITORINFOEX();
            mi.Size = Marshal.SizeOf(typeof(MONITORINFOEX));
            if (GetMonitorInfo(hMonitor, ref mi))
                Console.WriteLine(mi.DeviceName);
            return true;
        }

        static void Main(string[] args)
        {
            EnumDisplayMonitors(IntPtr.Zero, IntPtr.Zero, MonitorEnumProc, IntPtr.Zero);
        }
    }
}

According to your update, GetMonitorInfo does not yield the information you need. This program based on QueryDisplayConfig does. Note that QueryDisplayConfig was introduced in Windows 7.

using System;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace ConsoleApplication3
{
    class Program
    {
        public const int ERROR_SUCCESS = 0;

        public enum QUERY_DEVICE_CONFIG_FLAGS: uint
        {
            QDC_ALL_PATHS          = 0x00000001,
            QDC_ONLY_ACTIVE_PATHS  = 0x00000002,
            QDC_DATABASE_CURRENT   = 0x00000004
        }

        public enum DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY: uint
        {
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_OTHER                   = 0xFFFFFFFF,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HD15                    = 0,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SVIDEO                  = 1,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPOSITE_VIDEO         = 2,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_COMPONENT_VIDEO         = 3,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DVI                     = 4,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_HDMI                    = 5,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_LVDS                    = 6,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_D_JPN                   = 8,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDI                     = 9,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EXTERNAL    = 10,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_DISPLAYPORT_EMBEDDED    = 11,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EXTERNAL            = 12,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_UDI_EMBEDDED            = 13,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_SDTVDONGLE              = 14,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_MIRACAST                = 15,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_INTERNAL                = 0x80000000,
            DISPLAYCONFIG_OUTPUT_TECHNOLOGY_FORCE_UINT32            = 0xFFFFFFFF
        }

        public enum DISPLAYCONFIG_SCANLINE_ORDERING: uint
        {
            DISPLAYCONFIG_SCANLINE_ORDERING_UNSPECIFIED                 = 0,
            DISPLAYCONFIG_SCANLINE_ORDERING_PROGRESSIVE                 = 1,
            DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED                  = 2,
            DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_UPPERFIELDFIRST  = DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED,
            DISPLAYCONFIG_SCANLINE_ORDERING_INTERLACED_LOWERFIELDFIRST  = 3,
            DISPLAYCONFIG_SCANLINE_ORDERING_FORCE_UINT32                = 0xFFFFFFFF
        }

        public enum DISPLAYCONFIG_ROTATION: uint
        {
            DISPLAYCONFIG_ROTATION_IDENTITY     = 1,
            DISPLAYCONFIG_ROTATION_ROTATE90     = 2,
            DISPLAYCONFIG_ROTATION_ROTATE180    = 3,
            DISPLAYCONFIG_ROTATION_ROTATE270    = 4,
            DISPLAYCONFIG_ROTATION_FORCE_UINT32 = 0xFFFFFFFF
        }

        public enum DISPLAYCONFIG_SCALING: uint
        {
            DISPLAYCONFIG_SCALING_IDENTITY                  = 1,
            DISPLAYCONFIG_SCALING_CENTERED                  = 2,
            DISPLAYCONFIG_SCALING_STRETCHED                 = 3,
            DISPLAYCONFIG_SCALING_ASPECTRATIOCENTEREDMAX    = 4,
            DISPLAYCONFIG_SCALING_CUSTOM                    = 5,
            DISPLAYCONFIG_SCALING_PREFERRED                 = 128,
            DISPLAYCONFIG_SCALING_FORCE_UINT32              = 0xFFFFFFFF
        }

        public enum DISPLAYCONFIG_PIXELFORMAT : uint
        {
            DISPLAYCONFIG_PIXELFORMAT_8BPP          = 1,
            DISPLAYCONFIG_PIXELFORMAT_16BPP         = 2,
            DISPLAYCONFIG_PIXELFORMAT_24BPP         = 3,
            DISPLAYCONFIG_PIXELFORMAT_32BPP         = 4,
            DISPLAYCONFIG_PIXELFORMAT_NONGDI        = 5,
            DISPLAYCONFIG_PIXELFORMAT_FORCE_UINT32  = 0xffffffff
        }

        public enum DISPLAYCONFIG_MODE_INFO_TYPE : uint
        {
            DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1,
            DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2,
            DISPLAYCONFIG_MODE_INFO_TYPE_FORCE_UINT32 = 0xFFFFFFFF
        }

        public enum DISPLAYCONFIG_DEVICE_INFO_TYPE : uint
        {
              DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME             = 1,
              DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME             = 2,
              DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_PREFERRED_MODE   = 3,
              DISPLAYCONFIG_DEVICE_INFO_GET_ADAPTER_NAME            = 4,
              DISPLAYCONFIG_DEVICE_INFO_SET_TARGET_PERSISTENCE      = 5,
              DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_BASE_TYPE        = 6,
              DISPLAYCONFIG_DEVICE_INFO_FORCE_UINT32                = 0xFFFFFFFF
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct LUID
        {
            public uint LowPart;
            public int HighPart;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_PATH_SOURCE_INFO
        {
          public LUID adapterId;
          public uint id;
          public uint modeInfoIdx;
          public uint statusFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_PATH_TARGET_INFO
        {
            public LUID adapterId;
            public uint id;
            public uint modeInfoIdx;
            DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY   outputTechnology;
            DISPLAYCONFIG_ROTATION                  rotation;
            DISPLAYCONFIG_SCALING                   scaling;
            DISPLAYCONFIG_RATIONAL                  refreshRate;
            DISPLAYCONFIG_SCANLINE_ORDERING         scanLineOrdering;
            public bool targetAvailable;
            public uint statusFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_RATIONAL
        {
            public uint Numerator;
            public uint Denominator;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_PATH_INFO
        {
            public DISPLAYCONFIG_PATH_SOURCE_INFO sourceInfo;
            public DISPLAYCONFIG_PATH_TARGET_INFO targetInfo;
            public uint flags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_2DREGION
        {
            public uint cx;
            public uint cy;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_VIDEO_SIGNAL_INFO
        {
            public ulong pixelRate;
            public DISPLAYCONFIG_RATIONAL hSyncFreq;
            public DISPLAYCONFIG_RATIONAL vSyncFreq;
            public DISPLAYCONFIG_2DREGION activeSize;
            public DISPLAYCONFIG_2DREGION totalSize;
            public uint videoStandard;
            public DISPLAYCONFIG_SCANLINE_ORDERING scanLineOrdering;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_TARGET_MODE
        {
            public DISPLAYCONFIG_VIDEO_SIGNAL_INFO targetVideoSignalInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINTL
        {
            int x;
            int y;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_SOURCE_MODE
        {
            public uint width;
            public uint height;
            public DISPLAYCONFIG_PIXELFORMAT pixelFormat;
            public POINTL position;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct DISPLAYCONFIG_MODE_INFO_UNION
        {
            [FieldOffset(0)]
            public DISPLAYCONFIG_TARGET_MODE targetMode;
            [FieldOffset(0)]
            public DISPLAYCONFIG_SOURCE_MODE sourceMode;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_MODE_INFO
        {
            public DISPLAYCONFIG_MODE_INFO_TYPE infoType;
            public uint id;
            public LUID adapterId;
            public DISPLAYCONFIG_MODE_INFO_UNION modeInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS
        {
            public uint value;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct DISPLAYCONFIG_DEVICE_INFO_HEADER
        {
            public DISPLAYCONFIG_DEVICE_INFO_TYPE type;
            public uint size;
            public LUID adapterId;
            public uint id;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct DISPLAYCONFIG_TARGET_DEVICE_NAME
        {
            public DISPLAYCONFIG_DEVICE_INFO_HEADER header;
            public DISPLAYCONFIG_TARGET_DEVICE_NAME_FLAGS flags;
            public DISPLAYCONFIG_VIDEO_OUTPUT_TECHNOLOGY outputTechnology;
            public ushort edidManufactureId;
            public ushort edidProductCodeId;
            public uint connectorInstance;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string monitorFriendlyDeviceName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
            public string monitorDevicePath;
        }

        [DllImport("user32.dll")]
        public static extern int GetDisplayConfigBufferSizes(
            QUERY_DEVICE_CONFIG_FLAGS Flags, 
            out uint NumPathArrayElements, 
            out uint NumModeInfoArrayElements
        );

        [DllImport("user32.dll")]
        public static extern int QueryDisplayConfig(
            QUERY_DEVICE_CONFIG_FLAGS Flags, 
            ref uint NumPathArrayElements, 
            [Out] DISPLAYCONFIG_PATH_INFO[] PathInfoArray,
            ref uint NumModeInfoArrayElements,
            [Out] DISPLAYCONFIG_MODE_INFO[] ModeInfoArray,
            IntPtr CurrentTopologyId
        );

        [DllImport("user32.dll")]
        public static extern int DisplayConfigGetDeviceInfo(
            ref DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName
        );

        public static string MonitorFriendlyName(LUID adapterId, uint targetId)
        {
            DISPLAYCONFIG_TARGET_DEVICE_NAME deviceName = new DISPLAYCONFIG_TARGET_DEVICE_NAME();
            deviceName.header.size = (uint)Marshal.SizeOf(typeof(DISPLAYCONFIG_TARGET_DEVICE_NAME));
            deviceName.header.adapterId = adapterId;
            deviceName.header.id = targetId;
            deviceName.header.type = DISPLAYCONFIG_DEVICE_INFO_TYPE.DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
            int error = DisplayConfigGetDeviceInfo(ref deviceName);
            if (error != ERROR_SUCCESS)
                throw new Win32Exception(error);
            return deviceName.monitorFriendlyDeviceName;
        }

        static void Main(string[] args)
        {
            uint PathCount, ModeCount;
            int error = GetDisplayConfigBufferSizes(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
                out PathCount, out ModeCount);
            if (error != ERROR_SUCCESS)
                throw new Win32Exception(error);

            DISPLAYCONFIG_PATH_INFO[] DisplayPaths = new DISPLAYCONFIG_PATH_INFO[PathCount];
            DISPLAYCONFIG_MODE_INFO[] DisplayModes = new DISPLAYCONFIG_MODE_INFO[ModeCount];
            error = QueryDisplayConfig(QUERY_DEVICE_CONFIG_FLAGS.QDC_ONLY_ACTIVE_PATHS,
                ref PathCount, DisplayPaths, ref ModeCount, DisplayModes, IntPtr.Zero);
            if (error != ERROR_SUCCESS)
                throw new Win32Exception(error);

            for (int i = 0; i < ModeCount; i++) 
            {
                if (DisplayModes[i].infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET)
                {
                    Console.WriteLine(MonitorFriendlyName(DisplayModes[i].adapterId, DisplayModes[i].id));
                }
            }
            Console.ReadLine();
        }
    }
}

I've not tested this at all extensively and it's quite plausible that there are mistakes. It should get you on your way though.

Atropine answered 16/10, 2014 at 13:46 Comment(4)
i want get friendly namePirri
Perhaps you could edit the question to make it clear what you want. You asked how to call GetMonitorInfo.Atropine
its excellent, thanks) and one question especially for you. Did you know Everest/Aida alternative on c#? ThanksPirri
I don't know what they are. I don't even know these APIs I just translated the header to pinvoke.Atropine
K
1

Taking some of the PInvoke work done by @DavidHeffeman and some prior work on this I'd done, I have added the native signatures to the Vanara libraries along with some helper functions. Now by adding their NuGet packages you can do this work in very few lines of code.

using static Vanara.PInvoke.Gdi32;
using static Vanara.PInvoke.User32;
using static Vanara.PInvoke.User32_Gdi;

QueryDisplayConfig(QDC.QDC_ONLY_ACTIVE_PATHS, out var paths, out var modes, out var topId);
foreach (var mode in modes.Where(m => m.infoType == DISPLAYCONFIG_MODE_INFO_TYPE.DISPLAYCONFIG_MODE_INFO_TYPE_TARGET))
{ 
   Console.WriteLine(DisplayConfigGetDeviceInfo<DISPLAYCONFIG_TARGET_DEVICE_NAME>(mode.adapterId, mode.id).monitorFriendlyDeviceName);
}

Kalamazoo answered 25/2, 2019 at 2:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.