Yuhang Zhao
2024-12-09 42977738aba59150109fea3e9edd2b74643c1000
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
// Copyright (C) 2023-2024 Stdware Collections (https://www.github.com/stdware)
// Copyright (C) 2021-2023 wangwenx190 (Yuhang Zhao)
// SPDX-License-Identifier: Apache-2.0
 
#ifndef QWINDOWKIT_WINDOWS_H
#define QWINDOWKIT_WINDOWS_H
 
#include <QtCore/qt_windows.h>
#include <QtCore/qglobal.h>
 
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
#  include <QtCore/private/qwinregistry_p.h>
#endif
 
#include <QWKCore/qwkglobal.h>
 
#ifndef GET_X_LPARAM
#  define GET_X_LPARAM(lp) (static_cast<int>(static_cast<short>(LOWORD(lp))))
#endif
 
#ifndef GET_Y_LPARAM
#  define GET_Y_LPARAM(lp) (static_cast<int>(static_cast<short>(HIWORD(lp))))
#endif
 
#ifndef RECT_WIDTH
#  define RECT_WIDTH(rect) ((rect).right - (rect).left)
#endif
 
#ifndef RECT_HEIGHT
#  define RECT_HEIGHT(rect) ((rect).bottom - (rect).top)
#endif
 
#ifndef USER_DEFAULT_SCREEN_DPI
#  define USER_DEFAULT_SCREEN_DPI (96)
#endif
 
// Maybe undocumented Windows messages
// https://github.com/tinysec/public/blob/master/win32k/MessageTable.md
// https://ulib.sourceforge.io/doxy/a00239.html
#ifndef WM_UAHDESTROYWINDOW
#  define WM_UAHDESTROYWINDOW (0x0090)
#endif
 
#ifndef WM_UNREGISTER_WINDOW_SERVICES
#  define WM_UNREGISTER_WINDOW_SERVICES (0x0272)
#endif
 
#ifndef WM_NCUAHDRAWCAPTION
#  define WM_NCUAHDRAWCAPTION (0x00AE)
#endif
 
#ifndef WM_NCUAHDRAWFRAME
#  define WM_NCUAHDRAWFRAME (0x00AF)
#endif
 
namespace QWK {
 
    namespace Private {
 
        QWK_CORE_EXPORT RTL_OSVERSIONINFOW GetRealOSVersion();
 
        inline bool IsWindows1122H2OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 10) ||
                   (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 ||
                    rovi.dwBuildNumber >= 22621));
        }
 
        inline bool IsWindows11OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 10) ||
                   (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 ||
                    rovi.dwBuildNumber >= 22000));
        }
 
        inline bool IsWindows1020H1OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 10) ||
                   (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 ||
                    rovi.dwBuildNumber >= 19041));
        }
 
        inline bool IsWindows102004OrGreater_Real() {
            return IsWindows1020H1OrGreater_Real();
        }
 
        inline bool IsWindows101903OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 10) ||
                   (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 ||
                    rovi.dwBuildNumber >= 18362));
        }
 
        inline bool IsWindows1019H1OrGreater_Real() {
            return IsWindows101903OrGreater_Real();
        }
 
        inline bool IsWindows101809OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 10) ||
                   (rovi.dwMajorVersion == 10 && (rovi.dwMinorVersion > 0 ||
                    rovi.dwBuildNumber >= 17763));
        }
 
        inline bool IsWindows10RS5OrGreater_Real() {
            return IsWindows101809OrGreater_Real();
        }
 
        inline bool IsWindows10OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return rovi.dwMajorVersion >= 10;
        }
 
        inline bool IsWindows8Point1OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 6) ||
                   (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 3);
        }
 
        inline bool IsWindows8OrGreater_Real() {
            RTL_OSVERSIONINFOW rovi = GetRealOSVersion();
            return (rovi.dwMajorVersion > 6) ||
                   (rovi.dwMajorVersion == 6 && rovi.dwMinorVersion >= 2);
        }
 
        inline bool IsWindows10Only_Real() {
            return IsWindows10OrGreater_Real() && !IsWindows11OrGreater_Real();
        }
 
    }
 
    //
    // Registry Helpers
    //
 
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
    class QWK_CORE_EXPORT WindowsRegistryKey {
    public:
        WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ,
                           REGSAM access = 0);
 
        ~WindowsRegistryKey();
 
        bool isValid() const;
 
        void close();
        QString stringValue(QStringView subKey) const;
        QPair<DWORD, bool> dwordValue(QStringView subKey) const;
 
        template<typename T>
        std::optional<T> value(QStringView subKey) const;
 
    private:
        HKEY m_key;
 
        Q_DISABLE_COPY(WindowsRegistryKey)
    };
 
    inline bool WindowsRegistryKey::isValid() const {
        return m_key != nullptr;
    }
 
    template<>
    inline std::optional<DWORD> WindowsRegistryKey::value(QStringView subKey) const {
        const auto dv = dwordValue(subKey);
        if (!dv.second) {
            return {};
        }
        return dv.first;
    }
