potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。はてなブログ無料版なので記事の上の方はたぶん広告です。記事中にも広告挿入されるみたいです。

C++20&Win API プライマリモニターのハンドル取得&物理モニター情報の列挙

プライマリモニターのハンドルを取得して、その物理モニター情報を列挙するサンプルコードです。

#include <format>
#include <iostream>
#include <string_view>
#include <span>
#include <vector>

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

inline HMONITOR GetPrimaryMonitorHandle() noexcept
{
    return ::MonitorFromWindow(nullptr, MONITOR_DEFAULTTOPRIMARY);;
}

class PhysicalMonitors final
{
public:
    PhysicalMonitors(HMONITOR monitorHandle)
    {
        DWORD physicalMonitorCount;
        if (!::GetNumberOfPhysicalMonitorsFromHMONITOR(monitorHandle, &physicalMonitorCount))
            return;

        physicalMonitors.resize(physicalMonitorCount);
        if (!::GetPhysicalMonitorsFromHMONITOR(monitorHandle, physicalMonitorCount, physicalMonitors.data()))
            physicalMonitors.clear();
    }

    ~PhysicalMonitors()
    {
        ::DestroyPhysicalMonitors((DWORD)physicalMonitors.size(), physicalMonitors.data());
    }

    auto GetSpan() const noexcept
    {
        return std::span<const PHYSICAL_MONITOR>(physicalMonitors.cbegin(), physicalMonitors.cend());
    }

    HANDLE GetHandleAt(size_t index) const noexcept
    {
        return physicalMonitors[index].hPhysicalMonitor;
    }

    std::wstring_view GetDescriptionAt(size_t index) const noexcept
    {
        return physicalMonitors[index].szPhysicalMonitorDescription;
    }

    DWORD GetCount() const noexcept
    {
        return (DWORD)physicalMonitors.size();
    }

private:
    std::vector<PHYSICAL_MONITOR> physicalMonitors;
};

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

    auto primaryMonitorHandle = GetPrimaryMonitorHandle();

    PhysicalMonitors physicalMonitors(primaryMonitorHandle);
    for (auto& physicalMonitor : physicalMonitors.GetSpan())
    {
        std::wcout
            << std::format(L"{:x} - {}",
                (size_t)physicalMonitor.hPhysicalMonitor,
                physicalMonitor.szPhysicalMonitorDescription)
            << std::endl;
    }
}