/ src / common / Display / monitors.h
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  };