potisanのプログラミングメモ

プログラミング素人です。昔の自分を育ててくれたネット情報に少しでも貢献できるよう、情報を貯めていこうと思っています。Windows環境のC++やC#がメインです。

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