0

Question similar to my problem is asked here previously. But I assume this is unique .

I have my PC monitor and an extended monitor, I got the EDID and some data by this code :

ManagementObjectSearcher searcher =
   new ManagementObjectSearcher("root\\WMI", "SELECT * FROM WmiMonitorID");

foreach (ManagementObject queryObj in searcher.Get())
{
    dynamic snid = queryObj["SerialNumberID"];
    string serialnum = GetStringFromInt(snid);

    Console.WriteLine("SerialNumber:  {0}",serialnum);
    Console.WriteLine("YearOfManufacture: {0}", queryObj["YearOfManufacture"]);
    dynamic code = queryObj["ProductCodeID"];
    string pcid = GetStringFromInt(code);
    code = queryObj["ManufacturerName"];
    string manufactrName = GetStringFromInt(code);

    Console.WriteLine("ProductCodeID: " + pcid);
    Console.WriteLine("Manufacture: " + manufactrName);
}}

So I have Manufacture and ProductCodeID combined, which is something like ABC3401 and DEF4561 (I have two monitor). I need to move my application to DEF4561. I tried Move Form onto specified Screen but the name returns \\DISPLAY1 , \\DISPLAY2 etc. I need the ABC3401 strng to identify the monitor. I dont know how to combine these results.

Community
  • 1
  • 1
Zigma
  • 529
  • 6
  • 37
  • How can a product code identify a monitor? You have to write a function that returns the monitor number for a specific product id. – PMF Nov 14 '13 at 06:16
  • I am doing app for a specific monitor. – Zigma Nov 14 '13 at 06:23
  • You mean for a specific type of monitor? You nee to find a mapping between the serial numbers and the display ids. That should be available somewhere, but I don't know where, sorry. – PMF Nov 14 '13 at 07:59
  • You need to pinvoke EnumDisplayDevices() and find a match on the device ID. – Hans Passant Nov 19 '13 at 16:48

2 Answers2

1

To complete the answer, I am completing this. First, get the Details of monitor by the edokan's answer

    public struct DisplayInfo
    {
        public string DisplayID;
        public string DisplayName;
        public string EDID;
    }
     [DllImport("user32.dll")]
    static extern bool EnumDisplayDevices(string lpDevice, uint iDevNum, ref DISPLAY_DEVICE lpDisplayDevice, uint dwFlags);
     [DllImport("user32.dll")]
      [return: MarshalAs(UnmanagedType.Bool)]
      static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, SetWindowPosFlags uFlags);

    public static List<DisplayInfo> GetConnectedMonitorInfo()
    {
        var MonitorCollection = new List<DisplayInfo>();
        DISPLAY_DEVICE d = new DISPLAY_DEVICE();
        d.cb = Marshal.SizeOf(d);
        try
        {
            for (uint id = 0; EnumDisplayDevices(null, id, ref d, 0); id++)
            {

                EnumDisplayDevices(d.DeviceName, 0, ref d, 1);

                if (string.IsNullOrEmpty(d.DeviceName.ToString()) 
                        && string.IsNullOrEmpty(d.DeviceID.ToString())) continue; 

                var dispInfo = new DisplayInfo();
                dispInfo.DisplayID = id.ToString();
                dispInfo.DisplayName = d.DeviceName.ToString();
                dispInfo.EDID = d.DeviceID.ToString();

                if (d.DeviceID.ToString().Contains("ABC4562"))
                {
                    //Identify Multiple monitor of same series
                    if (string.IsNullOrEmpty(myMonitor.myMonDevName))
                    {
                        myMonitor.myMonDevName = d.DeviceName.ToString();
                    }
                    else
                    {
                        MultipleMonitorFound = true;
                    }

                }
                    MonitorCollection.Add(dispInfo);

                d.cb = Marshal.SizeOf(d);
            }
        }
        catch (Exception ex)
        {
           LogError(ex.ToString());
        }
        return MonitorCollection;
    }

Now we have the list of monitors and its details. Now need to change GUI to that monitor,

We need some params for the method :

        //I am Using WPF
        //For C# only, we can use GetActiveWindow() API.
        WindowInteropHelper winHelp = new WindowInteropHelper(this);
        ScreenObject sc = new ScreenObject();
        //Compare the name with screens
        sc.screen = sc.GetMyMonitor(myMonitor.myMonDevName);

The ScreenObject class is from Move form onto the specified screen answer.

    public static void MoveWindowToMonitor(IntPtr hWnd, int left, int top,double width, double height)
    {


        if (SetWindowPos(hWnd, (IntPtr)SpecialWindowHandles.HWND_TOP, left, top, (int)width, (int)height, SetWindowPosFlags.SWP_SHOWWINDOW))
           LogError( " :  Success");
        else
            LogError(" :  Failed");
    }

