如何在 C# 中启用第二个监视器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/233411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:12:02  来源:igfitidea点击:

How do I enable a second monitor in C#?

c#winformsdesktopmultiple-monitors

提问by Matt Warren

Is it possible to enable a second monitor programatically and extend the Windows Desktop onto it in C#? It needs to do the equivalent of turning on the checkbox in the image below.

是否可以以编程方式启用第二个监视器并在 C# 中将 Windows 桌面扩展到它上?它需要做相当于打开下图中的复选框。

alt text

替代文字

采纳答案by Pop Catalin

MSDN Device Context Functions

MSDN 设备上下文函数

What you basically need to do:

你基本上需要做的:

Use the EnumDisplayDevices() API call to enumerate the display devices on the system and look for those that don't have the DISPLAY_DEVICE_ATTACHED_TO_DESKTOPflag set (this will include any mirroring devices so not all will be physical displays.) Once you've found the display device you'll need to get a valid display mode to change it to, you can find this by calling the EnumDisplaySettingsEx() API call - Generally you'd display all the available modes and allow the user to choose however in your case it sounds like this may be possible to hard-code and save you an additional step. For the sake of future-proofing your application though I'd suggest having this easily changeable without having to dig through the source every time, a registry key would be the obvious choice. Once you've got that sorted out populate a DevMode display structure with the information about the display positioning (set the PelsWidth/Height, Position, DisplayFrequency and BitsPerPel properties) then set these flags in the fields member. Finally call ChangeDisplaySettingsEx() with this settings structure and be sure to send the reset and update registry flags. That should be all you need, hope this helps,

使用 EnumDisplayDevices() API 调用枚举系统上的显示设备并查找那些没有 DISPLAY_DEVICE_ATTACHED_TO_DESKTOP标志设置(这将包括任何镜像设备,因此并非所有设备都是物理显示器。)找到显示设备后,您需要获得有效的显示模式才能将其更改为,您可以通过调用 EnumDisplaySettingsEx( ) API 调用 - 通常,您会显示所有可用模式并允许用户进行选择,但是在您的情况下,这听起来可能可以进行硬编码并为您节省一个额外的步骤。为了使您的应用程序面向未来,尽管我建议您可以轻松更改它而不必每次都挖掘源代码,但注册表项将是显而易见的选择。一旦你搞定了,用关于显示定位的信息填充一个 DevMode 显示结构(设置 PelsWidth/Height、Position、DisplayFrequency 和 BitsPerPel 属性)然后在字段成员中设置这些标志。最后使用此设置结构调用 ChangeDisplaySettingsEx() 并确保发送重置和更新注册表标志。这应该是你所需要的,希望这有帮助,

DISPLAY_DEVICEstructure import using PInvoke

使用 PInvoke 导入DISPLAY_DEVICE结构

EnumDisplayDevicesfunction import

EnumDisplayDevices函数导入

EnumDisplaySettingsExfunction import

EnumDisplaySettingsEx函数导入

etc. the rest of them functions can be found with a simple search by name.

等等。其余的功能可以通过简单的名称搜索找到。

回答by Timbo

I don't have the full answer here but I am almost sure that you will have to call out of .Net to do this. You will have to use Pinvoke to call an unmanaged dll. A great resource for this is pinvoke.net.

我在这里没有完整的答案,但我几乎可以肯定,您将不得不调用 .Net 来执行此操作。您将不得不使用 Pinvoke 来调用非托管 dll。这方面的一个很好的资源是 pinvoke.net。

I did a quick search and found http://www.pinvoke.net/default.aspx/user32/ChangeDisplaySettings.htmlwhich probably isn't exactly what you want but you will probably find it somewhere on pinvoke.net

我进行了快速搜索,发现http://www.pinvoke.net/default.aspx/user32/ChangeDisplaySettings.html这可能不是您想要的,但您可能会在 pinvoke.net 上的某个地方找到它

回答by Pop Catalin

I am looking for the same solution. I have written the following code to call ChangeDisplaySettingsExwith PInvoke:

我正在寻找相同的解决方案。我编写了以下代码以ChangeDisplaySettingsEx使用 PInvoke进行调用:

DEVMODE dm = new DEVMODE();
dm.dmSize = (short)Marshal.SizeOf(dm);
dm.dmPelsWidth = 1680;
dm.dmPelsHeight = 1050;
dm.dmBitsPerPel = 32;
dm.dmDisplayFrequency = 60;
dm.dmFields = DevModeFields.DM_BITSPERPEL | DevModeFields.DM_PELSWIDTH | 
              DevModeFields.DM_PELSHEIGHT | DevModeFields.DM_DISPLAYFREQUENCY;
int res = ChangeDisplaySettingsEx(@"\.\DISPLAY2", ref dm, IntPtr.Zero, CDS_RESET | CDS_UPDATEREGISTRY, IntPtr.Zero);
Console.WriteLine("result = " + res.ToString());

If the monitor is already enabled, this changes the resolution successfully. But if the monitor isn't attached to the desktop already, this won't activate it. So does anyone have a code example that works?

如果监视器已启用,这将成功更改分辨率。但是,如果显示器尚未连接到桌面,则不会激活它。那么有人有一个有效的代码示例吗?

回答by Robert Baker

If you have windows 7, then just start a process:

如果您有 Windows 7,那么只需启动一个进程:

    private static Process DisplayChanger = new Process
    {
        StartInfo =
        {
            CreateNoWindow = true,
            WindowStyle = ProcessWindowStyle.Hidden,
            FileName = "DisplaySwitch.exe",
            Arguments = "/extend"
        }
    };

then DisplayChanger.Start();

然后 DisplayChanger.Start();

回答by user

To enable a monitor, set its position to something other than 0,0, like as shown:

要启用监视器,请将其位置设置为 0,0 以外的值,如下所示:

POINTL enabledPosition = new POINTL();
enabledPosition.x = -1280;
enabledPosition.y = 0;

dm.dmPosition = enabledPosition;
dm.dmFields = DM.Position;
res = ChangeDisplaySettingsEx(d.DeviceName, ref dm, IntPtr.Zero, (uint) DeviceFlags.CDS_UPDATEREGISTRY, IntPtr.Zero);