System.Windows.Forms.Screen.DeviceName在Windows XP上提供了垃圾

时间:2012-09-07 14:16:40

标签: c# .net winforms windows-xp screen

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

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

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

1 个答案:

答案 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上运行此代码段,您将获得类似的内容:

enter image description here

请注意您在这里至少有三个DeviceName版本。

相反,在Windows 7上,垃圾部分将被剥离。

这就是代码无法识别屏幕的原因 - 设备名称每次都不同。

要解决此问题,请在第一个DeviceName字符后裁剪'\0'字符串。