-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmonitor.hpp
100 lines (96 loc) · 4.94 KB
/
monitor.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
//Copyright (C) 2014-2017, 2019 I
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#pragma once
#include"_windows.hpp"
#if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE
#include<ShellScalingApi.h>
#pragma comment(lib, "Shcore.lib")
#include"com.hpp"
#endif
namespace will{
class monitor{
HMONITOR h;
template<typename T>
expected<T, winapi_last_error> get_info_impl()const{
T mon{};
mon.cbSize = sizeof(T);
if(::GetMonitorInfo(h, &mon) != 0)
return mon;
return make_unexpected<winapi_last_error>(_T("will::monitor::get_info"));
}
public:
enum class default_to:DWORD{
null = MONITOR_DEFAULTTONULL,
nearest = MONITOR_DEFAULTTONEAREST,
primary = MONITOR_DEFAULTTOPRIMARY
};
explicit monitor(HMONITOR h):h(h){}
monitor(const monitor&) = default;
monitor(monitor&&) = default;
monitor& operator=(const monitor&) = default;
monitor& operator=(monitor&&) = default;
~monitor() = default;
explicit operator bool()const noexcept{return h != nullptr;}
explicit operator HMONITOR()const noexcept{return h;}
HMONITOR get()const{return h;}
friend bool operator==(const monitor& lhs, const monitor& rhs)noexcept{return lhs.h == rhs.h;}
friend bool operator==(const monitor& lhs, HMONITOR rhs)noexcept{return lhs.h == rhs;}
friend bool operator==(HMONITOR lhs, const monitor& rhs)noexcept{return lhs == rhs.h;}
friend bool operator!=(const monitor& lhs, const monitor& rhs)noexcept{return !(lhs == rhs);}
friend bool operator!=(const monitor& lhs, HMONITOR rhs)noexcept{return !(lhs == rhs);}
friend bool operator!=(HMONITOR lhs, const monitor& rhs)noexcept{return !(lhs == rhs);}
static monitor from_point(const POINT& p, default_to d = default_to::null){return monitor{::MonitorFromPoint(p, static_cast<std::underlying_type_t<default_to>>(d))};}
static monitor from_rect(const RECT& r, default_to d = default_to::null){return monitor{::MonitorFromRect(&r, static_cast<std::underlying_type_t<default_to>>(d))};}
static monitor from_window(HWND hwnd, default_to d = default_to::null){return monitor{::MonitorFromWindow(hwnd, static_cast<std::underlying_type_t<default_to>>(d))};}
template<typename Window, std::enable_if_t<!std::is_same<std::decay_t<Window>, HWND>::value>* = nullptr>
static monitor from_window(Window&& w, default_to d = default_to::null){return from_window(std::forward<Window>(w).get(), d);}
template<typename bool(const_will_monitor&,const_RECT&)>
static expected<void, winapi_last_error> enum_display(bool(const_will_monitor&,const_RECT&)&& f){
using F = bool(const_will_monitor&,const_RECT&);
if(::EnumDisplayMonitors(nullptr, nullptr, [](HMONITOR hm, HDC, LPRECT lpr, LPARAM f)->BOOL{
return (*reinterpret_cast<F*>(f))(monitor{hm}, *lpr) ? TRUE : FALSE;
}, reinterpret_cast<LPARAM>(&f)) != 0)return {};
return make_unexpected<winapi_last_error>(_T(__FUNCTION__));
}
template<typename bool(const_will_monitor&,HDC,const_RECT&)>
static bool enum_display(bool(const_will_monitor&,HDC,const_RECT&)&& f, HDC hdc){
using F = bool(const_will_monitor&,HDC,const_RECT&);
if(::EnumDisplayMonitors(hdc, nullptr, [](HMONITOR hm, HDC hdc, LPRECT lpr, LPARAM f)->BOOL{
return (*reinterpret_cast<F*>(f))(monitor{hm}, hdc, *lpr) ? TRUE : FALSE;
}, reinterpret_cast<LPARAM>(&f)) != 0)return {};
return make_unexpected<winapi_last_error>(_T(__FUNCTION__));
}
template<typename bool(const_will_monitor&,const_RECT&)>
static bool enum_display(bool(const_will_monitor&,const_RECT&)&& f, const RECT& r){
using F = bool(const_will_monitor&,const_RECT&);
if(::EnumDisplayMonitors(nullptr, &r, [](HMONITOR hm, HDC, LPRECT lpr, LPARAM f)->BOOL{
return (*reinterpret_cast<F*>(f))(monitor{hm}, *lpr) ? TRUE : FALSE;
}, reinterpret_cast<LPARAM>(&f)) != 0)return {};
return make_unexpected<winapi_last_error>(_T(__FUNCTION__));
}
template<typename bool(const_will_monitor&,HDC,const_RECT&)>
static bool enum_display(bool(const_will_monitor&,HDC,const_RECT&)&& f, HDC hdc, const RECT& r){
using F = bool(const_will_monitor&,HDC,const_RECT&);
if(::EnumDisplayMonitors(hdc, &r, [](HMONITOR hm, HDC hdc, LPRECT lpr, LPARAM f)->BOOL{
return (*reinterpret_cast<F*>(f))(monitor{hm}, hdc, *lpr) ? TRUE : FALSE;
}, reinterpret_cast<LPARAM>(&f)) != 0)return {};
return make_unexpected<winapi_last_error>(_T(__FUNCTION__));
}
expected<::MONITORINFO, winapi_last_error> get_info()const{
return get_info_impl<::MONITORINFO>();
}
expected<::MONITORINFOEX, winapi_last_error> get_info_ex()const{
return get_info_impl<::MONITORINFOEX>();
}
#if _WIN32_WINNT >= _WIN32_WINNT_WINBLUE
expected<two_dim::xy<UINT>, hresult_error> get_dpi(MONITOR_DPI_TYPE type)const{
two_dim::xy<UINT> xy;
const auto hr = ::GetDpiForMonitor(h, type, &xy.x, &xy.y);
if(SUCCEEDED(hr))
return xy;
return make_unexpected<hresult_error>(_T(__FUNCTION__), hr);
}
#endif
};
}