1 /**************************************************************************** 2 ** 3 ** Copyright (C) 2016 The Qt Company Ltd. 4 ** Contact: https://www.qt.io/licensing/ 5 ** 6 ** This file is part of the plugins of the Qt Toolkit. 7 ** 8 ** $QT_BEGIN_LICENSE:LGPL$ 9 ** Commercial License Usage 10 ** Licensees holding valid commercial Qt licenses may use this file in 11 ** accordance with the commercial license agreement provided with the 12 ** Software or, alternatively, in accordance with the terms contained in 13 ** a written agreement between you and The Qt Company. For licensing terms 14 ** and conditions see https://www.qt.io/terms-conditions. For further 15 ** information use the contact form at https://www.qt.io/contact-us. 16 ** 17 ** GNU Lesser General Public License Usage 18 ** Alternatively, this file may be used under the terms of the GNU Lesser 19 ** General Public License version 3 as published by the Free Software 20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 21 ** packaging of this file. Please review the following information to 22 ** ensure the GNU Lesser General Public License version 3 requirements 23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 24 ** 25 ** GNU General Public License Usage 26 ** Alternatively, this file may be used under the terms of the GNU 27 ** General Public License version 2.0 or (at your option) the GNU General 28 ** Public license version 3 or any later version approved by the KDE Free 29 ** Qt Foundation. The licenses are as published by the Free Software 30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 31 ** included in the packaging of this file. Please review the following 32 ** information to ensure the GNU General Public License requirements will 33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and 34 ** https://www.gnu.org/licenses/gpl-3.0.html. 35 ** 36 ** $QT_END_LICENSE$ 37 ** 38 ****************************************************************************/ 39 40 #ifndef QWINDOWSCONTEXT_H 41 #define QWINDOWSCONTEXT_H 42 43 #include "qtwindowsglobal.h" 44 #include <QtCore/qt_windows.h> 45 46 #include <QtCore/qscopedpointer.h> 47 #include <QtCore/qsharedpointer.h> 48 #include <QtCore/qloggingcategory.h> 49 50 #define STRICT_TYPED_ITEMIDS 51 #include <shlobj.h> 52 #include <shlwapi.h> 53 54 struct IBindCtx; 55 struct _SHSTOCKICONINFO; 56 57 QT_BEGIN_NAMESPACE 58 59 Q_DECLARE_LOGGING_CATEGORY(lcQpaWindows) 60 Q_DECLARE_LOGGING_CATEGORY(lcQpaEvents) 61 Q_DECLARE_LOGGING_CATEGORY(lcQpaGl) 62 Q_DECLARE_LOGGING_CATEGORY(lcQpaMime) 63 Q_DECLARE_LOGGING_CATEGORY(lcQpaInputMethods) 64 Q_DECLARE_LOGGING_CATEGORY(lcQpaDialogs) 65 Q_DECLARE_LOGGING_CATEGORY(lcQpaMenus) 66 Q_DECLARE_LOGGING_CATEGORY(lcQpaTablet) 67 Q_DECLARE_LOGGING_CATEGORY(lcQpaAccessibility) 68 Q_DECLARE_LOGGING_CATEGORY(lcQpaUiAutomation) 69 Q_DECLARE_LOGGING_CATEGORY(lcQpaTrayIcon) 70 71 class QWindow; 72 class QPlatformScreen; 73 class QPlatformWindow; 74 class QWindowsMenuBar; 75 class QWindowsScreenManager; 76 class QWindowsTabletSupport; 77 class QWindowsWindow; 78 class QWindowsMimeConverter; 79 struct QWindowCreationContext; 80 struct QWindowsContextPrivate; 81 class QPoint; 82 class QKeyEvent; 83 class QTouchDevice; 84 85 struct QWindowsUser32DLL 86 { 87 inline void init(); 88 inline bool supportsPointerApi(); 89 90 typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL); 91 typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID); 92 typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID); 93 typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *); 94 typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID); 95 typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID); 96 typedef BOOL (WINAPI *GetPointerFrameTouchInfoHistory)(UINT32, UINT32 *, UINT32 *, PVOID); 97 typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID); 98 typedef BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32, UINT32 *, PVOID); 99 typedef BOOL (WINAPI *SkipPointerFrameMessages)(UINT32); 100 typedef BOOL (WINAPI *SetProcessDPIAware)(); 101 typedef BOOL (WINAPI *AddClipboardFormatListener)(HWND); 102 typedef BOOL (WINAPI *RemoveClipboardFormatListener)(HWND); 103 typedef BOOL (WINAPI *GetDisplayAutoRotationPreferences)(DWORD *); 104 typedef BOOL (WINAPI *SetDisplayAutoRotationPreferences)(DWORD); 105 typedef BOOL (WINAPI *AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT); 106 typedef BOOL (WINAPI *EnableNonClientDpiScaling)(HWND); 107 typedef int (WINAPI *GetWindowDpiAwarenessContext)(HWND); 108 typedef int (WINAPI *GetAwarenessFromDpiAwarenessContext)(int); 109 typedef BOOL (WINAPI *SystemParametersInfoForDpi)(UINT, UINT, PVOID, UINT, UINT); 110 111 // Windows pointer functions (Windows 8 or later). 112 EnableMouseInPointer enableMouseInPointer = nullptr; 113 GetPointerType getPointerType = nullptr; 114 GetPointerInfo getPointerInfo = nullptr; 115 GetPointerDeviceRects getPointerDeviceRects = nullptr; 116 GetPointerTouchInfo getPointerTouchInfo = nullptr; 117 GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr; 118 GetPointerFrameTouchInfoHistory getPointerFrameTouchInfoHistory = nullptr; 119 GetPointerPenInfo getPointerPenInfo = nullptr; 120 GetPointerPenInfoHistory getPointerPenInfoHistory = nullptr; 121 SkipPointerFrameMessages skipPointerFrameMessages = nullptr; 122 123 // Windows Vista onwards 124 SetProcessDPIAware setProcessDPIAware = nullptr; 125 126 // Clipboard listeners are present on Windows Vista onwards 127 // but missing in MinGW 4.9 stub libs. Can be removed in MinGW 5. 128 AddClipboardFormatListener addClipboardFormatListener = nullptr; 129 RemoveClipboardFormatListener removeClipboardFormatListener = nullptr; 130 131 // Rotation API 132 GetDisplayAutoRotationPreferences getDisplayAutoRotationPreferences = nullptr; 133 SetDisplayAutoRotationPreferences setDisplayAutoRotationPreferences = nullptr; 134 135 AdjustWindowRectExForDpi adjustWindowRectExForDpi = nullptr; 136 EnableNonClientDpiScaling enableNonClientDpiScaling = nullptr; 137 GetWindowDpiAwarenessContext getWindowDpiAwarenessContext = nullptr; 138 GetAwarenessFromDpiAwarenessContext getAwarenessFromDpiAwarenessContext = nullptr; 139 SystemParametersInfoForDpi systemParametersInfoForDpi = nullptr; 140 }; 141 142 // Shell scaling library (Windows 8.1 onwards) 143 struct QWindowsShcoreDLL { 144 void init(); isValidQWindowsShcoreDLL145 inline bool isValid() const { return getProcessDpiAwareness && setProcessDpiAwareness && getDpiForMonitor; } 146 147 typedef HRESULT (WINAPI *GetProcessDpiAwareness)(HANDLE,int *); 148 typedef HRESULT (WINAPI *SetProcessDpiAwareness)(int); 149 typedef HRESULT (WINAPI *GetDpiForMonitor)(HMONITOR,int,UINT *,UINT *); 150 151 GetProcessDpiAwareness getProcessDpiAwareness = nullptr; 152 SetProcessDpiAwareness setProcessDpiAwareness = nullptr; 153 GetDpiForMonitor getDpiForMonitor = nullptr; 154 }; 155 156 class QWindowsContext 157 { 158 Q_DISABLE_COPY_MOVE(QWindowsContext) 159 public: 160 161 enum SystemInfoFlags 162 { 163 SI_RTL_Extensions = 0x1, 164 SI_SupportsTouch = 0x2, 165 SI_SupportsPointer = 0x4, 166 }; 167 168 // Verbose flag set by environment variable QT_QPA_VERBOSE 169 static int verbose; 170 171 explicit QWindowsContext(); 172 ~QWindowsContext(); 173 174 bool initTouch(); 175 bool initTouch(unsigned integrationOptions); // For calls from QWindowsIntegration::QWindowsIntegration() only. 176 bool initTablet(unsigned integrationOptions); 177 bool initPointer(unsigned integrationOptions); 178 179 bool initPowerNotificationHandler(); 180 181 int defaultDPI() const; 182 183 static QString classNamePrefix(); 184 QString registerWindowClass(const QWindow *w); 185 QString registerWindowClass(QString cname, WNDPROC proc, 186 unsigned style = 0, HBRUSH brush = nullptr, 187 bool icon = false); 188 HWND createDummyWindow(const QString &classNameIn, 189 const wchar_t *windowName, 190 WNDPROC wndProc = nullptr, DWORD style = WS_OVERLAPPED); 191 192 HDC displayContext() const; 193 int screenDepth() const; 194 195 static QWindowsContext *instance(); 196 197 static QString windowsErrorMessage(unsigned long errorCode); 198 199 void addWindow(HWND, QWindowsWindow *w); 200 void removeWindow(HWND); 201 202 QWindowsWindow *findClosestPlatformWindow(HWND) const; 203 QWindowsWindow *findPlatformWindow(HWND) const; 204 QWindowsWindow *findPlatformWindow(const QWindowsMenuBar *mb) const; 205 QWindow *findWindow(HWND) const; 206 QWindowsWindow *findPlatformWindowAt(HWND parent, const QPoint &screenPoint, 207 unsigned cwex_flags) const; 208 209 static bool shouldHaveNonClientDpiScaling(const QWindow *window); 210 211 QWindow *windowUnderMouse() const; 212 void clearWindowUnderMouse(); 213 214 inline bool windowsProc(HWND hwnd, UINT message, 215 QtWindows::WindowsEventType et, 216 WPARAM wParam, LPARAM lParam, LRESULT *result, 217 QWindowsWindow **platformWindowPtr); 218 219 QWindow *keyGrabber() const; 220 void setKeyGrabber(QWindow *hwnd); 221 222 QSharedPointer<QWindowCreationContext> setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx); 223 QSharedPointer<QWindowCreationContext> windowCreationContext() const; 224 225 void setTabletAbsoluteRange(int a); 226 void setProcessDpiAwareness(QtWindows::ProcessDpiAwareness dpiAwareness); 227 static int processDpiAwareness(); 228 229 static bool isDarkMode(); 230 231 void setDetectAltGrModifier(bool a); 232 233 // Returns a combination of SystemInfoFlags 234 unsigned systemInfo() const; 235 236 bool useRTLExtensions() const; 237 QList<int> possibleKeys(const QKeyEvent *e) const; 238 239 static bool isSessionLocked(); 240 241 QWindowsMimeConverter &mimeConverter() const; 242 QWindowsScreenManager &screenManager(); 243 QWindowsTabletSupport *tabletSupport() const; 244 245 static QWindowsUser32DLL user32dll; 246 static QWindowsShcoreDLL shcoredll; 247 248 static QByteArray comErrorString(HRESULT hr); 249 bool asyncExpose() const; 250 void setAsyncExpose(bool value); 251 252 static void forceNcCalcSize(HWND hwnd); 253 254 static bool systemParametersInfo(unsigned action, unsigned param, void *out, unsigned dpi = 0); 255 static bool systemParametersInfoForScreen(unsigned action, unsigned param, void *out, 256 const QPlatformScreen *screen = nullptr); 257 static bool systemParametersInfoForWindow(unsigned action, unsigned param, void *out, 258 const QPlatformWindow *win = nullptr); 259 static bool nonClientMetrics(NONCLIENTMETRICS *ncm, unsigned dpi = 0); 260 static bool nonClientMetricsForScreen(NONCLIENTMETRICS *ncm, 261 const QPlatformScreen *screen = nullptr); 262 static bool nonClientMetricsForWindow(NONCLIENTMETRICS *ncm, 263 const QPlatformWindow *win = nullptr); 264 265 static DWORD readAdvancedExplorerSettings(const wchar_t *subKey, DWORD defaultValue); 266 267 QTouchDevice *touchDevice() const; 268 269 static bool filterNativeEvent(MSG *msg, LRESULT *result); 270 static bool filterNativeEvent(QWindow *window, MSG *msg, LRESULT *result); 271 272 private: 273 void handleFocusEvent(QtWindows::WindowsEventType et, QWindowsWindow *w); 274 #ifndef QT_NO_CONTEXTMENU 275 bool handleContextMenuEvent(QWindow *window, const MSG &msg); 276 #endif 277 void handleExitSizeMove(QWindow *window); 278 void unregisterWindowClasses(); 279 280 QScopedPointer<QWindowsContextPrivate> d; 281 static QWindowsContext *m_instance; 282 }; 283 284 extern "C" LRESULT QT_WIN_CALLBACK qWindowsWndProc(HWND, UINT, WPARAM, LPARAM); 285 286 QT_END_NAMESPACE 287 288 #endif // QWINDOWSCONTEXT_H 289