P/Invoke can help you there.

A note for C# WPF users :

If you use Windows Presentation Foundation you'll need WindowInteropHelper to get Window handle.

Make sure you referenced PresentationFramework assembly.

Insert this into Using block

using System.Windows.Interop;

Create instance of WindowInteropHelper

WindowInteropHelper winHelp = new WindowInteropHelper(target);

Then use winHelp.Handle insted of GetActiveWindowHandle().

Community
  • 1
  • 1
Zigma
  • 529
  • 6
  • 37
0

You must use EnumDisplayDevices to enumerate display devices and monitors attached to them, then you can match them.

Below is a shameless copy of the codes from pinvoke.net

[Flags()]
public enum DisplayDeviceStateFlags : int
{
    /// <summary>The device is part of the desktop.</summary>
    AttachedToDesktop = 0x1,
    MultiDriver = 0x2,
    /// <summary>The device is part of the desktop.</summary>
    PrimaryDevice = 0x4,
    /// <summary>Represents a pseudo device used to mirror application drawing for remoting or other purposes.</summary>
    MirroringDriver = 0x8,
    /// <summary>The device is VGA compatible.</summary>
    VGACompatible = 0x10,
    /// <summary>The device is removable; it cannot be the primary display.</summary>
    Removable = 0x20,
    /// <summary>The device has more display modes than its output devices support.</summary>
    ModesPruned = 0x8000000,
    Remote = 0x4000000,
    Disconnect = 0x2000000
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct DISPLAY_DEVICE 
{
      [MarshalAs(UnmanagedType.U4)]
      public int cb;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)]
      public string DeviceName;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
      public string DeviceString;
      [MarshalAs(UnmanagedType.U4)]
      public DisplayDeviceStateFlags StateFlags;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
      public string DeviceID;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=128)]
      public string DeviceKey;
}


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

void Main()
{
    DISPLAY_DEVICE d=new DISPLAY_DEVICE();
    d.cb=Marshal.SizeOf(d);
    try {
        for (uint id=0; EnumDisplayDevices(null, id, ref d, 0); id++) {
            Console.WriteLine(String.Format("{0}, {1}, {2}, {3}, {4}", id, d.DeviceName, d.DeviceString, d.StateFlags, d.DeviceID));
            
            EnumDisplayDevices(d.DeviceName, 0, ref d, 1);
            Console.WriteLine(String.Format("    {0}, {1}, {2}, {3}, {4}", id, d.DeviceName, d.DeviceString, d.StateFlags, d.DeviceID));                          
            d.cb=Marshal.SizeOf(d);
        }
    } catch (Exception ex) {
        Console.WriteLine(String.Format("{0}",ex.ToString()));
    }
}

It gives following output on my computer

0, \\.\DISPLAY1, ATI Radeon HD 5570, 134742017, PCI\VEN_1002&DEV_68D9&SUBSYS_E142174B&REV_00
    0, \\.\DISPLAY1\Monitor0, SyncMaster B2230 (Digital), AttachedToDesktop, MultiDriver, \\?\DISPLAY#SAM0635#5&15bb0574&0&UID256#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
1, \\.\DISPLAY2, ATI Radeon HD 5570, 134742021, PCI\VEN_1002&DEV_68D9&SUBSYS_E142174B&REV_00
    1, \\.\DISPLAY2\Monitor0, SyncMaster B2230 (Analog), AttachedToDesktop, MultiDriver, \\?\DISPLAY#SAM0635#5&15bb0574&0&UID257#{e6f07b5f-ee97-4a90-b076-33f57bf4eaa7}
2, \\.\DISPLAYV1, RDPDD Chained DD, 2097160, 
    2, , , 0, 
3, \\.\DISPLAYV2, RDP Encoder Mirror Driver, 2097160, 
    3, , , 0, 
4, \\.\DISPLAYV3, RDP Reflector Display Driver, 2097160, 
    4, , , 0, 
Erdogan Kurtur
  • 3,630
  • 21
  • 39
  • This gives the graphics card name., any option to ignore that? (I think ignore the first `console.writeLine()` right ? – Zigma Nov 22 '13 at 04:41
  • You must find the monitor you want by checking results of second api call. When you find what you look for than you should use its card name to match the `Screen` object you need – Erdogan Kurtur Nov 22 '13 at 07:09
  • card name : graphics card name? I think this is going to be the answer. Let me try – Zigma Nov 22 '13 at 07:21