关于winapi:C#如何关闭特定的监视器?

C# How to turn off specific monitor?

我知道如何使用user32.dll打开/关闭所有监视器。

1
2
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM) -1);
SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)  2);

但是我只想打开/关闭一个。


您始终可以从nirsoft运行ControlMyMonitor.exe。

从1.20版开始,您可以使用以下方法打开和关闭显示器:

1
ControlMyMonitor.exe /SwitchValue"\\\\.\\DISPLAY1\\Monitor0" D6 1 5

@Dai是正确的。使用低级监视器配置功能可以关闭指定的监视器。

下面是选择一台显示器并在5秒钟后将其关闭后将其关闭的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <windows.h>
#include <vector>
#include <lowlevelmonitorconfigurationapi.h>

#pragma comment(lib,"Dxva2.lib")

const BYTE PowerMode = 0xD6;  // VCP Code defined in VESA Monitor Control Command Set (MCCS) standard
const DWORD PowerOn = 0x01;
const DWORD PowerOff = 0x04;

// Monitor description struct
struct MonitorDesc
{
    HANDLE hdl;
    DWORD power;
};

// Monitor enumeration callback
BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData)
{
    std::vector<MonitorDesc>* pMonitors = reinterpret_cast<std::vector<MonitorDesc>*>(dwData);

    DWORD nMonitorCount;
    if (GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &nMonitorCount))
    {
        PHYSICAL_MONITOR* pMons = new PHYSICAL_MONITOR[nMonitorCount];

        if (GetPhysicalMonitorsFromHMONITOR(hMonitor, nMonitorCount, pMons))
        {
            for (DWORD i = 0; i < nMonitorCount; i++)
            {
                MonitorDesc desc;
                desc.hdl = pMons[i].hPhysicalMonitor;

                pMonitors->push_back(desc);
            }
        }
        delete[] pMons;
    }
    return TRUE;
}

// Switch monitor power
void MonitorSwitch(MonitorDesc& monitor, DWORD mode)
{
    if (monitor.power == mode)
        return;

    SetVCPFeature(monitor.hdl, PowerMode, mode);
    monitor.power = mode;
}

int main()
{
    std::vector<MonitorDesc> monitors;
    EnumDisplayMonitors(NULL, NULL, &MonitorEnumProc, reinterpret_cast<LPARAM>(&monitors));

    // Init
    for (auto& monitor : monitors)
    {
        monitor.power = PowerOn;
    }

    // Here select the first one monitor as example
    MonitorDesc targetMonitor = monitors[0];

    // turn off
    if (targetMonitor.power == PowerOn)
    {
        MonitorSwitch(targetMonitor, PowerOff);
    }

    Sleep(5000);

    // turn on
    if (targetMonitor.power == PowerOff)
    {
        MonitorSwitch(targetMonitor, PowerOn);
    }
}