potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。

C++20&Win API(Vista~) 画面の明るさを取得・設定する

Windows Vista以降で画面の明るさを取得・設定するサンプルコードです。

画面の明るさの範囲と設定値を取得する。

#include <iostream>
#include <string>
#include <optional>

#define STRICT
#include <Windows.h>
#include <powrprof.h>
#pragma comment(lib, "powrprof.lib")

namespace PowerUtil
{
    std::optional<GUID> GetActiveSchemeGUID() noexcept
    {
        LPGUID pguid;
        auto ret = ::PowerGetActiveScheme(nullptr, &pguid);
        if (ret != NOERROR)
            return {};
        GUID guid;
        ::RtlCopyMemory(&guid, pguid, sizeof(GUID));
        ::LocalFree(pguid);
        return guid;
    }

    std::optional<std::wstring> ReadDescription(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept(false)
    {
        DWORD bufferSize;
        if (::PowerReadDescription(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            nullptr, &bufferSize) != NOERROR)
        {
            return {};
        }

        std::wstring buffer(bufferSize / sizeof(wchar_t) - 1, L'\0');
        if (::PowerReadDescription(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            reinterpret_cast<PUCHAR>(buffer.data()),
            &bufferSize) != NOERROR)
        {
            return {};
        }
        return std::move(buffer);
    }

    std::optional<std::wstring> ReadFriendlyName(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept(false)
    {
        DWORD bufferSize;
        if (::PowerReadFriendlyName(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            nullptr, &bufferSize) != NOERROR)
        {
            return {};
        }

        std::wstring buffer(bufferSize / sizeof(wchar_t) - 1, L'\0');
        if (::PowerReadFriendlyName(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            reinterpret_cast<PUCHAR>(buffer.data()),
            &bufferSize) != NOERROR)
        {
            return {};
        }
        return std::move(buffer);
    }

    std::optional<DWORD> ReadValueMin(
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept
    {
        DWORD value;
        auto ret = ::PowerReadValueMin(
            nullptr,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            &value);
        return ret == NOERROR ? value : value;
    }

    std::optional<DWORD> ReadValueMax(
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept
    {
        DWORD value;
        auto ret = ::PowerReadValueMax(
            nullptr,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            &value);
        return ret == NOERROR ? value : value;
    }

    std::optional<DWORD> ReadACValueIndex(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept
    {
        DWORD value;
        auto ret = ::PowerReadACValueIndex(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            &value);
        return ret == NOERROR ? value : value;
    }

    std::optional<DWORD> ReadDCValueIndex(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept
    {
        DWORD value;
        auto ret = ::PowerReadDCValueIndex(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            &value);
        return ret == NOERROR ? value : value;
    }
}

int main()
{
    std::wcout.imbue(std::locale("Japanese", std::locale::ctype));

    // 現在の電源プロファイルのScheme GUIDを取得する。
    auto schemeGuid = PowerUtil::GetActiveSchemeGUID();
    if (!schemeGuid)
        return ::GetLastError();

    // 画面の明るさの範囲を取得する。
    auto definesRange = (bool)::PowerIsSettingRangeDefined(
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);
    auto minValue = PowerUtil::ReadValueMin(
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);
    auto maxValue = PowerUtil::ReadValueMax(
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);

    // 現在の電源設定の画面の明るさを取得する。
    auto acValue = PowerUtil::ReadACValueIndex(
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);
    auto dcValue = PowerUtil::ReadDCValueIndex(
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);

    // 現在の電源プロファイルの画面の明るさの概要・説明を取得する。
    auto description = PowerUtil::ReadDescription(
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);
    auto friendlyName = PowerUtil::ReadFriendlyName(
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS);

    return err;
}

画面の明るさを設定する。

#include <iostream>
#include <string>
#include <optional>

#define STRICT
#include <Windows.h>
#include <powrprof.h>
#pragma comment(lib, "powrprof.lib")

namespace PowerUtil
{
    std::optional<GUID> GetActiveSchemeGUID() noexcept
    {
        LPGUID pguid;
        auto ret = ::PowerGetActiveScheme(nullptr, &pguid);
        if (ret != NOERROR)
            return {};
        GUID guid;
        ::RtlCopyMemory(&guid, pguid, sizeof(GUID));
        ::LocalFree(pguid);
        return guid;
    }
}

int main()
{
    std::wcout.imbue(std::locale("Japanese", std::locale::ctype));

    // 現在の電源プロファイルのScheme GUIDを取得する。
    auto schemeGuid = PowerUtil::GetActiveSchemeGUID();
    if (!schemeGuid)
        return ::GetLastError();

    // 現在の電源プロファイルの画面の明るさを設定する。
    DWORD err{ 0 };
    err = ::PowerWriteACValueIndex(
        nullptr,
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS,
        50);
    err = ::PowerWriteDCValueIndex(
        nullptr,
        &*schemeGuid,
        &GUID_VIDEO_SUBGROUP,
        &GUID_DEVICE_POWER_POLICY_VIDEO_BRIGHTNESS,
        50);
    err = ::PowerSetActiveScheme(
        nullptr,
        &*schemeGuid);

    return err;
}

現在の画面プロファイルの概要・名前を取得する。

#include <iostream>
#include <string>
#include <optional>

#define STRICT
#include <Windows.h>
#include <powrprof.h>
#pragma comment(lib, "powrprof.lib")

namespace PowerUtil
{
    std::optional<GUID> GetActiveSchemeGUID() noexcept
    {
        LPGUID pguid;
        auto ret = ::PowerGetActiveScheme(nullptr, &pguid);
        if (ret != NOERROR)
            return {};
        GUID guid;
        ::RtlCopyMemory(&guid, pguid, sizeof(GUID));
        ::LocalFree(pguid);
        return guid;
    }

    std::optional<std::wstring> ReadDescription(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept(false)
    {
        DWORD bufferSize;
        if (::PowerReadDescription(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            nullptr, &bufferSize) != NOERROR)
        {
            return {};
        }

        std::wstring buffer(bufferSize / sizeof(wchar_t) - 1, L'\0');
        if (::PowerReadDescription(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            reinterpret_cast<PUCHAR>(buffer.data()),
            &bufferSize) != NOERROR)
        {
            return {};
        }
        return std::move(buffer);
    }

    std::optional<std::wstring> ReadFriendlyName(
        const GUID* SchemeGuid,
        const GUID* SubGroupOfPowerSettingsGuid,
        const GUID* PowerSettingGuid)
        noexcept(false)
    {
        DWORD bufferSize;
        if (::PowerReadFriendlyName(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            nullptr, &bufferSize) != NOERROR)
        {
            return {};
        }

        std::wstring buffer(bufferSize / sizeof(wchar_t) - 1, L'\0');
        if (::PowerReadFriendlyName(
            nullptr,
            SchemeGuid,
            SubGroupOfPowerSettingsGuid,
            PowerSettingGuid,
            reinterpret_cast<PUCHAR>(buffer.data()),
            &bufferSize) != NOERROR)
        {
            return {};
        }
        return std::move(buffer);
    }
}

int main()
{
    std::wcout.imbue(std::locale("Japanese", std::locale::ctype));

    // 現在の電源プロファイルのScheme GUIDを取得する。
    auto schemeGuid = PowerUtil::GetActiveSchemeGUID();
    if (!schemeGuid)
        return ::GetLastError();

    // 現在の電源プロファイルの概要・説明を取得する。
    auto description = PowerUtil::ReadDescription(
        &*schemeGuid, &NO_SUBGROUP_GUID, nullptr);
    auto friendlyName = PowerUtil::ReadFriendlyName(
        &*schemeGuid, &GUID_VIDEO_SUBGROUP, nullptr);

    return 0;
}