如何在 Windows 中强制显示检测?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3858844/
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-09-15 15:21:53  来源:igfitidea点击:

How can I force display detection in Windows?

c#windowswinapimonitor

提问by Martin Wiboe

I often boot my Windows 7 PC with the attached KVM switch focused on another computer. When I switch to the booted PC, the display resolution is wrong (and the second attached monitor is not detected).

我经常使用附加的 KVM 切换器启动我的 Windows 7 PC,该切换器专注于另一台计算机。当我切换到启动的 PC 时,显示分辨率错误(并且未检测到第二个连接的显示器)。

I can correct this by right-clicking the desktop, choosing Screen Resolutionand clicking Detect. This makes Windows detect attached displays and adjust to the most optimal resolution.

我可以通过右键单击桌面,选择Screen Resolution并单击来更正此问题Detect。这使得 Windows 检测连接的显示器并调整到最佳分辨率。

I would like to write a small utility to do this automatically. Which Win32 API call or C# object should I use?

我想编写一个小实用程序来自动执行此操作。我应该使用哪个 Win32 API 调用或 C# 对象?

采纳答案by Marlon

You can try:

你可以试试:

  1. You can use Spy++ to search for the windows that are open and take a look at their properties and messages.
  2. Use process to start "rundll32.exe shell32.dll,Control_RunDLL desk.cpl" or experiment with calling it directly to see if you can get a window handle, check below link for ideas.
  3. Use the code "send button click to external app"and modify it to search for a window with caption "Screen Resolution" and send a BN_CLICK to the childwindow with the caption "Detect".
  4. Since the computer is already on you might want to fire it up automatically on logon, for that use the task scheduler.
  1. 您可以使用 Spy++ 搜索打开的窗口并查看它们的属性和消息。
  2. 使用进程启动“rundll32.exe shell32.dll,Control_RunDLL desk.cpl”或尝试直接调用它以查看是否可以获得窗口句柄,查看以下链接以获取想法。
  3. 使用代码“发送按钮单击到外部应用程序”并修改它以搜索标题为“屏幕分辨率”的窗口,并将 BN_CLICK 发送到标题为“检测”的子窗口。
  4. 由于计算机已经打开,您可能希望在登录时自动启动它,为此请使用任务计划程序。

回答by Neal Tibrewala

This will get you half-way there:

这会让你半途而废:

Execute: control.exe desk.cpl,Settings,@Settings

执行:control.exe desk.cpl,Settings,@Settings

That will bring up the Screen Resolution panel directly.

这将直接调出屏幕分辨率面板。

I might also suggest a scripting tool like http://en.wikipedia.org/wiki/Windows_Script_HostAnd write a utility that'll open the panel and click the button.

我也可能会建议使用像http://en.wikipedia.org/wiki/Windows_Script_Host这样的脚本工具 并编写一个实用程序来打开面板并单击按钮。

Barring that it's possible that the control panel directly calls into a windows .dll which you can load and invoke in code directly, but that would require some sleuthing to detect. (you can start by running the .cpl in a debugger and see what happens when you click the detect).

除非控制面板可能直接调用 Windows .dll,您可以直接加载和调用代码,但这需要一些侦查来检测。(您可以首先在调试器中运行 .cpl 并查看单击检测时会发生什么)。

回答by ander

Why not just use Do It Againand write a macro that resets the resolution for you by recording your mouse and keyboard actions?

为什么不直接使用Do It Again并编写一个宏,通过记录您的鼠标和键盘操作来为您重置分辨率?

回答by Ray Henry

Not sure if this will work for you, but you can try something like this. At least it can get you started.

不确定这是否适合你,但你可以尝试这样的事情。至少它可以让你开始。

[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 714)]
public struct DISPLAY_DEVICE
{
    [FieldOffset(0)]
    public int cb;
    [FieldOffset(4)]
    public char DeviceName;
    [FieldOffset(68)]
    public char DeviceString;
    [FieldOffset(324)]
    public int StateFlags;
    [FieldOffset(328)]
    public char DeviceID;
    [FieldOffset(584)]
    public char DeviceKey;
}

[DllImport("User32.dll", SetLastError = true)]
static extern Boolean EnumDisplayDevices(
        string lpDevice,
        uint iDevNum,
        ref DISPLAY_DEVICE lpDisplayDevice,
        uint dwFlags
);

public void DetectDevices()
{
    var flag = true;
    for (uint i = 0; flag && i < 100; i++)
    {
        var device = new DISPLAY_DEVICE();
        device.cb = Marshal.SizeOf(device);
        flag = EnumDisplayDevices(null, i, ref device, 1);
    }
}