My 3.5 .NET Framework program handles multiple monitors, so I use Screen.DeviceName
to distinguish between different monitors (can't just compare references to the instances of the Screen
object -- different instances can refer to the same screen).
The program works no problem on Windows 7, but on Windows XP SP3 with all .NET frameworks installed it would randomly do strange things, as if it failed to realise that the two given screens are in fact the same screen, which it should be able to recognize as they should have identical DeviceName
s.
What is the problem and how do I fix it?
There appears to be a bug somewhere in the framework or in Windows XP.
If you dump a Screen.DeviceName
under Windows 7, you will get something like
\\.\DISPLAY1 \\.\DISPLAY2
But if you do the same on Windows XP, you will get something like
\\.\DISPLAY1 ????A??M?↕?☺ ? \\.\DISPLAY2 ????☺ ? ☺ ?????
Apparently Microsoft was aware of the bug, so they put a note in the documentation:
This string may contain non-printable characters.
And that would be perfectly okay if the non-printable characters were the same each time.
But they are not, because in fact, they are garbage, random memory contents that goes after the terminating null character.
If you create just one cached instance of the Screen
object and call its DeviceName
property several times, the garbage will be the same each time, because the Screen
object caches the name in itself. But if you create a new instance of the Screen
object for each request, then the garbage is likely to be different for these instances, even if they refer to the same device:
System.Windows.Forms.Screen s = null;
System.Drawing.Point p = new System.Drawing.Point(0,0);
Console.WriteLine("Using same instance of Screen:");
s = System.Windows.Forms.Screen.FromPoint(p);
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(s.DeviceName);
}
Console.WriteLine();
Console.WriteLine("Using new instance of Screen:");
for (int i = 0; i < 5; ++i)
{
Console.WriteLine(System.Windows.Forms.Screen.FromPoint(p).DeviceName);
}
If you run this snippet on Windows XP, you will get something like:
Note how you have at least three versions of DeviceName
here.
On Windows 7, on contrary, the garbage part will be stripped out.
This is why the code fails to recognize screens -- device names are different each time.
To fix that, crop the DeviceName
string after the first '\0'
character.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With