8

我的 3.5 .NET Framework 程序处理多个监视器,所以我Screen.DeviceName用来区分不同的监视器(不能只比较对Screen对象实例的引用——不同的实例可以引用同一个屏幕)。

该程序在 Windows 7 上运行没有问题,但在安装了所有 .NET 框架的 Windows XP SP3 上,它会随机做一些奇怪的事情,好像它没有意识到两个给定的屏幕实际上是同一个屏幕,它应该能够认识到它们应该具有相同DeviceName的 s。

有什么问题,我该如何解决?

4

1 回答 1

14

框架或 Windows XP 中的某处似乎存在错误。

如果你Screen.DeviceName在 Windows 7 下转储 a ,你会得到类似的东西

\\.\DISPLAY1
\\.\DISPLAY2

但是如果你在 Windows XP 上做同样的事情,你会得到类似的东西

\\.\DISPLAY1 ????A??M?↕?☺ ?
\\.\DISPLAY2 ????☺ ? ☺?????

显然微软已经意识到了这个错误,所以他们在文档中写了一个注释:

此字符串可能包含不可打印的字符。

如果不可打印的字符每次都相同,那将是完全可以的。
但它们不是,因为事实上,它们是在终止空字符之后的垃圾随机内存内容。

如果只创建一个对象的缓存实例并多次Screen调用其属性,则每次的垃圾都是相同的,因为对象本身缓存了名称。但是如果你为每个请求创建一个新的对象实例,那么这些实例的垃圾很可能是不同的,即使它们引用的是同一个设备:DeviceNameScreenScreen

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'

于 2012-09-07T14:18:22.917 回答