#pragma once #pragma comment(lib, "Gdi32.lib") #include #include #include #include // TODO: merge with FZ::Rect struct Box { RECT rect; explicit Box(RECT rect = {}) : rect(rect) {} Box(const Box&) = default; Box& operator=(const Box&) = default; int left() const { return rect.left; } int right() const { return rect.right; } int top() const { return rect.top; } int bottom() const { return rect.bottom; } int height() const { return rect.bottom - rect.top; }; int width() const { return rect.right - rect.left; }; POINT top_left() const { return { rect.left, rect.top }; }; POINT top_middle() const { return { rect.left + width() / 2, rect.top }; }; POINT top_right() const { return { rect.right, rect.top }; }; POINT middle_left() const { return { rect.left, rect.top + height() / 2 }; }; POINT middle() const { return { rect.left + width() / 2, rect.top + height() / 2 }; }; POINT middle_right() const { return { rect.right, rect.top + height() / 2 }; }; POINT bottom_left() const { return { rect.left, rect.bottom }; }; POINT bottom_middle() const { return { rect.left + width() / 2, rect.bottom }; }; POINT bottom_right() const { return { rect.right, rect.bottom }; }; inline bool inside(const POINT point) const { return PtInRect(&rect, point); } inline friend auto operator<=>(const Box& lhs, const Box& rhs) { auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom); auto rhs_tuple = std::make_tuple(rhs.rect.left, rhs.rect.right, rhs.rect.top, rhs.rect.bottom); return lhs_tuple <=> rhs_tuple; } }; class MonitorInfo { public: typedef struct Size { uint32_t width_logical, height_logical; uint32_t width_physical, height_physical; float width_mm, height_mm; } Size; private: HMONITOR handle; MONITORINFOEX info = {}; public: explicit MonitorInfo(HMONITOR h); inline HMONITOR GetHandle() const { return handle; } Box GetScreenSize(const bool includeNonWorkingArea) const; bool IsPrimary() const; Size GetSize() const; // Returns monitor rects ordered from left to right static std::vector GetMonitors(bool includeNonWorkingArea); static MonitorInfo GetPrimaryMonitor(); static MonitorInfo GetFromWindow(HWND); static MonitorInfo GetFromPoint(int32_t, int32_t); private: static Size GetSize(const MONITORINFOEX&); };