我的3.5 .NET Framework程序处理多个监视器,因此我使用Screen.DeviceName
来区分不同的监视器(不能仅仅比较对Screen
对象实例的引用 - 不同的实例可以参考同一个屏幕。)
该程序在Windows 7上没有问题,但在安装了所有.NET框架的Windows XP SP3上,它会随机做一些奇怪的事情,好像它没有意识到两个给定的屏幕实际上是同一个屏幕,它应该能够识别出它们应该具有相同的DeviceName
s。
问题是什么,我该如何解决?
答案 0 :(得分:14)
框架或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上运行此代码段,您将获得类似的内容:
请注意您在这里至少有三个DeviceName
版本。
相反,在Windows 7上,垃圾部分将被剥离。
这就是代码无法识别屏幕的原因 - 设备名称每次都不同。
要解决此问题,请在第一个DeviceName
字符后裁剪'\0'
字符串。