[英]Disconnect and Reconnect Displays Programmatically
问题:以编程方式以编程方式断开连接和重新连接显示的最佳方法是什么?
目标:在显示器上杀死视频输出(没有背光的黑屏),然后再将其重新打开。 想象一下,从显示器上拔下视频线,然后将其重新插入。
我的尝试:
// Get the monitor to disable
uint iDevNum = 0;
DISPLAY_DEVICE displayDevice = new DISPLAY_DEVICE();
displayDevice.cb = Marshal.SizeOf(displayDevice);
EnumDisplayDevices(null, iDevNum, ref displayDevice, 0))
DEVMODE devMode = new DEVMODE();
EnumDisplaySettings(displayDevice.DeviceName, 0, ref devMode);
//
// Do something here to disable this display device!
//
// Save the display settings
ChangeDisplaySettingsEx(displayDevice.DeviceName, ref devMode,
IntPtr.Zero, ChangeDisplaySettingsFlags.CDS_NONE, IntPtr.Zero);
我可以与每个显示器进行交互,但我无法弄清楚如何断开连接。
它类似于Windows 7中屏幕分辨率属性中的“断开此显示”:
笔记:
参考文献:
有一个github项目,我仍然没有,但它是一个起点。 您需要使用Win7特定的API才能更改设置 。 ChangeDisplaySettings无效。
看看: https : //github.com/ChrisEelmaa/MultiMonitorHelper
这是你需要做的:
更新IDisplay
接口以支持TurnOff()方法,
然后调用它:
var displayModel = DisplayFactory.GetDisplayModel();
var displayList = displayModel.GetActiveDisplays().ToList();
var firstDisplay = displayList[0].TurnOff();
如何实现TurnOff()? 我想象这就是(我现在可能在这里错了):
您需要通过打破“路径”来打破GPU和监视器之间的连接。 你可以像这样打破源和目标之间的路径:
调用SetDisplayConfig
()并传递特定路径,并确保从DISPLAY_PATH_INFO
结构标记整数中映射出DISPLAYCONFIG_PATH_ACTIVE
。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553945(v=vs.85).aspx
很抱歉没有更多的帮助,但这是非常核心的东西,我花了很长时间甚至了解该API的基础知识。 这是一个起点:-),
看看如何在Win7中旋转特定监视器的示例: 如何在Windows 7中设置监视器方向?
老实说,只需将DisplaySwitch.exe包装为Win7,然后传递/ internal或/ external(取决于您是否要禁用/启用第一个/第二个监视器),这可能适用于> 2个监视器,也可能不适用。
1)从这里获取MultiMonitorHelper : https : //github.com/ChrisEelmaa/MultiMonitorHelper/tree/master
2)扩展Win7Display以断开显示 :
using MultiMonitorHelper.DisplayModels.Win7.Enum;
using MultiMonitorHelper.DisplayModels.Win7.Struct;
/// <summary>
/// Disconnect a display.
/// </summary>
public void DisconnectDisplay(int displayNumber)
{
// Get the necessary display information
int numPathArrayElements = -1;
int numModeInfoArrayElements = -1;
StatusCode error = CCDWrapper.GetDisplayConfigBufferSizes(
QueryDisplayFlags.OnlyActivePaths,
out numPathArrayElements,
out numModeInfoArrayElements);
DisplayConfigPathInfo[] pathInfoArray = new DisplayConfigPathInfo[numPathArrayElements];
DisplayConfigModeInfo[] modeInfoArray = new DisplayConfigModeInfo[numModeInfoArrayElements];
error = CCDWrapper.QueryDisplayConfig(
QueryDisplayFlags.OnlyActivePaths,
ref numPathArrayElements,
pathInfoArray,
ref numModeInfoArrayElements,
modeInfoArray,
IntPtr.Zero);
if (error != StatusCode.Success)
{
// QueryDisplayConfig failed
}
// Check the index
if (pathInfoArray[displayNumber].sourceInfo.modeInfoIdx < modeInfoArray.Length)
{
// Disable and reset the display configuration
pathInfoArray[displayNumber].flags = DisplayConfigFlags.Zero;
error = CCDWrapper.SetDisplayConfig(
pathInfoArray.Length,
pathInfoArray,
modeInfoArray.Length,
modeInfoArray,
(SdcFlags.Apply | SdcFlags.AllowChanges | SdcFlags.UseSuppliedDisplayConfig));
if (error != StatusCode.Success)
{
// SetDisplayConfig failed
}
}
}
3)使用此帖子的答案扩展Win7Display以重新连接显示 :
using System.Diagnostics;
/// <summary>
/// Reconnect all displays.
/// </summary>
public void ReconnectDisplays()
{
DisplayChanger.Start();
}
private static Process DisplayChanger = new Process
{
StartInfo =
{
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden,
FileName = "DisplaySwitch.exe",
Arguments = "/extend"
}
};
4)更新IDisplay中的方法。
5)实施方法:
IDisplayModel displayModel = DisplayFactory.GetDisplayModel();
List<IDisplay> displayList = displayModel.GetActiveDisplays().ToList();
displayList[0].DisconnectDisplay(0);
displayList[0].ReconnectDisplays();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.