Screen.AllScreen 未给出正确的显示器计数
我在我的程序中做了这样的事情:
Int32 currentMonitorCount = Screen.AllScreens.Length;
if (currentMonitorCount < 2)
{
//Put app in single screen mode.
}
else
{
//Put app in dual screen mode.
}
我的应用程序识别当前连接的显示器数量非常重要。
但是,在我插拔显示器几次后,Screen.AllScreens.Length 始终返回“2”。
我的显示器知道它没有连接(它已进入“省电”模式),并且控制面板知道它没有连接(它只显示一台显示器)。
那么我错过了什么? 我如何知道只有一台显示器?
I am doing something like this in my program:
Int32 currentMonitorCount = Screen.AllScreens.Length;
if (currentMonitorCount < 2)
{
//Put app in single screen mode.
}
else
{
//Put app in dual screen mode.
}
It is VERY important my application recognizes how many monitors are currently connected.
However, after I plug/unplug the monitor a couple of times, Screen.AllScreens.Length always returns '2'.
My monitor knows it's not connected (it has entered 'power save' mode), and the control panel knows that it's not connected (it shows only one monitor).
So what am I missing? How do I figure out that there's only one monitor?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我查看了源代码(记住我们可以使用 MS Symbol 服务器来做到这一点)。 AllScreens 使用非托管 API 在第一次访问时获取屏幕,然后将结果存储在静态变量中以供以后使用。
这样做的结果是,如果程序运行时监视器的数量发生变化;那么
Screen.AllScreens
将不会接受更改。解决这个问题的最简单方法可能是调用非托管 API直接地。
(或者你可能是邪恶的,在询问之前使用反射将静态
screens
字段设置为 null。不要这样做)。编辑:
如果您只需要知道计数,请在使用 P/Invoke 路线之前检查是否可以使用 System.Windows.Forms.SystemInformation.MonitorCount (如注释中建议的那样)。这直接调用GetSystemMetrics,并且它可能已正确更新。
如果您发现需要使用 P/Invoke 来执行此操作,这里有一个完整的示例,演示了 C# 中非托管 API 的用法:
I had a look at the source (remember we can do that using the MS Symbol servers). AllScreens uses an unmanaged API to get the screens on the first access, then stores the result in a static variable for later use.
The consequence of this, is that if the number of monitors changes while your program is running; then
Screen.AllScreens
will not pick up the change.The easiest way to get around this would probably be to call the unmanaged API directly.
(Or you could be evil, and use reflection to set the static
screens
field to null before asking. Don't do that).Edit:
If you just need to know the count, check whether you can use
System.Windows.Forms.SystemInformation.MonitorCount
(as suggested in the comments) before going the P/Invoke route. This calls GetSystemMetrics directly, and it is probably correctly updated.If you find you need to do it using P/Invoke, here is a complete example that demonstrates the usage of the unmanaged API from C#:
根据 driis 之前的回复,这就是我的处理方式。我应该注意到以下代码位于我的 Program.cs 文件中。
首先是到外部资源和数据结构的链接:
现在创建一个简单的对象来包含监视器信息:
以及一个保存这些对象的容器:
以及刷新容器的方法:
然后在表单上,如果我想检测显示已添加或删除......
其中可能有一些拼写错误,但这是基本思想。祝你好运!
Building on the previous reply by driis, this is how I handled it. I should note that the following code lives in my Program.cs file.
First the links to external resources and data structures:
Now create a simple object to contain monitor information:
And a container to hold these objects:
and a method to refresh the container:
Then later on a Form, If I wanted to detect that a display had been added or removed ...
Might be a few typos in there, but that is the basic idea. Good luck!
我查看了 Screen 类的代码(在 这里 )
参见第120行,Screen.AllScreens使用字段Screen.screens进行缓存。
在我的解决方案中,我使用反射 api 来更改 Screen 类。
我在调用 Screen.AllScreens 之前清除 Screens.screens。
I had a look at the code of the Screen class ( in here )
See line 120, Screen.AllScreens uses the field Screen.screens for cache.
In my solution, I use the reflection api to change the Screen class.
I clear Screens.screens before calling Screen.AllScreens.
我的笔记本电脑运行 1920x1080 32 BitsPerPixel,配有 4k 50 英寸电视和 4k 32 英寸电视。
另请查看 - 将屏幕捕获为位图
I have My laptop running 1920x1080 32 BitsPerPixel with a 4k 50-inch tv and a 4k 32-inch tv.
Also check this out - Capture the Screen into a Bitmap