问题:以编程方式断开连接并重新连接显示的最佳方法是什么?
目标:在显示屏上杀死视频输出(没有背光的黑屏),然后重新打开。想象一下,从显示器上拔下视频线,然后将其重新插入。
我的尝试:
// 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中的屏幕分辨率属性中:
注意:
参考文献:
答案 0 :(得分:1)
还有一个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
()并传递特定路径,确保从DISPLAYCONFIG_PATH_ACTIVE
结构标记整数中映射DISPLAY_PATH_INFO
。
http://msdn.microsoft.com/en-us/library/windows/hardware/ff553945(v=vs.85).aspx
很抱歉没有更多的帮助,但这是非常核心的东西,我花了很长时间才了解该API的基础知识。这是一个起点: - ),
看看如何在Win7中旋转特定监视器的示例:How do I set the monitor orientation in Windows 7?
老实说,只需将DisplaySwitch.exe包装为Win7,然后传递/ internal或/ external(取决于您是否要禁用/启用第一个/第二个监视器),这可能适用于> 2个监视器。
答案 1 :(得分:1)
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)使用this post的答案将 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();