Reputation: 529
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.
Upvotes: 0
Views: 1808
Reputation: 3685
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,
Upvotes: 0
Reputation: 529
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().
Upvotes: 1