框架或 Windows XP 中的某处似乎存在错误。
如果你在 Windows 7 下转储 Screen.DeviceName,你会得到类似的东西
\\.\DISPLAY1
\\.\DISPLAY2
但是如果你在 Windows XP 上做同样的事情,你会得到类似的东西
\\.\DISPLAY1 ????A??M?↕?☺ ?
\\.\DISPLAY2 ????☺ ? ☺ ?????
显然微软已经意识到了这个错误,所以他们在documentation 中写了一个注释:
此字符串可能包含不可打印的字符。
如果不可打印的字符每次都相同,那就完全没问题了。
但它们不是,因为事实上,它们是垃圾,随机内存内容终止空字符。
如果您只创建一个Screen 对象的缓存实例并多次调用其DeviceName 属性,则每次垃圾都将相同,因为Screen 对象本身缓存了名称。但是,如果您为每个请求创建一个 Screen 对象的新实例,那么这些实例的垃圾可能会有所不同,即使它们引用的是同一个设备:
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);
}
如果你在 Windows XP 上运行这个 sn-p,你会得到类似的东西:
请注意您在此处如何拥有至少三个版本的DeviceName。
相反,在 Windows 7 上,垃圾部分会被剔除。
这就是代码无法识别屏幕的原因——设备名称每次都不同。
要解决此问题,请在第一个 '\0' 字符之后裁剪 DeviceName 字符串。