c++ - cpp如何关闭特定的监视器?

标签 c++ winapi

我知道如何关闭所有显示器

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

但我想只转一个。

最佳答案

正如我上面提到的 - 它需要使用 lowlevelmonitorconfigurationapi 库。

以下代码是关于如何为所有显示器创建独立屏保的示例。

#include <lowlevelmonitorconfigurationapi.h>
#include <windows.h>

const BYTE PowerMode = 0xD6;
const DWORD PowerOn = 0x01;
const DWORD PowerOff = 0x04;

/*
 * Monitor description struct
 */
struct MonitorDesc
{
    HANDLE hdl;
    RECT rc;
    DWORD lastTick;
    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;
                desc.rc = *lprcMonitor;

                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;
}

/*
 * Main
 */
int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
    // Idle time
    DWORD IdleTime = 10 * 60 * 1000;

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

    DWORD tick = GetTickCount();

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

    // Last cursor position
    POINT lastPos;
    GetCursorPos(&lastPos);

    while(1)
    {
        DWORD tick = GetTickCount();

        POINT pt;
        GetCursorPos(&pt);

        // Check cursor move
        bool move = false;
        if(pt.x != lastPos.x || pt.y != lastPos.y)
        {
            move = true;
        }

        lastPos = pt;

        if(move)
        {
            // Check which monitor status should be updateted
            for(auto& monitor : monitors)
            {
                if(pt.x >= monitor.rc.left && pt.x < monitor.rc.right && pt.y >= monitor.rc.top && pt.y < monitor.rc.bottom)
                {
                    monitor.lastTick = tick;
                    break;
                }
            }
        }

        for(auto& monitor : monitors)
        {
            // Check idle time
            DWORD delta = (tick - monitor.lastTick);
            if(delta >= IdleTime)
            {
                // turn off
                if(monitor.power == PowerOn)
                {
                    MonitorSwitch(monitor, PowerOff);
                }
            }
            else
            {
                // turn on
                if(monitor.power == PowerOff)
                {
                    MonitorSwitch(monitor, PowerOn);
                }
            }
        }
        Sleep(50);
    }

    return 0;
}

关于c++ - cpp如何关闭特定的监视器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32847726/

相关文章:

c++ - 使用花括号而不是括号时 Visual Studio 会中断

c++ - 读取解码后的 JSON Lua 表

c - 使用不带名称修饰的 __stdcall 的 DLL : why does it even work?

winapi - 在 Windows API 中设置菜单的宽度

C++ WinAPI 使用 DWM 在自定义窗口框架上显示位图

c++ - Qt C++ 继续一个文件而不是覆盖

c++ - 创建字符串到函数 vector 的 HashMap

使用正则表达式时 C++ 程序崩溃

c++ - 如何快速制作只有两层的宽虚拟 TreeView 控件?

winapi - 为 win32 API 创建上下文菜单