#elif QT_VERSION < QT_VERSION_CHECK(6, 8, 1)
    class WindowsRegistryKey : public QWinRegistryKey {
    public:
        WindowsRegistryKey(HKEY parentHandle, QStringView subKey, REGSAM permissions = KEY_READ, REGSAM access = 0);
 
        template<typename T>
        std::optional<T> value(QStringView subKey) const;
    };
 
    template<>
    inline std::optional<DWORD> WindowsRegistryKey::value(QStringView subKey) const {
        const auto dv = dwordValue(subKey);
        if (!dv.second) {
            return {};
        }
        return dv.first;
    }
#else
    using WindowsRegistryKey = QWinRegistryKey;
#endif
 
    //
    // Version Helpers
    //
 
    inline bool isWin8OrGreater() {
        static const bool result = Private::IsWindows8OrGreater_Real();
        return result;
    }
 
    inline bool isWin8Point1OrGreater() {
        static const bool result = Private::IsWindows8Point1OrGreater_Real();
        return result;
    }
 
    inline bool isWin10OrGreater() {
        static const bool result = Private::IsWindows10OrGreater_Real();
        return result;
    }
 
    inline bool isWin101809OrGreater() {
        static const bool result = Private::IsWindows101809OrGreater_Real();
        return result;
    }
 
    inline bool isWin10RS5OrGreater() {
        return isWin101809OrGreater();
    }
 
    inline bool isWin101903OrGreater() {
        static const bool result = Private::IsWindows101903OrGreater_Real();
        return result;
    }
 
    inline bool isWin1019H1OrGreater() {
        return isWin101903OrGreater();
    }
 
    inline bool isWin1020H1OrGreater() {
        static const bool result = Private::IsWindows1020H1OrGreater_Real();
        return result;
    }
 
    inline bool isWin102004OrGreater() {
        return isWin1020H1OrGreater();
    }
 
    inline bool isWin11OrGreater() {
        static const bool result = Private::IsWindows11OrGreater_Real();
        return result;
    }
 
    inline bool isWin1122H2OrGreater() {
        static const bool result = Private::IsWindows1122H2OrGreater_Real();
        return result;
    }
 
    inline bool isWin10Only() {
        static const bool result = Private::IsWindows10Only_Real();
        return result;
    };
 
    //
    // Native Event Helpers
    //
 
    inline bool isImmersiveColorSetChange(WPARAM wParam, LPARAM lParam) {
        return !wParam && lParam &&
               std::wcscmp(reinterpret_cast<LPCWSTR>(lParam), L"ImmersiveColorSet") == 0;
    }
 
}
 
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
Q_DECLARE_METATYPE(QMargins)
#endif
 
#endif // QWINDOWKIT_WINDOWS_H