Como colocar o Windows para dormir quando o monitor (HDMI) está desligado?

5

Eu tenho um HTPC (Intel NUC) conectado à TV via HDMI. É possível colocar o Windows para dormir quando a TV está desligada?

Parece que o Windows possui detecção integrada para quando o monitor está desligado; talvez exponha uma API para isso? Eu estou bem em ter que codificar a solução sozinho.

    
por Knaģis 25.05.2014 / 22:21

2 respostas

1

Eu encontrei esta postagem no fórum , que contém o código C ++. Eu não tentei ainda.

Você precisa de um compilador para fazer isso funcionar.

#include <windows.h>
#include <setupapi.h>

#ifdef _MSC_VER
#pragma comment(lib, "Setupapi.lib")
#endif

#include <list>
#include <vector>
#include <string>
using namespace std;

// my StlPort configured w/o iostreams at the moment
#include <stdio.h> 

//------------------------------------------------------------------------------

struct DevData
{
    std::wstring Description;  // SPDRP_DEVICEDESC
    CM_POWER_DATA PowerData;   // SPDRP_DEVICE_POWER_DATA

    DevData() 
    {
        PowerData.PD_Size = sizeof(PowerData);
    }//constructor
};//DevData

//------------------------------------------------------------------------------

bool GetDeviceRegString(HDEVINFO infoSet, SP_DEVINFO_DATA *pinfoData, 
                        DWORD prop, wstring &val)
{
    DWORD req_sz = 0;
    BOOL res = SetupDiGetDeviceRegistryPropertyW(infoSet, pinfoData, prop,
                                                 0, 0, 0, &req_sz);
    if (!res && (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
    {
        if (GetLastError() != ERROR_INVALID_DATA)
        {
            printf("SetupDiGetDeviceRegistryPropertyW() failed, le = &#37;u",
                   GetLastError());
        }//if

        return false;
    }//if

    vector<wchar_t> vec_buff; // in case we have to go to the heap
    wchar_t auto_buff[512];

    DWORD buff_sz;
    wchar_t *buff;
    if (req_sz > sizeof(auto_buff))
    {
        vec_buff.reserve(req_sz/2 + 2);
        buff = &vec_buff[0];
        buff_sz = req_sz;
    }//if
    else
    {
        buff = auto_buff;
        buff_sz = sizeof(auto_buff);
    }//else

    res = SetupDiGetDeviceRegistryPropertyW(infoSet, pinfoData, prop,
                                            0, (PBYTE)buff, buff_sz, 0);
    if (!res)
    {
        DWORD le = GetLastError();
        if (le != ERROR_INVALID_DATA)
        {
            printf("SetupDiGetDeviceRegistryPropertyW(%d) "
                   "failed, le = %u",
                   prop, le);
            return false;
        }//if

        // return empty string on ERROR_INVALID_DATA
        val.erase(val.begin(), val.end());
        return true;
    }//else

    val.assign(buff, req_sz);
    return true;
}//GetDeviceRegString

//------------------------------------------------------------------------------

template <typename T>
bool GetDeviceRegData(HDEVINFO infoSet, SP_DEVINFO_DATA *pinfoData, 
                        DWORD prop, T &val)
{
    SetLastError(0);
    BOOL res = SetupDiGetDeviceRegistryPropertyW(infoSet, pinfoData, prop,
                                                 0, (PBYTE)&val, 
                                                 sizeof(val), 0);
    DWORD le = GetLastError();
    if (!res || (le == ERROR_INVALID_DATA))
    {
        if (le != ERROR_INVALID_DATA)
            printf("GetDeviceRegData() failed, le = %u", le);
        return false;
    }//if

    return true;
}//GetDeviceRegData

//------------------------------------------------------------------------------

void ListDeviceClassData(const GUID *classGuid, std::list<DevData> &devList)
{
    devList.clear();

    const DWORD flags = DIGCF_PRESENT;
    HDEVINFO infoSet = SetupDiGetClassDevsW(classGuid, 0, 0, flags);
    if (infoSet == INVALID_HANDLE_VALUE)
    {
        printf("SetupDiGetClassDevs() failed, le = %u", 
               GetLastError());
        return;
    }//if

    SP_DEVINFO_DATA infoData;
    infoData.cbSize = sizeof(SP_DEVINFO_DATA);

    DWORD n;
    for (n = 0; SetupDiEnumDeviceInfo(infoSet, n, &infoData); ++n)
    {
        DevData dd;
        if (GetDeviceRegString(infoSet, &infoData, SPDRP_DEVICEDESC, 
                               dd.Description) &&
            GetDeviceRegData(infoSet, &infoData, SPDRP_DEVICE_POWER_DATA, 
                             dd.PowerData))
        {
            devList.push_back(dd);
        }//if
    }//for

    if (GetLastError() != ERROR_NO_MORE_ITEMS)
    {
        printf("Last call to SetupDiEnumDeviceInfo(%d) failed, le = %u",
               n, GetLastError());
    }//if

    SetupDiDestroyDeviceInfoList(infoSet);
}//ListDeviceClassData

//------------------------------------------------------------------------------

void print_monitor_info()
{
    const GUID MonitorClassGuid =
        {0x4d36e96e, 0xe325, 0x11ce, 
            {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};

    list<DevData> monitors;
    ListDeviceClassData(&MonitorClassGuid, monitors);

    printf("# Monitors = %d\n", monitors.size());

    list<DevData>::iterator it = monitors.begin(),
                            it_end = monitors.end();
    for (; it != it_end; ++it)
    {
        const char *off_msg = "";

        if (it->PowerData.PD_MostRecentPowerState > PowerDeviceD0)
            off_msg = ", *** Sleeping State ***";

        printf("[%ls]\n"
               "   PowerState = %d%s\n", 
               it->Description.c_str(),
               it->PowerData.PD_MostRecentPowerState,
               off_msg);
    }//for

    putchar('\n');
}//print_monitor_info

//------------------------------------------------------------------------------

int main()
{
    printf("*** Current Status of Monitor(s) ***\n\n");
    print_monitor_info();

    printf("*** Turning OFF Monitor(s) ***\n\n");
    fflush(stdout);
    Sleep(500); // don't use mouse or keyboard
    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)2);

    print_monitor_info();

    printf("*** Turning ON Monitor(s) ***\n\n");
    SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, (LPARAM)-1);

    print_monitor_info();

    return 0;
}//main

//------------------------------------------------------------------------------
    
por 23.07.2014 / 23:36
0

O HDMI possui Controle Eletrônico de Consumo (CEC). link Basicamente, os dispositivos HDMI (se suportarem) podem se comunicar uns com os outros. Por exemplo, se você usar um controle remoto para HTPC, um monitor ou tv pode ser desligado via CEC de HTPC. HTPC - home theater pc. Google HDMI cec e você pode ter algumas ideias.

    
por 21.08.2014 / 01:06