monitors.h
1 #pragma once 2 #pragma comment(lib, "Gdi32.lib") 3 #include <Windows.h> 4 5 #include <compare> 6 #include <optional> 7 #include <vector> 8 9 // TODO: merge with FZ::Rect 10 struct Box 11 { 12 RECT rect; 13 14 explicit Box(RECT rect = {}) : 15 rect(rect) {} 16 Box(const Box&) = default; 17 Box& operator=(const Box&) = default; 18 19 int left() const { return rect.left; } 20 int right() const { return rect.right; } 21 int top() const { return rect.top; } 22 int bottom() const { return rect.bottom; } 23 int height() const { return rect.bottom - rect.top; }; 24 int width() const { return rect.right - rect.left; }; 25 POINT top_left() const { return { rect.left, rect.top }; }; 26 POINT top_middle() const { return { rect.left + width() / 2, rect.top }; }; 27 POINT top_right() const { return { rect.right, rect.top }; }; 28 POINT middle_left() const { return { rect.left, rect.top + height() / 2 }; }; 29 POINT middle() const { return { rect.left + width() / 2, rect.top + height() / 2 }; }; 30 POINT middle_right() const { return { rect.right, rect.top + height() / 2 }; }; 31 POINT bottom_left() const { return { rect.left, rect.bottom }; }; 32 POINT bottom_middle() const { return { rect.left + width() / 2, rect.bottom }; }; 33 POINT bottom_right() const { return { rect.right, rect.bottom }; }; 34 inline bool inside(const POINT point) const { return PtInRect(&rect, point); } 35 36 inline friend auto operator<=>(const Box& lhs, const Box& rhs) 37 { 38 auto lhs_tuple = std::make_tuple(lhs.rect.left, lhs.rect.right, lhs.rect.top, lhs.rect.bottom); 39 auto rhs_tuple = std::make_tuple(rhs.rect.left, rhs.rect.right, rhs.rect.top, rhs.rect.bottom); 40 return lhs_tuple <=> rhs_tuple; 41 } 42 }; 43 44 class MonitorInfo 45 { 46 public: 47 typedef struct Size 48 { 49 uint32_t width_logical, height_logical; 50 uint32_t width_physical, height_physical; 51 float width_mm, height_mm; 52 } Size; 53 54 private: 55 HMONITOR handle; 56 MONITORINFOEX info = {}; 57 58 public: 59 explicit MonitorInfo(HMONITOR h); 60 inline HMONITOR GetHandle() const 61 { 62 return handle; 63 } 64 Box GetScreenSize(const bool includeNonWorkingArea) const; 65 bool IsPrimary() const; 66 Size GetSize() const; 67 68 // Returns monitor rects ordered from left to right 69 static std::vector<MonitorInfo> GetMonitors(bool includeNonWorkingArea); 70 static MonitorInfo GetPrimaryMonitor(); 71 static MonitorInfo GetFromWindow(HWND); 72 static MonitorInfo GetFromPoint(int32_t, int32_t); 73 74 private: 75 static Size GetSize(const MONITORINFOEX&); 76 };