update to Qt 6.7.3

This commit is contained in:
kleuter
2024-06-29 14:33:57 +02:00
parent d8e4680eb6
commit 36dc9b47f0
19 changed files with 4278 additions and 908 deletions

View File

@ -46,10 +46,13 @@
#include <QtCore/quuid.h>
#include <QtCore/private/qsystemlibrary_p.h>
#include <QtCore/private/qwinregistry_p.h>
#include <QtCore/private/qfactorycacheregistration_p.h>
#if QT_CONFIG(cpp_winrt)
# include <QtCore/private/qfactorycacheregistration_p.h>
#endif
#include <QtCore/private/qsystemerror_p.h>
#include <QtGui/private/qwindowsguieventdispatcher_p.h>
#include <QtGui/private/qwindowsthemecache_p.h>
#include <stdlib.h>
#include <stdio.h>
@ -58,6 +61,8 @@
#include <wtsapi32.h>
#include <shellscalingapi.h>
#include "vxkex.h"
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@ -276,6 +281,8 @@ QWindowsContext::~QWindowsContext()
if (d->m_powerDummyWindow)
DestroyWindow(d->m_powerDummyWindow);
d->m_screenManager.destroyWindow();
unregisterWindowClasses();
if (d->m_oleInitializeResult == S_OK || d->m_oleInitializeResult == S_FALSE) {
#ifdef QT_USE_FACTORY_CACHE_REGISTRATION
@ -445,11 +452,25 @@ void QWindowsContext::setDetectAltGrModifier(bool a)
return QtWindows::DpiAwareness::System;
if (QWindowsContext::user32dll.areDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
return QtWindows::DpiAwareness::Unaware;
return QtWindows::DpiAwareness::Invalid;
}
else
{
// IsValidDpiAwarenessContext() will handle the NULL pointer case.
if (!vxkex::IsValidDpiAwarenessContext(context))
return QtWindows::DpiAwareness::Invalid;
if (vxkex::AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED))
return QtWindows::DpiAwareness::Unaware_GdiScaled;
if (vxkex::AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2))
return QtWindows::DpiAwareness::PerMonitorVersion2;
if (vxkex::AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE))
return QtWindows::DpiAwareness::PerMonitor;
if (vxkex::AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE))
return QtWindows::DpiAwareness::System;
if (vxkex::AreDpiAwarenessContextsEqual(context, DPI_AWARENESS_CONTEXT_UNAWARE))
return QtWindows::DpiAwareness::Unaware;
}
return QtWindows::DpiAwareness::Unaware; // Windows 7
return QtWindows::DpiAwareness::Invalid;
}
QtWindows::DpiAwareness QWindowsContext::windowDpiAwareness(HWND hwnd)
@ -457,31 +478,26 @@ QtWindows::DpiAwareness QWindowsContext::windowDpiAwareness(HWND hwnd)
if (!hwnd)
return QtWindows::DpiAwareness::Invalid;
if (QWindowsContext::user32dll.getWindowDpiAwarenessContext)
{
const auto context = QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd);
return dpiAwarenessContextToQtDpiAwareness(context);
}
const auto context = QWindowsContext::user32dll.getWindowDpiAwarenessContext ?
QWindowsContext::user32dll.getWindowDpiAwarenessContext(hwnd) :
vxkex::GetWindowDpiAwarenessContext(hwnd);
return dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT_UNAWARE);
return dpiAwarenessContextToQtDpiAwareness(context);
}
QtWindows::DpiAwareness QWindowsContext::processDpiAwareness()
{
if (QWindowsContext::user32dll.getThreadDpiAwarenessContext)
{
// Although we have GetDpiAwarenessContextForProcess(), however,
// it's only available on Win10 1903+, which is a little higher
// than Qt's minimum supported version (1809), so we can't use it.
// Luckily, MS docs said GetThreadDpiAwarenessContext() will also
// return the default DPI_AWARENESS_CONTEXT for the process if
// SetThreadDpiAwarenessContext() was never called. So we can use
// it as an equivalent.
const auto context = QWindowsContext::user32dll.getThreadDpiAwarenessContext();
return dpiAwarenessContextToQtDpiAwareness(context);
}
return dpiAwarenessContextToQtDpiAwareness(DPI_AWARENESS_CONTEXT_UNAWARE);
// Although we have GetDpiAwarenessContextForProcess(), however,
// it's only available on Win10 1903+, which is a little higher
// than Qt's minimum supported version (1809), so we can't use it.
// Luckily, MS docs said GetThreadDpiAwarenessContext() will also
// return the default DPI_AWARENESS_CONTEXT for the process if
// SetThreadDpiAwarenessContext() was never called. So we can use
// it as an equivalent.
const DPI_AWARENESS_CONTEXT context = QWindowsContext::user32dll.getThreadDpiAwarenessContext ?
QWindowsContext::user32dll.getThreadDpiAwarenessContext() :
vxkex::GetThreadDpiAwarenessContext();
return dpiAwarenessContextToQtDpiAwareness(context);
}
[[nodiscard]] static inline DPI_AWARENESS_CONTEXT
@ -541,28 +557,32 @@ bool QWindowsContext::setProcessDpiAwareness(QtWindows::DpiAwareness dpiAwarenes
return true;
const auto context = qtDpiAwarenessToDpiAwarenessContext(dpiAwareness);
if (QWindowsContext::user32dll.isValidDpiAwarenessContext && QWindowsContext::user32dll.setProcessDpiAwarenessContext)
{
if (!QWindowsContext::user32dll.isValidDpiAwarenessContext(context)) {
qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system.";
return false;
}
if (!QWindowsContext::user32dll.setProcessDpiAwarenessContext(context)) {
qCWarning(lcQpaWindow).noquote().nospace()
<< "SetProcessDpiAwarenessContext() failed: "
<< QSystemError::windowsString()
<< "\nQt's default DPI awareness context is "
<< "DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
<< "are doing, you can overwrite this default using qt.conf "
<< "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
return false;
}
QWindowsContextPrivate::m_v2DpiAware
= processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2;
return true;
BOOL bResultIsValid = QWindowsContext::user32dll.isValidDpiAwarenessContext ?
QWindowsContext::user32dll.isValidDpiAwarenessContext(context) :
vxkex::IsValidDpiAwarenessContext(context);
if (!bResultIsValid) {
qCWarning(lcQpaWindow) << dpiAwareness << "is not supported by current system.";
return false;
}
return false; // Windows 7
BOOL bResultSet = QWindowsContext::user32dll.setProcessDpiAwarenessContext ?
QWindowsContext::user32dll.setProcessDpiAwarenessContext(context) :
vxkex::SetProcessDpiAwarenessContext(context);
if (!bResultSet) {
qCWarning(lcQpaWindow).noquote().nospace()
<< "SetProcessDpiAwarenessContext() failed: "
<< QSystemError::windowsString()
<< "\nQt's default DPI awareness context is "
<< "DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2. If you know what you "
<< "are doing, you can overwrite this default using qt.conf "
<< "(https://doc.qt.io/qt-6/highdpi.html#configuring-windows).";
return false;
}
QWindowsContextPrivate::m_v2DpiAware
= processDpiAwareness() == QtWindows::DpiAwareness::PerMonitorVersion2;
return true;
}
bool QWindowsContext::isDarkMode()
@ -585,9 +605,9 @@ bool QWindowsContext::useRTLExtensions() const
return d->m_keyMapper.useRTLExtensions();
}
QList<int> QWindowsContext::possibleKeys(const QKeyEvent *e) const
QPlatformKeyMapper *QWindowsContext::keyMapper() const
{
return d->m_keyMapper.possibleKeys(e);
return &d->m_keyMapper;
}
QWindowsContext::HandleBaseWindowHash &QWindowsContext::windows()
@ -994,7 +1014,7 @@ bool QWindowsContext::systemParametersInfo(unsigned action, unsigned param, void
{
const BOOL result = (QWindowsContext::user32dll.systemParametersInfoForDpi != nullptr && dpi != 0)
? QWindowsContext::user32dll.systemParametersInfoForDpi(action, param, out, 0, dpi)
: SystemParametersInfo(action, param, out, 0);
: vxkex::SystemParametersInfoForDpi(action, param, out, 0, dpi);
return result == TRUE;
}
@ -1080,8 +1100,11 @@ static inline bool isInputMessage(UINT m)
static bool enableNonClientDpiScaling(HWND hwnd)
{
bool result = false;
if (QWindowsContext::user32dll.enableNonClientDpiScaling && QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
result = QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE;
if (QWindowsContext::windowDpiAwareness(hwnd) == QtWindows::DpiAwareness::PerMonitor) {
result = QWindowsContext::user32dll.enableNonClientDpiScaling ?
(QWindowsContext::user32dll.enableNonClientDpiScaling(hwnd) != FALSE) :
(vxkex::EnableNonClientDpiScaling(hwnd) != FALSE);
if (!result) {
const DWORD errorCode = GetLastError();
qErrnoWarning(int(errorCode), "EnableNonClientDpiScaling() failed for HWND %p (%lu)",
@ -1267,7 +1290,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
if (wParam == DBT_DEVNODES_CHANGED)
initTouch();
break;
case QtWindows::KeyboardLayoutChangeEvent:
case QtWindows::InputLanguageChangeEvent:
if (QWindowsInputContext *wic = windowsInputContext())
wic->handleInputLanguageChanged(wParam, lParam);
Q_FALLTHROUGH();
@ -1379,6 +1402,7 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QWindowSystemInterface::handleCloseEvent(platformWindow->window());
return true;
case QtWindows::ThemeChanged: {
QWindowsThemeCache::clearThemeCache(platformWindow->handle());
// Switch from Aero to Classic changes margins.
if (QWindowsTheme *theme = QWindowsTheme::instance())
theme->windowsThemeChanged(platformWindow->window());
@ -1517,7 +1541,7 @@ void QWindowsContext::handleFocusEvent(QtWindows::WindowsEventType et,
}
if (nextActiveWindow != d->m_lastActiveWindow) {
d->m_lastActiveWindow = nextActiveWindow;
QWindowSystemInterface::handleWindowActivated(nextActiveWindow, Qt::ActiveWindowFocusReason);
QWindowSystemInterface::handleFocusWindowChanged(nextActiveWindow, Qt::ActiveWindowFocusReason);
}
}
@ -1547,7 +1571,7 @@ bool QWindowsContext::handleContextMenuEvent(QWindow *window, const MSG &msg)
}
QWindowSystemInterface::handleContextMenuEvent(window, mouseTriggered, pos, globalPos,
QWindowsKeyMapper::queryKeyboardModifiers());
keyMapper()->queryKeyboardModifiers());
return true;
}
#endif
@ -1568,7 +1592,7 @@ void QWindowsContext::handleExitSizeMove(QWindow *window)
const Qt::MouseButtons appButtons = QGuiApplication::mouseButtons();
if (currentButtons == appButtons)
return;
const Qt::KeyboardModifiers keyboardModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const Qt::KeyboardModifiers keyboardModifiers = keyMapper()->queryKeyboardModifiers();
const QPoint globalPos = QWindowsCursor::mousePosition();
const QPlatformWindow *platWin = window->handle();
const QPoint localPos = platWin->mapFromGlobal(globalPos);

View File

@ -34,6 +34,7 @@ Q_DECLARE_LOGGING_CATEGORY(lcQpaScreen)
class QWindow;
class QPlatformScreen;
class QPlatformWindow;
class QPlatformKeyMapper;
class QWindowsMenuBar;
class QWindowsScreenManager;
class QWindowsTabletSupport;
@ -217,7 +218,7 @@ public:
unsigned systemInfo() const;
bool useRTLExtensions() const;
QList<int> possibleKeys(const QKeyEvent *e) const;
QPlatformKeyMapper *keyMapper() const;
HandleBaseWindowHash &windows();

View File

@ -28,9 +28,13 @@
#include <QtCore/qdebug.h>
#include <QtCore/qbuffer.h>
#include <QtCore/qpoint.h>
#include <QtCore/qpointer.h>
#include <QtCore/private/qcomobject_p.h>
#include <shlobj.h>
#include "vxkex.h"
QT_BEGIN_NAMESPACE
/*!
@ -167,7 +171,7 @@ static Qt::MouseButtons lastButtons = Qt::NoButton;
\internal
*/
class QWindowsOleDropSource : public QWindowsComBase<IDropSource>
class QWindowsOleDropSource : public QComObject<IDropSource>
{
public:
enum Mode {
@ -526,7 +530,8 @@ QWindowsOleDropTarget::DragLeave()
qCDebug(lcQpaMime) << __FUNCTION__ << ' ' << m_window;
lastModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const auto *keyMapper = QWindowsContext::instance()->keyMapper();
lastModifiers = keyMapper->queryKeyboardModifiers();
lastButtons = QWindowsMouseHandler::queryMouseButtons();
QWindowSystemInterface::handleDrag(m_window, nullptr, QPoint(), Qt::IgnoreAction,
@ -611,7 +616,6 @@ QWindowsOleDropTarget::Drop(LPDATAOBJECT pDataObj, DWORD grfKeyState,
*/
bool QWindowsDrag::m_canceled = false;
bool QWindowsDrag::m_dragging = false;
QWindowsDrag::QWindowsDrag() = default;
@ -671,7 +675,11 @@ static HRESULT startDoDragDrop(LPDATAOBJECT pDataObj, LPDROPSOURCE pDropSource,
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
POINTER_INFO pointerInfo{};
if (!QWindowsContext::user32dll.getPointerInfo || !QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo))
BOOL bResultPointerInfo = QWindowsContext::user32dll.getPointerInfo ?
QWindowsContext::user32dll.getPointerInfo(pointerId, &pointerInfo) :
vxkex::GetPointerInfo(pointerId, &pointerInfo);
if (!bResultPointerInfo)
return E_FAIL;
if (pointerInfo.pointerFlags & POINTER_FLAG_PRIMARY) {
@ -739,10 +747,7 @@ Qt::DropAction QWindowsDrag::drag(QDrag *drag)
const DWORD allowedEffects = translateToWinDragEffects(possibleActions);
qCDebug(lcQpaMime) << '>' << __FUNCTION__ << "possible Actions=0x"
<< Qt::hex << int(possibleActions) << "effects=0x" << allowedEffects << Qt::dec;
// Indicate message handlers we are in DoDragDrop() event loop.
QWindowsDrag::m_dragging = true;
const HRESULT r = startDoDragDrop(dropDataObject, windowDropSource, allowedEffects, &resultEffect);
QWindowsDrag::m_dragging = false;
const DWORD reportedPerformedEffect = dropDataObject->reportedPerformedEffect();
if (r == DRAGDROP_S_DROP) {
if (reportedPerformedEffect == DROPEFFECT_MOVE && resultEffect != DROPEFFECT_MOVE) {

View File

@ -17,6 +17,8 @@
#include <QtCore/private/qdebug_p.h>
#include <QtCore/private/qtools_p.h>
#include "vxkex.h"
#if defined(WM_APPCOMMAND)
# ifndef FAPPCOMMAND_MOUSE
# define FAPPCOMMAND_MOUSE 0x8000
@ -88,9 +90,17 @@ QWindowsKeyMapper::~QWindowsKeyMapper()= default;
#define VK_OEM_3 0xC0
#endif
// We not only need the scancode itself but also the extended bit of key messages. Thus we need
// the additional bit when masking the scancode.
enum { scancodeBitmask = 0x1ff };
// Get scancode from the given message
static constexpr quint32 getScancode(const MSG &msg)
{
const auto keyFlags = HIWORD(msg.lParam);
quint32 scancode = LOBYTE(keyFlags);
// if extended-key flag is on, the scan code consists of a sequence of two bytes,
// where the first byte has a value of 0xe0.
if ((keyFlags & KF_EXTENDED) != 0)
scancode |= 0xE000;
return scancode;
}
// Key recorder ------------------------------------------------------------------------[ start ] --
struct KeyRecord {
@ -532,33 +542,6 @@ QDebug operator<<(QDebug d, const KeyboardLayoutItem &k)
d << ')';
return d;
}
// Helpers to format a list of int as Qt key sequence
class formatKeys
{
public:
explicit formatKeys(const QList<int> &keys) : m_keys(keys) {}
private:
friend QDebug operator<<(QDebug d, const formatKeys &keys);
const QList<int> &m_keys;
};
QDebug operator<<(QDebug d, const formatKeys &k)
{
QDebugStateSaver saver(d);
d.nospace();
d << '(';
for (int i =0, size = k.m_keys.size(); i < size; ++i) {
if (i)
d << ", ";
d << QKeySequence(k.m_keys.at(i));
}
d << ')';
return d;
}
#else // !QT_NO_DEBUG_STREAM
static int formatKeys(const QList<int> &) { return 0; }
#endif // QT_NO_DEBUG_STREAM
/**
@ -656,7 +639,7 @@ void QWindowsKeyMapper::updateKeyMap(const MSG &msg)
{
unsigned char kbdBuffer[256]; // Will hold the complete keyboard state
GetKeyboardState(kbdBuffer);
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
const quint32 scancode = getScancode(msg);
updatePossibleKeyCodes(kbdBuffer, scancode, quint32(msg.wParam));
}
@ -751,28 +734,18 @@ static inline QString messageKeyText(const MSG &msg)
[[nodiscard]] static inline int getTitleBarHeight(const HWND hwnd)
{
if (QWindowsContext::user32dll.getDpiForWindow && QWindowsContext::user32dll.getSystemMetricsForDpi)
{
const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
const int captionHeight = QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYCAPTION, dpi);
if (IsZoomed(hwnd))
return captionHeight;
// The frame height should also be taken into account if the window
// is not maximized.
const int frameHeight = QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi)
+ QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
return captionHeight + frameHeight;
}
else
{
const int captionHeight = GetSystemMetrics(SM_CYCAPTION);
if (IsZoomed(hwnd))
return captionHeight;
// The frame height should also be taken into account if the window
// is not maximized.
const int frameHeight = GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
return captionHeight + frameHeight;
}
const BOOL bNewAPI = (QWindowsContext::user32dll.getSystemMetricsForDpi != nullptr);
const UINT dpi = bNewAPI ? QWindowsContext::user32dll.getDpiForWindow(hwnd) : vxkex::GetDpiForWindow(hwnd);
const int captionHeight = bNewAPI ? QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYCAPTION, dpi) : vxkex::GetSystemMetricsForDpi(SM_CYCAPTION, dpi);
if (IsZoomed(hwnd))
return captionHeight;
// The frame height should also be taken into account if the window
// is not maximized.
const int frameHeight = bNewAPI ?
(QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CYSIZEFRAME, dpi) + QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi))
: (vxkex::GetSystemMetricsForDpi(SM_CYSIZEFRAME, dpi) + vxkex::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi));
return captionHeight + frameHeight;
}
[[nodiscard]] static inline bool isSystemMenuOffsetNeeded(const Qt::WindowFlags flags)
@ -955,7 +928,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
m_seenAltGr = true;
const UINT msgType = msg.message;
const quint32 scancode = (msg.lParam >> 16) & scancodeBitmask;
const quint32 scancode = getScancode(msg);
auto vk_key = quint32(msg.wParam);
quint32 nModifiers = 0;
@ -1352,7 +1325,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, MSG msg,
return result;
}
Qt::KeyboardModifiers QWindowsKeyMapper::queryKeyboardModifiers()
Qt::KeyboardModifiers QWindowsKeyMapper::queryKeyboardModifiers() const
{
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
if (GetKeyState(VK_SHIFT) < 0)
@ -1366,9 +1339,9 @@ Qt::KeyboardModifiers QWindowsKeyMapper::queryKeyboardModifiers()
return modifiers;
}
QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
QList<QKeyCombination> QWindowsKeyMapper::possibleKeyCombinations(const QKeyEvent *e) const
{
QList<int> result;
QList<QKeyCombination> result;
const quint32 nativeVirtualKey = e->nativeVirtualKey();
@ -1382,31 +1355,34 @@ QList<int> QWindowsKeyMapper::possibleKeys(const QKeyEvent *e) const
quint32 baseKey = kbItem.qtKey[0];
Qt::KeyboardModifiers keyMods = e->modifiers();
if (baseKey == Qt::Key_Return && (e->nativeModifiers() & ExtendedKey)) {
result << (Qt::Key_Enter | keyMods).toCombined();
result << (Qt::Key_Enter | keyMods);
return result;
}
result << int(baseKey) + int(keyMods); // The base key is _always_ valid, of course
// The base key is _always_ valid, of course
result << QKeyCombination::fromCombined(int(baseKey) + int(keyMods));
for (size_t i = 1; i < NumMods; ++i) {
Qt::KeyboardModifiers neededMods = ModsTbl[i];
quint32 key = kbItem.qtKey[i];
if (key && key != baseKey && ((keyMods & neededMods) == neededMods)) {
const Qt::KeyboardModifiers missingMods = keyMods & ~neededMods;
const int matchedKey = int(key) + int(missingMods);
const auto it =
std::find_if(result.begin(), result.end(),
[key] (int k) { return (k & ~Qt::KeyboardModifierMask) == key; });
const auto matchedKey = QKeyCombination::fromCombined(int(key) + int(missingMods));
const auto it = std::find_if(result.begin(), result.end(),
[key](auto keyCombination) {
return keyCombination.key() == key;
});
// QTBUG-67200: Use the match with the least modifiers (prefer
// Shift+9 over Alt + Shift + 9) resulting in more missing modifiers.
if (it == result.end())
result << matchedKey;
else if (missingMods > Qt::KeyboardModifiers(*it & Qt::KeyboardModifierMask))
else if (missingMods > it->keyboardModifiers())
*it = matchedKey;
}
}
qCDebug(lcQpaEvents) << __FUNCTION__ << e << "nativeVirtualKey="
<< Qt::showbase << Qt::hex << e->nativeVirtualKey() << Qt::dec << Qt::noshowbase
<< e->modifiers() << kbItem << "\n returns" << formatKeys(result);
<< e->modifiers() << kbItem << "\n returns" << result;
return result;
}

View File

@ -27,6 +27,8 @@
#include <windowsx.h>
#include "vxkex.h"
QT_BEGIN_NAMESPACE
enum {
@ -48,7 +50,11 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
*result = 0;
const quint32 pointerId = GET_POINTERID_WPARAM(msg.wParam);
if (!QWindowsContext::user32dll.getPointerType(pointerId, &m_pointerType)) {
BOOL bResultPt = QWindowsContext::user32dll.getPointerType ?
QWindowsContext::user32dll.getPointerType(pointerId, &m_pointerType) :
vxkex::GetPointerType(pointerId, &m_pointerType);
if (!bResultPt) {
qWarning() << "GetPointerType() failed:" << qt_error_string();
return false;
}
@ -62,12 +68,21 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
}
case QT_PT_TOUCH: {
quint32 pointerCount = 0;
if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, nullptr)) {
BOOL bResultPointerTouchInfo = QWindowsContext::user32dll.getPointerFrameTouchInfo ?
QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, nullptr) :
vxkex::GetPointerFrameTouchInfo(pointerId, &pointerCount, nullptr);
if (!bResultPointerTouchInfo) {
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false;
}
QVarLengthArray<POINTER_TOUCH_INFO, 10> touchInfo(pointerCount);
if (!QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data())) {
bResultPointerTouchInfo = QWindowsContext::user32dll.getPointerFrameTouchInfo ?
QWindowsContext::user32dll.getPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data()) :
vxkex::GetPointerFrameTouchInfo(pointerId, &pointerCount, touchInfo.data());
if (!bResultPointerTouchInfo) {
qWarning() << "GetPointerFrameTouchInfo() failed:" << qt_error_string();
return false;
}
@ -80,10 +95,12 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
// dispatch any skipped frames if event compression is disabled by the app
if (historyCount > 1 && !QCoreApplication::testAttribute(Qt::AA_CompressHighFrequencyEvents)) {
touchInfo.resize(pointerCount * historyCount);
if (!QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId,
&historyCount,
&pointerCount,
touchInfo.data())) {
BOOL bResultTouchHistory = QWindowsContext::user32dll.getPointerFrameTouchInfoHistory ?
QWindowsContext::user32dll.getPointerFrameTouchInfoHistory(pointerId, &historyCount, &pointerCount, touchInfo.data()) :
vxkex::GetPointerFrameTouchInfoHistory(pointerId, &historyCount, &pointerCount, touchInfo.data());
if (!bResultTouchHistory) {
qWarning() << "GetPointerFrameTouchInfoHistory() failed:" << qt_error_string();
return false;
}
@ -101,7 +118,11 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
}
case QT_PT_PEN: {
POINTER_PEN_INFO penInfo;
if (!QWindowsContext::user32dll.getPointerPenInfo(pointerId, &penInfo)) {
BOOL bResultPenInfo = QWindowsContext::user32dll.getPointerPenInfo ?
QWindowsContext::user32dll.getPointerPenInfo(pointerId, &penInfo) : vxkex::GetPointerPenInfo(pointerId, &penInfo);
if (!bResultPenInfo) {
qWarning() << "GetPointerPenInfo() failed:" << qt_error_string();
return false;
}
@ -113,7 +134,11 @@ bool QWindowsPointerHandler::translatePointerEvent(QWindow *window, HWND hwnd, Q
|| !QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents))) {
QVarLengthArray<POINTER_PEN_INFO, 10> penInfoHistory(historyCount);
if (!QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId, &historyCount, penInfoHistory.data())) {
BOOL bResultPenInfoHistory = QWindowsContext::user32dll.getPointerPenInfoHistory ?
QWindowsContext::user32dll.getPointerPenInfoHistory(pointerId, &historyCount, penInfoHistory.data()) :
vxkex::GetPointerPenInfoHistory(pointerId, &historyCount, penInfoHistory.data());
if (!bResultPenInfoHistory) {
qWarning() << "GetPointerPenInfoHistory() failed:" << qt_error_string();
return false;
}
@ -428,8 +453,9 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
return false;
if (msg.message == WM_POINTERCAPTURECHANGED) {
const auto *keyMapper = QWindowsContext::instance()->keyMapper();
QWindowSystemInterface::handleTouchCancelEvent(window, m_touchDevice.data(),
QWindowsKeyMapper::queryKeyboardModifiers());
keyMapper->queryKeyboardModifiers());
m_lastTouchPoints.clear();
return true;
}
@ -519,7 +545,10 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
inputIds.insert(touchPoint.id);
// Avoid getting repeated messages for this frame if there are multiple pointerIds
QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
if (QWindowsContext::user32dll.skipPointerFrameMessages)
QWindowsContext::user32dll.skipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
else
vxkex::SkipPointerFrameMessages(touchInfo[i].pointerInfo.pointerId);
}
// Some devices send touches for each finger in a different message/frame, instead of consolidating
@ -539,8 +568,9 @@ bool QWindowsPointerHandler::translateTouchEvent(QWindow *window, HWND hwnd,
if (allStates == QEventPoint::State::Released)
m_touchInputIDToTouchPointID.clear();
const auto *keyMapper = QWindowsContext::instance()->keyMapper();
QWindowSystemInterface::handleTouchEvent(window, m_touchDevice.data(), touchPoints,
QWindowsKeyMapper::queryKeyboardModifiers());
keyMapper->queryKeyboardModifiers());
return false; // Allow mouse messages to be generated.
}
@ -565,7 +595,12 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
auto *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo);
RECT pRect, dRect;
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
BOOL bResultDeviceRects = QWindowsContext::user32dll.getPointerDeviceRects ?
QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect) :
vxkex::GetPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect);
if (!bResultDeviceRects)
return false;
const auto systemId = (qint64)penInfo->pointerInfo.sourceDevice;
@ -673,7 +708,8 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
wumPlatformWindow->applyCursor();
}
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const auto *keyMapper = QWindowsContext::instance()->keyMapper();
const Qt::KeyboardModifiers keyModifiers = keyMapper->queryKeyboardModifiers();
QWindowSystemInterface::handleTabletEvent(target, device.data(),
localPos, hiResGlobalPos, mouseButtons,
@ -762,7 +798,8 @@ bool QWindowsPointerHandler::translateMouseEvent(QWindow *window,
: QWindowsGeometryHint::mapFromGlobal(targetHwnd, globalPos);
}
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
const auto *keyMapper = QWindowsContext::instance()->keyMapper();
const Qt::KeyboardModifiers keyModifiers = keyMapper->queryKeyboardModifiers();
QWindow *currentWindowUnderPointer = getWindowUnderPointer(window, globalPos);
if (et == QtWindows::MouseWheelEvent)

View File

@ -32,6 +32,8 @@
#include <setupapi.h>
#include <shellscalingapi.h>
#include "vxkex.h"
QT_BEGIN_NAMESPACE
using namespace Qt::StringLiterals;
@ -43,12 +45,18 @@ static inline QDpi deviceDPI(HDC hdc)
static inline QDpi monitorDPI(HMONITOR hMonitor)
{
if (QWindowsContext::shcoredll.isValid()) {
UINT dpiX;
UINT dpiY;
if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY)))
return QDpi(dpiX, dpiY);
}
UINT dpiX;
UINT dpiY;
HRESULT hr = S_OK;
if (QWindowsContext::shcoredll.isValid())
hr = QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
else
hr = vxkex::GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (SUCCEEDED(hr))
return QDpi(dpiX, dpiY);
return {0, 0};
}
@ -579,51 +587,58 @@ QRect QWindowsScreen::virtualGeometry(const QPlatformScreen *screen) // cf QScre
bool QWindowsScreen::setOrientationPreference(Qt::ScreenOrientation o)
{
bool result = false;
if (QWindowsContext::user32dll.setDisplayAutoRotationPreferences) {
ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
switch (o) {
case Qt::PrimaryOrientation:
break;
case Qt::PortraitOrientation:
orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT;
break;
case Qt::LandscapeOrientation:
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE;
break;
case Qt::InvertedPortraitOrientation:
orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED;
break;
case Qt::InvertedLandscapeOrientation:
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
break;
}
result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences(orientationPreference);
ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
switch (o) {
case Qt::PrimaryOrientation:
break;
case Qt::PortraitOrientation:
orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT;
break;
case Qt::LandscapeOrientation:
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE;
break;
case Qt::InvertedPortraitOrientation:
orientationPreference = ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED;
break;
case Qt::InvertedLandscapeOrientation:
orientationPreference = ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED;
break;
}
if (QWindowsContext::user32dll.setDisplayAutoRotationPreferences)
result = QWindowsContext::user32dll.setDisplayAutoRotationPreferences(orientationPreference);
else
result = vxkex::SetDisplayAutoRotationPreferences(orientationPreference);
return result;
}
Qt::ScreenOrientation QWindowsScreen::orientationPreference()
{
Qt::ScreenOrientation result = Qt::PrimaryOrientation;
if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences) {
DWORD orientationPreference = ORIENTATION_PREFERENCE_NONE;
if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences(&orientationPreference)) {
switch (orientationPreference) {
case ORIENTATION_PREFERENCE_NONE:
break;
case ORIENTATION_PREFERENCE_LANDSCAPE:
result = Qt::LandscapeOrientation;
break;
case ORIENTATION_PREFERENCE_PORTRAIT:
result = Qt::PortraitOrientation;
break;
case ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED:
result = Qt::InvertedLandscapeOrientation;
break;
case ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED:
result = Qt::InvertedPortraitOrientation;
break;
}
ORIENTATION_PREFERENCE orientationPreference = ORIENTATION_PREFERENCE_NONE;
BOOL bResult = TRUE;
if (QWindowsContext::user32dll.getDisplayAutoRotationPreferences)
bResult = QWindowsContext::user32dll.getDisplayAutoRotationPreferences((DWORD *)&orientationPreference);
else
bResult = vxkex::GetDisplayAutoRotationPreferences(&orientationPreference);
if (bResult) {
switch (orientationPreference) {
case ORIENTATION_PREFERENCE_NONE:
break;
case ORIENTATION_PREFERENCE_LANDSCAPE:
result = Qt::LandscapeOrientation;
break;
case ORIENTATION_PREFERENCE_PORTRAIT:
result = Qt::PortraitOrientation;
break;
case ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED:
result = Qt::InvertedLandscapeOrientation;
break;
case ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED:
result = Qt::InvertedPortraitOrientation;
break;
}
}
return result;
@ -704,11 +719,15 @@ void QWindowsScreenManager::initialize()
handleScreenChanges();
}
QWindowsScreenManager::~QWindowsScreenManager()
void QWindowsScreenManager::destroyWindow()
{
qCDebug(lcQpaScreen) << "Destroying display change observer" << m_displayChangeObserver;
DestroyWindow(m_displayChangeObserver);
m_displayChangeObserver = nullptr;
}
QWindowsScreenManager::~QWindowsScreenManager() = default;
bool QWindowsScreenManager::isSingleScreen()
{
return QWindowsContext::instance()->screenManager().screens().size() < 2;

View File

@ -7,6 +7,7 @@
#include "qwindowsmenu.h"
#include "qwindowsdialoghelpers.h"
#include "qwindowscontext.h"
#include "qwindowsiconengine.h"
#include "qwindowsintegration.h"
#if QT_CONFIG(systemtrayicon)
# include "qwindowssystemtrayicon.h"
@ -27,6 +28,7 @@
#include <QtCore/qthread.h>
#include <QtCore/qmutex.h>
#include <QtCore/qwaitcondition.h>
#include <QtCore/qoperatingsystemversion.h>
#include <QtGui/qcolor.h>
#include <QtGui/qpalette.h>
#include <QtGui/qguiapplication.h>
@ -42,7 +44,7 @@
#include <algorithm>
#include <VersionHelpers.h>
#include "vxkex.h"
#if QT_CONFIG(cpp_winrt)
# include <QtCore/private/qt_winrtbase_p.h>
@ -81,11 +83,11 @@ static inline QColor mixColors(const QColor &c1, const QColor &c2)
(c1.blue() + c2.blue()) / 2};
}
static inline QColor getSysColor(int index)
{
COLORREF cr = GetSysColor(index);
return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
}
enum AccentColorLevel {
AccentColorDarkest,
AccentColorNormal,
AccentColorLightest
};
#if QT_CONFIG(cpp_winrt)
static constexpr QColor getSysColor(winrt::Windows::UI::Color &&color)
@ -94,6 +96,54 @@ static constexpr QColor getSysColor(winrt::Windows::UI::Color &&color)
}
#endif
[[maybe_unused]] [[nodiscard]] static inline QColor qt_accentColor(AccentColorLevel level)
{
QColor accent;
QColor accentLight;
QColor accentDarkest;
#if QT_CONFIG(cpp_winrt)
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
{
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
}
#endif
if (!accent.isValid())
{
const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
if (!registry.isValid())
return {};
const QVariant value = registry.value(L"AccentColor");
if (!value.isValid())
return {};
// The retrieved value is in the #AABBGGRR format, we need to
// convert it to the #AARRGGBB format which Qt expects.
const QColor abgr = QColor::fromRgba(qvariant_cast<DWORD>(value));
if (!abgr.isValid())
return {};
accent = QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
accentLight = accent.lighter(120);
accentDarkest = accent.darker(120 * 120 * 120);
}
if (level == AccentColorDarkest)
return accentDarkest;
else if (level == AccentColorLightest)
return accentLight;
return accent;
}
static inline QColor getSysColor(int index)
{
COLORREF cr = GetSysColor(index);
return QColor(GetRValue(cr), GetGValue(cr), GetBValue(cr));
}
// QTBUG-48823/Windows 10: SHGetFileInfo() (as called by item views on file system
// models has been observed to trigger a WM_PAINT on the mainwindow. Suppress the
// behavior by running it in a thread.
@ -223,44 +273,17 @@ static QColor placeHolderColor(QColor textColor)
return textColor;
}
[[maybe_unused]] [[nodiscard]] static inline QColor qt_accentColor()
{
const QWinRegistryKey registry(HKEY_CURRENT_USER, LR"(Software\Microsoft\Windows\DWM)");
if (!registry.isValid())
return {};
const QVariant value = registry.value(L"AccentColor");
if (!value.isValid())
return {};
// The retrieved value is in the #AABBGGRR format, we need to
// convert it to the #AARRGGBB format which Qt expects.
const QColor abgr = QColor::fromRgba(qvariant_cast<DWORD>(value));
if (!abgr.isValid())
return {};
return QColor::fromRgb(abgr.blue(), abgr.green(), abgr.red(), abgr.alpha());
}
/*
This is used when the theme is light mode, and when the theme is dark but the
application doesn't support dark mode. In the latter case, we need to check.
*/
static void populateLightSystemBasePalette(QPalette &result)
{
QColor background = getSysColor(COLOR_BTNFACE);
QColor textColor = getSysColor(COLOR_WINDOWTEXT);
QColor accent = qt_accentColor();
QColor accentDarkest = accent.darker(120 * 120 * 120);
const QColor background = getSysColor(COLOR_BTNFACE);
const QColor textColor = getSysColor(COLOR_WINDOWTEXT);
#if QT_CONFIG(cpp_winrt)
if (IsWindows10OrGreater())
{
// respect the Windows 11 accent color
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
}
#endif
const QColor accent = qt_accentColor(AccentColorNormal);
const QColor accentDarkest = qt_accentColor(AccentColorDarkest);
const QColor linkColor = accent;
const QColor btnFace = background;
@ -298,7 +321,7 @@ static void populateDarkSystemBasePalette(QPalette &result)
{
QColor foreground = Qt::white;
QColor background = QColor(0x1E, 0x1E, 0x1E);
QColor accent = qt_accentColor();
QColor accent = qt_accentColor(AccentColorNormal);
QColor accentDark = accent.darker(120);
QColor accentDarker = accentDark.darker(120);
QColor accentDarkest = accentDarker.darker(120);
@ -307,7 +330,7 @@ static void populateDarkSystemBasePalette(QPalette &result)
QColor accentLightest = accentLighter.lighter(120);
#if QT_CONFIG(cpp_winrt)
if (IsWindows10OrGreater())
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
{
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
@ -472,7 +495,10 @@ static inline QStringList iconThemeSearchPaths()
static inline QStringList styleNames()
{
return { QStringLiteral("WindowsVista"), QStringLiteral("Windows") };
QStringList styles = { QStringLiteral("WindowsVista"), QStringLiteral("Windows") };
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows11)
styles.prepend(QStringLiteral("Windows11"));
return styles;
}
static inline int uiEffects()
@ -537,6 +563,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
Qt::ColorScheme QWindowsTheme::colorScheme() const
{
if (queryHighContrast())
return Qt::ColorScheme::Unknown;
return QWindowsContext::isDarkMode() ? Qt::ColorScheme::Dark : Qt::ColorScheme::Light;
}
@ -559,24 +587,10 @@ void QWindowsTheme::refreshPalettes()
m_palettes[MenuPalette] = new QPalette(menuPalette(*m_palettes[SystemPalette], light));
m_palettes[MenuBarPalette] = menuBarPalette(*m_palettes[MenuPalette], light);
if (!light) {
QColor accent = qt_accentColor();
QColor accentLight = accent.lighter(120);
QColor accentDarkest = accent.darker(120 * 120 * 120);
#if QT_CONFIG(cpp_winrt)
if (IsWindows10OrGreater())
{
using namespace winrt::Windows::UI::ViewManagement;
const auto settings = UISettings();
accent = getSysColor(settings.GetColorValue(UIColorType::Accent));
accentLight = getSysColor(settings.GetColorValue(UIColorType::AccentLight1));
accentDarkest = getSysColor(settings.GetColorValue(UIColorType::AccentDark3));
}
#endif
m_palettes[CheckBoxPalette] = new QPalette(*m_palettes[SystemPalette]);
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Base, accent);
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Button, accentLight);
m_palettes[CheckBoxPalette]->setColor(QPalette::Inactive, QPalette::Base, accentDarkest);
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Base, qt_accentColor(AccentColorNormal));
m_palettes[CheckBoxPalette]->setColor(QPalette::Active, QPalette::Button, qt_accentColor(AccentColorLightest));
m_palettes[CheckBoxPalette]->setColor(QPalette::Inactive, QPalette::Base, qt_accentColor(AccentColorDarkest));
m_palettes[RadioButtonPalette] = new QPalette(*m_palettes[CheckBoxPalette]);
}
}
@ -586,15 +600,15 @@ QPalette QWindowsTheme::systemPalette(Qt::ColorScheme colorScheme)
QPalette result = standardPalette();
switch (colorScheme) {
case Qt::ColorScheme::Light:
populateLightSystemBasePalette(result);
break;
case Qt::ColorScheme::Dark:
populateDarkSystemBasePalette(result);
break;
default:
qFatal("Unknown color scheme");
break;
case Qt::ColorScheme::Light:
populateLightSystemBasePalette(result);
break;
case Qt::ColorScheme::Dark:
populateDarkSystemBasePalette(result);
break;
default:
qFatal("Unknown color scheme");
break;
}
if (result.window() != result.base()) {
@ -675,14 +689,11 @@ void QWindowsTheme::refreshFonts()
fixedFont.setStyleHint(QFont::TypeWriter);
LOGFONT lfIconTitleFont;
QFont iconTitleFont;
if (QWindowsContext::user32dll.systemParametersInfoForDpi) {
if (QWindowsContext::user32dll.systemParametersInfoForDpi)
QWindowsContext::user32dll.systemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
} else {
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont);
}
else
vxkex::SystemParametersInfoForDpi(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0, dpi);
const QFont iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont, dpi);
m_fonts[SystemFont] = new QFont(QWindowsFontDatabase::systemDefaultFont());
m_fonts[MenuFont] = new QFont(menuFont);
@ -856,15 +867,18 @@ QPixmap QWindowsTheme::standardPixmap(StandardPixmap sp, const QSizeF &pixmapSiz
}
if (stockId != SIID_INVALID) {
QPixmap pixmap;
SHSTOCKICONINFO iconInfo;
memset(&iconInfo, 0, sizeof(iconInfo));
iconInfo.cbSize = sizeof(iconInfo);
stockFlags |= (pixmapSize.width() > 16 ? SHGFI_LARGEICON : SHGFI_SMALLICON);
if (SHGetStockIconInfo(stockId, SHGFI_ICON | stockFlags, &iconInfo) == S_OK) {
pixmap = qt_pixmapFromWinHICON(iconInfo.hIcon);
DestroyIcon(iconInfo.hIcon);
return pixmap;
stockFlags |= SHGSI_ICONLOCATION;
if (SHGetStockIconInfo(stockId, stockFlags, &iconInfo) == S_OK) {
const auto iconSize = pixmapSize.width();
HICON icon;
if (SHDefExtractIcon(iconInfo.szPath, iconInfo.iIcon, 0, &icon, nullptr, iconSize) == S_OK) {
QPixmap pixmap = qt_pixmapFromWinHICON(icon);
DestroyIcon(icon);
return pixmap;
}
}
}
@ -1088,6 +1102,11 @@ QIcon QWindowsTheme::fileIcon(const QFileInfo &fileInfo, QPlatformTheme::IconOpt
return QIcon(new QWindowsFileIconEngine(fileInfo, iconOptions));
}
QIconEngine *QWindowsTheme::createIconEngine(const QString &iconName) const
{
return new QWindowsIconEngine(iconName);
}
static inline bool doUseNativeMenus()
{
const unsigned options = QWindowsIntegration::instance()->options();

View File

@ -27,6 +27,7 @@
#include <QtGui/qwindow.h>
#include <QtGui/qregion.h>
#include <QtGui/qopenglcontext.h>
#include <QtGui/private/qwindowsthemecache_p.h>
#include <private/qwindow_p.h> // QWINDOWSIZE_MAX
#include <private/qguiapplication_p.h>
#include <private/qhighdpiscaling_p.h>
@ -43,6 +44,8 @@
#include <shellscalingapi.h>
#include "vxkex.h"
QT_BEGIN_NAMESPACE
using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;
@ -526,8 +529,8 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
return QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXSIZEFRAME, dpi)
+ QWindowsContext::user32dll.getSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
}
return GetSystemMetrics(SM_CXSIZEFRAME) + GetSystemMetrics(SM_CXPADDEDBORDER);
else
return vxkex::GetSystemMetricsForDpi(SM_CXSIZEFRAME, dpi) + vxkex::GetSystemMetricsForDpi(SM_CXPADDEDBORDER, dpi);
}
/*!
@ -537,16 +540,22 @@ static inline void updateGLWindowSettings(const QWindow *w, HWND hwnd, Qt::Windo
static QMargins invisibleMargins(QPoint screenPoint)
{
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10) {
POINT pt = {screenPoint.x(), screenPoint.y()};
if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
if (QWindowsContext::shcoredll.isValid()) {
UINT dpiX;
UINT dpiY;
if (SUCCEEDED(QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY))) {
const int gap = getResizeBorderThickness(dpiX);
return QMargins(gap, 0, gap, gap);
}
POINT pt = {screenPoint.x(), screenPoint.y()};
if (HMONITOR hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONULL)) {
if (QWindowsContext::shcoredll.isValid()) {
UINT dpiX;
UINT dpiY;
HRESULT hr = S_OK;
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion::Windows10)
hr = QWindowsContext::shcoredll.getDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
else
hr = vxkex::GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (SUCCEEDED(hr)) {
const int gap = getResizeBorderThickness(dpiX);
return QMargins(gap, 0, gap, gap);
}
}
}
@ -555,12 +564,10 @@ static QMargins invisibleMargins(QPoint screenPoint)
[[nodiscard]] static inline QMargins invisibleMargins(const HWND hwnd)
{
if (QWindowsContext::user32dll.getDpiForWindow) {
const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
const int gap = getResizeBorderThickness(dpi);
return QMargins(gap, 0, gap, gap);
}
return QMargins();
const UINT dpi = (QWindowsContext::user32dll.getDpiForWindow) ? QWindowsContext::user32dll.getDpiForWindow(hwnd) : vxkex::GetDpiForWindow(hwnd);
const int gap = getResizeBorderThickness(dpi);
return QMargins(gap, 0, gap, gap);
}
/*!
@ -848,6 +855,10 @@ void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flag
// NOTE: WS_EX_TRANSPARENT flag can make mouse inputs fall through a layered window
if (flagsIn & Qt::WindowTransparentForInput)
exStyle |= WS_EX_LAYERED | WS_EX_TRANSPARENT;
// Currently only compatible with D3D surfaces, use it with care.
if (qEnvironmentVariableIntValue("QT_QPA_DISABLE_REDIRECTION_SURFACE"))
exStyle |= WS_EX_NOREDIRECTIONBITMAP;
}
}
@ -1074,10 +1085,17 @@ QMargins QWindowsGeometryHint::frame(const QWindow *w, DWORD style, DWORD exStyl
return {};
RECT rect = {0,0,0,0};
style &= ~DWORD(WS_OVERLAPPED); // Not permitted, see docs.
if (QWindowsContext::user32dll.adjustWindowRectExForDpi &&
QWindowsContext::user32dll.adjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE) {
qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__);
if (QWindowsContext::user32dll.adjustWindowRectExForDpi)
{
if (QWindowsContext::user32dll.adjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE)
qErrnoWarning("%s: AdjustWindowRectExForDpi failed", __FUNCTION__);
}
else
{
if (vxkex::AdjustWindowRectExForDpi(&rect, style, FALSE, exStyle, unsigned(qRound(dpi))) == FALSE)
qErrnoWarning("%s: vxkex::AdjustWindowRectExForDpi failed", __FUNCTION__);
}
const QMargins result(qAbs(rect.left), qAbs(rect.top),
qAbs(rect.right), qAbs(rect.bottom));
qCDebug(lcQpaWindow).nospace() << __FUNCTION__ << " style="
@ -1364,6 +1382,8 @@ QWindowsForeignWindow::QWindowsForeignWindow(QWindow *window, HWND hwnd)
, m_hwnd(hwnd)
, m_topLevelStyle(0)
{
if (QPlatformWindow::parent())
setParent(QPlatformWindow::parent());
}
void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
@ -1539,6 +1559,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
QWindowsWindow::~QWindowsWindow()
{
setFlag(WithinDestroy);
QWindowsThemeCache::clearThemeCache(m_data.hwnd);
if (testFlag(TouchRegistered))
UnregisterTouchWindow(m_data.hwnd);
destroyWindow();
@ -1568,7 +1589,7 @@ void QWindowsWindow::initialize()
}
}
QWindowsWindow::setSavedDpi(QWindowsContext::user32dll.getDpiForWindow ?
QWindowsContext::user32dll.getDpiForWindow(handle()) : 96);
QWindowsContext::user32dll.getDpiForWindow(handle()) : vxkex::GetDpiForWindow(handle()));
}
QSurfaceFormat QWindowsWindow::format() const
@ -2018,6 +2039,9 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
const UINT dpi = HIWORD(wParam);
const qreal scale = dpiRelativeScale(dpi);
setSavedDpi(dpi);
QWindowsThemeCache::clearThemeCache(hwnd);
// Send screen change first, so that the new screen is set during any following resize
checkForScreenChanged(QWindowsWindow::FromDpiChange);
@ -2060,20 +2084,17 @@ void QWindowsWindow::handleDpiChanged(HWND hwnd, WPARAM wParam, LPARAM lParam)
void QWindowsWindow::handleDpiChangedAfterParent(HWND hwnd)
{
if (QWindowsContext::user32dll.getDpiForWindow)
{
const UINT dpi = QWindowsContext::user32dll.getDpiForWindow(hwnd);
const qreal scale = dpiRelativeScale(dpi);
setSavedDpi(dpi);
const UINT dpi = QWindowsContext::user32dll.getDpiForWindow ? QWindowsContext::user32dll.getDpiForWindow(hwnd) : vxkex::GetDpiForWindow(hwnd);
const qreal scale = dpiRelativeScale(dpi);
setSavedDpi(dpi);
checkForScreenChanged(QWindowsWindow::FromDpiChange);
checkForScreenChanged(QWindowsWindow::FromDpiChange);
// Child windows do not get WM_GETDPISCALEDSIZE messages to inform
// Windows about the new size, so we need to manually scale them.
QRect currentGeometry = geometry();
QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
setGeometry(scaledGeometry);
}
// Child windows do not get WM_GETDPISCALEDSIZE messages to inform
// Windows about the new size, so we need to manually scale them.
QRect currentGeometry = geometry();
QRect scaledGeometry = QRect(currentGeometry.topLeft() * scale, currentGeometry.size() * scale);
setGeometry(scaledGeometry);
}
static QRect normalFrameGeometry(HWND hwnd)
@ -2485,6 +2506,11 @@ void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
GetWindowPlacement(m_data.hwnd, &windowPlacement);
const RECT geometry = RECTfromQRect(m_data.restoreGeometry);
windowPlacement.rcNormalPosition = geometry;
// Even if the window is hidden, windowPlacement's showCmd is not SW_HIDE, so change it
// manually to avoid unhiding a hidden window with the subsequent call to
// SetWindowPlacement().
if (!isVisible())
windowPlacement.showCmd = SW_HIDE;
SetWindowPlacement(m_data.hwnd, &windowPlacement);
}
// QTBUG-17548: We send expose events when receiving WM_Paint, but for

View File

@ -0,0 +1,430 @@
#pragma once
#include <shtypes.h>
#include <winuser.h>
#include <windef.h>
#include <shellscalingapi.h>
#define MDT_MAXIMUM_DPI 3
namespace vxkex {
static INT GetSystemMetricsForDpi(
IN INT Index,
IN UINT Dpi)
{
INT Value;
Value = GetSystemMetrics(Index);
switch (Index) {
case SM_CXVSCROLL:
case SM_CYHSCROLL:
case SM_CYCAPTION:
case SM_CYVTHUMB:
case SM_CXHTHUMB:
case SM_CXICON:
case SM_CYICON:
case SM_CXCURSOR:
case SM_CYCURSOR:
case SM_CYMENU:
case SM_CYVSCROLL:
case SM_CXHSCROLL:
case SM_CXMIN:
case SM_CXMINTRACK:
case SM_CYMIN:
case SM_CYMINTRACK:
case SM_CXSIZE:
case SM_CXFRAME:
case SM_CYFRAME:
case SM_CXICONSPACING:
case SM_CYICONSPACING:
case SM_CXSMICON:
case SM_CYSMICON:
case SM_CYSMCAPTION:
case SM_CXSMSIZE:
case SM_CYSMSIZE:
case SM_CXMENUSIZE:
case SM_CYMENUSIZE:
case SM_CXMENUCHECK:
case SM_CYMENUCHECK:
// These are pixel values that have to be scaled according to DPI.
Value *= Dpi;
Value /= USER_DEFAULT_SCREEN_DPI;
break;
}
return Value;
}
static BOOL SystemParametersInfoForDpi(
IN UINT Action,
IN UINT Parameter,
IN OUT PVOID Data,
IN UINT WinIni,
IN UINT Dpi)
{
switch (Action) {
case SPI_GETICONTITLELOGFONT:
return SystemParametersInfo(Action, Parameter, Data, 0);
case SPI_GETICONMETRICS:
{
BOOL Success;
PICONMETRICS IconMetrics;
Success = SystemParametersInfo(Action, Parameter, Data, 0);
if (Success) {
IconMetrics = (PICONMETRICS) Data;
IconMetrics->iHorzSpacing *= Dpi;
IconMetrics->iVertSpacing *= Dpi;
IconMetrics->iHorzSpacing /= USER_DEFAULT_SCREEN_DPI;
IconMetrics->iVertSpacing /= USER_DEFAULT_SCREEN_DPI;
}
return Success;
}
case SPI_GETNONCLIENTMETRICS:
{
BOOL Success;
PNONCLIENTMETRICS NonClientMetrics;
Success = SystemParametersInfo(Action, Parameter, Data, 0);
if (Success) {
NonClientMetrics = (PNONCLIENTMETRICS) Data;
NonClientMetrics->iBorderWidth *= Dpi;
NonClientMetrics->iScrollWidth *= Dpi;
NonClientMetrics->iScrollHeight *= Dpi;
NonClientMetrics->iCaptionWidth *= Dpi;
NonClientMetrics->iCaptionHeight *= Dpi;
NonClientMetrics->iSmCaptionWidth *= Dpi;
NonClientMetrics->iSmCaptionHeight *= Dpi;
NonClientMetrics->iMenuWidth *= Dpi;
NonClientMetrics->iMenuHeight *= Dpi;
NonClientMetrics->iPaddedBorderWidth *= Dpi;
NonClientMetrics->iBorderWidth /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iScrollWidth /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iScrollHeight /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iCaptionWidth /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iCaptionHeight /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iSmCaptionWidth /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iSmCaptionHeight /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iMenuWidth /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iMenuHeight /= USER_DEFAULT_SCREEN_DPI;
NonClientMetrics->iPaddedBorderWidth /= USER_DEFAULT_SCREEN_DPI;
}
return Success;
}
default:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
static HRESULT GetScaleFactorForMonitor(
IN HMONITOR Monitor,
OUT DEVICE_SCALE_FACTOR *ScaleFactor)
{
HDC DeviceContext;
ULONG LogPixelsX;
DeviceContext = GetDC(NULL);
if (!DeviceContext) {
*ScaleFactor = SCALE_100_PERCENT;
return S_OK;
}
LogPixelsX = GetDeviceCaps(DeviceContext, LOGPIXELSX);
ReleaseDC(NULL, DeviceContext);
*ScaleFactor = (DEVICE_SCALE_FACTOR) (9600 / LogPixelsX);
return S_OK;
}
static HRESULT GetDpiForMonitor(
IN HMONITOR Monitor,
IN MONITOR_DPI_TYPE DpiType,
OUT UINT * DpiX,
OUT UINT * DpiY)
{
HDC DeviceContext;
if (DpiType >= MDT_MAXIMUM_DPI) {
return E_INVALIDARG;
}
if (!DpiX || !DpiY) {
return E_INVALIDARG;
}
if (!IsProcessDPIAware()) {
*DpiX = USER_DEFAULT_SCREEN_DPI;
*DpiY = USER_DEFAULT_SCREEN_DPI;
return S_OK;
}
DeviceContext = GetDC(NULL);
if (!DeviceContext) {
*DpiX = USER_DEFAULT_SCREEN_DPI;
*DpiY = USER_DEFAULT_SCREEN_DPI;
return S_OK;
}
*DpiX = GetDeviceCaps(DeviceContext, LOGPIXELSX);
*DpiY = GetDeviceCaps(DeviceContext, LOGPIXELSY);
if (DpiType == MDT_EFFECTIVE_DPI) {
DEVICE_SCALE_FACTOR ScaleFactor;
// We have to multiply the DPI values by the scaling factor.
vxkex::GetScaleFactorForMonitor(Monitor, &ScaleFactor);
*DpiX *= ScaleFactor;
*DpiY *= ScaleFactor;
*DpiX /= 100;
*DpiY /= 100;
}
ReleaseDC(NULL, DeviceContext);
return S_OK;
}
static UINT GetDpiForSystem(
VOID)
{
HDC DeviceContext;
ULONG LogPixelsX;
if (!IsProcessDPIAware()) {
return 96;
}
DeviceContext = GetDC(NULL);
if (!DeviceContext) {
return 96;
}
LogPixelsX = GetDeviceCaps(DeviceContext, LOGPIXELSX);
ReleaseDC(NULL, DeviceContext);
return LogPixelsX;
}
static UINT GetDpiForWindow(
IN HWND Window)
{
if (!IsWindow(Window)) {
return 0;
}
return vxkex::GetDpiForSystem();
}
static BOOL AdjustWindowRectExForDpi(
IN OUT LPRECT Rect,
IN ULONG WindowStyle,
IN BOOL HasMenu,
IN ULONG WindowExStyle,
IN ULONG Dpi)
{
// I'm not sure how to implement this function properly.
// If it turns out to be important, I'll have to do some testing
// on a Win10 VM.
return AdjustWindowRectEx(
Rect,
WindowStyle,
HasMenu,
WindowExStyle);
}
static BOOL SetDisplayAutoRotationPreferences(
IN ORIENTATION_PREFERENCE Orientation)
{
return TRUE;
}
static BOOL GetDisplayAutoRotationPreferences(
OUT ORIENTATION_PREFERENCE * Orientation)
{
*Orientation = ORIENTATION_PREFERENCE_NONE;
return TRUE;
}
// scaling.c
static BOOL SetProcessDpiAwarenessContext(
IN DPI_AWARENESS_CONTEXT DpiContext)
{
switch ((ULONG_PTR)DpiContext) {
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
//NOTHING;
break;
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2:
SetProcessDPIAware();
break;
default:
return FALSE;
}
return TRUE;
}
static BOOL AreDpiAwarenessContextsEqual(
IN DPI_AWARENESS_CONTEXT Value1,
IN DPI_AWARENESS_CONTEXT Value2)
{
return (Value1 == Value2);
}
static BOOL IsValidDpiAwarenessContext(
IN DPI_AWARENESS_CONTEXT Value)
{
switch ((ULONG_PTR)Value) {
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2:
return TRUE;
default:
return FALSE;
}
}
static BOOL EnableNonClientDpiScaling(
IN HWND Window)
{
return TRUE;
}
static DPI_AWARENESS_CONTEXT GetThreadDpiAwarenessContext(
VOID)
{
if (IsProcessDPIAware()) {
return DPI_AWARENESS_CONTEXT_SYSTEM_AWARE;
} else {
return DPI_AWARENESS_CONTEXT_UNAWARE;
}
}
static DPI_AWARENESS_CONTEXT GetWindowDpiAwarenessContext(
IN HWND Window)
{
ULONG WindowThreadId;
ULONG WindowProcessId;
WindowThreadId = GetWindowThreadProcessId(Window, &WindowProcessId);
if (!WindowThreadId) {
return 0;
}
// looks like there's a bug in vxkex, here should be == instead of =
// and if is always true
// anyway I don't want to deal with Windows kernel mode structures here
if (1) { //if (WindowProcessId = (ULONG) NtCurrentTeb()->ClientId.UniqueProcess) {
return vxkex::GetThreadDpiAwarenessContext();
}
return DPI_AWARENESS_CONTEXT_UNAWARE;
}
// pointer.c
static BOOL GetPointerType(
IN UINT32 PointerId,
OUT POINTER_INPUT_TYPE *PointerType)
{
*PointerType = PT_MOUSE;
return TRUE;
}
static BOOL GetPointerFrameTouchInfo(
IN UINT32 PointerId,
IN OUT UINT32 *PointerCount,
OUT LPVOID TouchInfo)
{
return FALSE;
}
static BOOL GetPointerFrameTouchInfoHistory(
IN UINT32 PointerId,
IN OUT UINT32 *EntriesCount,
IN OUT UINT32 *PointerCount,
OUT LPVOID TouchInfo)
{
return FALSE;
}
static BOOL GetPointerPenInfo(
IN UINT32 PointerId,
OUT LPVOID PenInfo)
{
return FALSE;
}
static BOOL GetPointerPenInfoHistory(
IN UINT32 PointerId,
IN OUT UINT32 *EntriesCount,
OUT LPVOID PenInfo)
{
return FALSE;
}
static BOOL SkipPointerFrameMessages(
IN UINT32 PointerId)
{
return TRUE;
}
static BOOL GetPointerDeviceRects(
IN HANDLE Device,
OUT LPRECT PointerDeviceRect,
OUT LPRECT DisplayRect)
{
PointerDeviceRect->top = 0;
PointerDeviceRect->left = 0;
PointerDeviceRect->bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
PointerDeviceRect->right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
DisplayRect->top = 0;
DisplayRect->left = 0;
DisplayRect->bottom = GetSystemMetrics(SM_CYVIRTUALSCREEN);
DisplayRect->right = GetSystemMetrics(SM_CXVIRTUALSCREEN);
return TRUE;
}
static BOOL GetPointerInfo(
IN DWORD PointerId,
OUT POINTER_INFO *PointerInfo)
{
PointerInfo->pointerType = PT_MOUSE;
PointerInfo->pointerId = PointerId;
PointerInfo->frameId = 0;
PointerInfo->pointerFlags = POINTER_FLAG_NONE;
PointerInfo->sourceDevice = NULL;
PointerInfo->hwndTarget = NULL;
GetCursorPos(&PointerInfo->ptPixelLocation);
GetCursorPos(&PointerInfo->ptHimetricLocation);
GetCursorPos(&PointerInfo->ptPixelLocationRaw);
GetCursorPos(&PointerInfo->ptHimetricLocationRaw);
PointerInfo->dwTime = 0;
PointerInfo->historyCount = 1;
PointerInfo->InputData = 0;
PointerInfo->dwKeyStates = 0;
PointerInfo->PerformanceCount = 0;
PointerInfo->ButtonChangeType = POINTER_CHANGE_NONE;
return TRUE;
}
} // namespace vxkex