QT源码拾贝6-11(qwindowswindow)

简介: 这篇文章深入探讨了Qt源码中与窗口激活相关的函数,QDebug运算符重载,vscode的变量提示,Windows常用类型名,获取所有窗体的方法,以及QSharedPointer智能指针的使用。

上一篇博客:

QT源码拾贝0-5(qimage和qpainter)

6 窗口激活相关的函数QWindowsForeignWindow::setParent

C:\Qt\6.5.0\Src\qtbase\src\plugins\platforms\windows\qwindowswindow.cpp


void QWindowsForeignWindow::setParent(const QPlatformWindow *newParentWindow)
{
   
    const bool wasTopLevel = isTopLevel_sys();
    const HWND newParent = newParentWindow ? reinterpret_cast<HWND>(newParentWindow->winId()) : HWND(nullptr);
    const bool isTopLevel = !newParent;
    const DWORD oldStyle = style();
    qCDebug(lcQpaWindow) << __FUNCTION__ << window() << "newParent="
        << newParentWindow << newParent << "oldStyle=" << debugWinStyle(oldStyle);
    SetParent(m_hwnd, newParent);
    if (wasTopLevel != isTopLevel) {
    // Top level window flags need to be set/cleared manually.
        DWORD newStyle = oldStyle;
        if (isTopLevel) {
   
            newStyle = m_topLevelStyle;
        } else {
   
            m_topLevelStyle = oldStyle;
            newStyle &= ~(WS_OVERLAPPEDWINDOW | WS_POPUPWINDOW);
            newStyle |= WS_CHILD;
        }
        SetWindowLongPtr(m_hwnd, GWL_STYLE, newStyle);
    }
}



void WindowCreationData::fromWindow(const QWindow *w, const Qt::WindowFlags flagsIn,
                                    unsigned creationFlags)
{
   
    flags = flagsIn;

    // Sometimes QWindow doesn't have a QWindow parent but does have a native parent window,
    // e.g. in case of embedded ActiveQt servers. They should not be considered a top-level
    // windows in such cases.
    QVariant prop = w->property(QWindowsWindow::embeddedNativeParentHandleProperty);
    if (prop.isValid()) {
   
        embedded = true;
        parentHandle = reinterpret_cast<HWND>(prop.value<WId>());
    }

    if (creationFlags & ForceChild) {
   
        topLevel = false;
    } else if (embedded) {
   
        // Embedded native windows (for example Active X server windows) are by
        // definition never toplevel, even though they do not have QWindow parents.
        topLevel = false;
    } else {
   
        topLevel = (creationFlags & ForceTopLevel) ? true : w->isTopLevel();
    }

    if (topLevel)
        fixTopLevelWindowFlags(flags);

    type = static_cast<Qt::WindowType>(int(flags) & Qt::WindowType_Mask);
    switch (type) {
   
    case Qt::Dialog:
    case Qt::Sheet:
        dialog = true;
        break;
    case Qt::Drawer:
    case Qt::Tool:
        tool = true;
        break;
    case Qt::Popup:
        popup = true;
        break;
    default:
        break;
    }
    if ((flags & Qt::MSWindowsFixedSizeDialogHint))
        dialog = true;

    // This causes the title bar to drawn RTL and the close button
    // to be left. Note that this causes:
    // - All DCs created on the Window to have RTL layout (see SetLayout)
    // - ClientToScreen() and ScreenToClient() to work in reverse as well.
    // - Mouse event coordinates to be mirrored.
    // - Positioning of child Windows.
    if (QGuiApplication::layoutDirection() == Qt::RightToLeft
        && (QWindowsIntegration::instance()->options() & QWindowsIntegration::RtlEnabled) != 0) {
   
        exStyle |= WS_EX_LAYOUTRTL | WS_EX_NOINHERITLAYOUT;
    }

    // Parent: Use transient parent for top levels.
    if (popup) {
   
        flags |= Qt::WindowStaysOnTopHint; // a popup stays on top, no parent.
    } else if (!embedded) {
   
        if (const QWindow *parentWindow = topLevel ? w->transientParent() : w->parent())
            parentHandle = QWindowsWindow::handleOf(parentWindow);
    }

    if (popup || (type == Qt::ToolTip) || (type == Qt::SplashScreen)) {
   
        style = WS_POPUP;
    } else if (topLevel) {
   
        if (flags & Qt::FramelessWindowHint)
            style = WS_POPUP;                // no border
        else if (flags & Qt::WindowTitleHint)
            style = WS_OVERLAPPED;
        else
            style = 0;
    } else {
   
        style = WS_CHILD;
    }

    // if (!testAttribute(Qt::WA_PaintUnclipped))
    // ### Commented out for now as it causes some problems, but
    // this should be correct anyway, so dig some more into this
#ifdef Q_FLATTEN_EXPOSE
    if (windowIsOpenGL(w)) // a bit incorrect since the is-opengl status may change from false to true at any time later on
        style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // see SetPixelFormat
#else
    style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN ;
#endif
    if (topLevel) {
   
        if ((type == Qt::Window || dialog || tool)) {
   
            if (!(flags & Qt::FramelessWindowHint)) {
   
                style |= WS_POPUP;
                if (flags & Qt::MSWindowsFixedSizeDialogHint) {
   
                    style |= WS_DLGFRAME;
                } else {
   
                    style |= WS_THICKFRAME;
                }
                if (flags & Qt::WindowTitleHint)
                    style |= WS_CAPTION; // Contains WS_DLGFRAME
            }
            if (flags & Qt::WindowSystemMenuHint)
                style |= WS_SYSMENU;
            else if (dialog && (flags & Qt::WindowCloseButtonHint) && !(flags & Qt::FramelessWindowHint)) {
   
                style |= WS_SYSMENU | WS_BORDER; // QTBUG-2027, dialogs without system menu.
                exStyle |= WS_EX_DLGMODALFRAME;
            }
            const bool showMinimizeButton = flags & Qt::WindowMinimizeButtonHint;
            if (showMinimizeButton)
                style |= WS_MINIMIZEBOX;
            const bool showMaximizeButton = shouldShowMaximizeButton(w, flags);
            if (showMaximizeButton)
                style |= WS_MAXIMIZEBOX;
            if (showMinimizeButton || showMaximizeButton)
                style |= WS_SYSMENU;
            if (tool)
                exStyle |= WS_EX_TOOLWINDOW;
            if ((flags & Qt::WindowContextHelpButtonHint) && !showMinimizeButton
                && !showMaximizeButton)
                exStyle |= WS_EX_CONTEXTHELP;
        } else {
   
             exStyle |= WS_EX_TOOLWINDOW;
        }

        // make mouse events fall through this window
        // 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;
    }
}



// Returns topmost QWindowsWindow ancestor even if there are embedded windows in the chain.
// Returns this window if it is the topmost ancestor.
QWindow *QWindowsWindow::topLevelOf(QWindow *w)
{
   
    while (QWindow *parent = w->parent())
        w = parent;

    if (const QPlatformWindow *handle = w->handle()) {
   
        const auto *ww = static_cast<const QWindowsWindow *>(handle);
        if (ww->isEmbedded()) {
   
            HWND parentHWND = GetAncestor(ww->handle(), GA_PARENT);
            const HWND desktopHwnd = GetDesktopWindow();
            const QWindowsContext *ctx = QWindowsContext::instance();
            while (parentHWND && parentHWND != desktopHwnd) {
   
                if (QWindowsWindow *ancestor = ctx->findPlatformWindow(parentHWND))
                    return topLevelOf(ancestor->window());
                parentHWND = GetAncestor(parentHWND, GA_PARENT);
            }
        }
    }
    return w;
}

C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\WinUser.h

WINUSERAPI
HWND
WINAPI
GetParent(
    _In_ HWND hWnd);

WINUSERAPI
HWND
WINAPI
SetParent(
    _In_ HWND hWndChild,
    _In_opt_ HWND hWndNewParent);



WINUSERAPI
BOOL
WINAPI
GetWindowPlacement(
    _In_ HWND hWnd,
    _Inout_ WINDOWPLACEMENT *lpwndpl);

WINUSERAPI
BOOL
WINAPI
SetWindowPlacement(
    _In_ HWND hWnd,
    _In_ CONST WINDOWPLACEMENT *lpwndpl);



WINUSERAPI
BOOL
WINAPI
DestroyWindow(
    _In_ HWND hWnd);

WINUSERAPI
BOOL
WINAPI
ShowWindow(
    _In_ HWND hWnd,
    _In_ int nCmdShow);


/* Types use for passing & returning polymorphic values */
typedef UINT_PTR            WPARAM;
typedef LONG_PTR            LPARAM;
typedef LONG_PTR            LRESULT;

7 QDebug运算符<<重载


#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug d, const RECT &r)
{
   
    QDebugStateSaver saver(d);
    d.nospace();
    d << "RECT(left=" << r.left << ", top=" << r.top
        << ", right=" << r.right << ", bottom=" << r.bottom
        << " (" << r.right - r.left << 'x' << r.bottom - r.top << "))";
    return d;
}

8 vscode的windows的变量提示很有意思


void WindowCreationData::applyWindowFlags(HWND hwnd) const
{
   
    // Keep enabled and visible from the current style.
    const LONG_PTR oldStyle = GetWindowLongPtr(hwnd, GWL_STYLE);
    const LONG_PTR oldExStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE);

    const LONG_PTR newStyle = style | (oldStyle & (WS_DISABLED|WS_VISIBLE));
    if (oldStyle != newStyle)
        SetWindowLongPtr(hwnd, GWL_STYLE, newStyle);
    const LONG_PTR newExStyle = exStyle;
    if (newExStyle != oldExStyle)
        SetWindowLongPtr(hwnd, GWL_EXSTYLE, newExStyle);
    qCDebug(lcQpaWindow).nospace() << __FUNCTION__ << hwnd << *this
        << "\n    Style from " << debugWinStyle(DWORD(oldStyle)) << "\n    to "
        << debugWinStyle(DWORD(newStyle)) << "\n    ExStyle from "
        << debugWinExStyle(DWORD(oldExStyle)) << " to "
        << debugWinExStyle(DWORD(newExStyle));
}

9 windows常用类型名

C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\minwindef.h

/****************************************************************************
*                                                                           *
* minwindef.h -- Basic Windows Type Definitions for minwin partition        *
*                                                                           *
* Copyright (c) Microsoft Corporation. All rights reserved.                 *
*                                                                           *
****************************************************************************/


#ifndef _MINWINDEF_
#define _MINWINDEF_
#pragma once

#include <specstrings.h>

#include <winapifamily.h>

#pragma region Application Family or OneCore Family or Games Family
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES)

#ifndef NO_STRICT
#ifndef STRICT
#define STRICT 1
#endif
#endif /* NO_STRICT */

// Win32 defines _WIN32 automatically,
// but Macintosh doesn't, so if we are using
// Win32 Functions, we must do it here

#ifdef _MAC
#ifndef _WIN32
#define _WIN32
#endif
#endif //_MAC

#ifndef WIN32
#define WIN32
#endif

#ifdef __cplusplus
extern "C" {
   
#endif

/*
 * BASETYPES is defined in ntdef.h if these types are already defined
 */

#ifndef BASETYPES
#define BASETYPES
typedef unsigned long ULONG;
typedef ULONG *PULONG;
typedef unsigned short USHORT;
typedef USHORT *PUSHORT;
typedef unsigned char UCHAR;
typedef UCHAR *PUCHAR;
typedef _Null_terminated_ char *PSZ;
#endif  /* !BASETYPES */

#define MAX_PATH          260

#ifndef NULL
#ifdef __cplusplus
#define NULL    0
#else
#define NULL    ((void *)0)
#endif
#endif

#ifndef FALSE
#define FALSE               0
#endif

#ifndef TRUE
#define TRUE                1
#endif

#ifndef IN
#define IN
#endif

#ifndef OUT
#define OUT
#endif

#ifndef OPTIONAL
#define OPTIONAL
#endif

#undef far
#undef near
#undef pascal

#define far
#define near

#if (!defined(_MAC)) && ((_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED))
#define pascal __stdcall
#else
#define pascal
#endif

#if defined(DOSWIN32) || defined(_MAC)
#define cdecl _cdecl
#ifndef CDECL
#define CDECL _cdecl
#endif
#else
#define cdecl
#ifndef CDECL
#define CDECL
#endif
#endif

#ifdef _MAC
#define CALLBACK    PASCAL
#define WINAPI      CDECL
#define WINAPIV     CDECL
#define APIENTRY    WINAPI
#define APIPRIVATE  CDECL
#ifdef _68K_
#define PASCAL      __pascal
#else
#define PASCAL
#endif
#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK    __stdcall
#define WINAPI      __stdcall
#define WINAPIV     __cdecl
#define APIENTRY    WINAPI
#define APIPRIVATE  __stdcall
#define PASCAL      __stdcall
#else
#define CALLBACK
#define WINAPI
#define WINAPIV
#define APIENTRY    WINAPI
#define APIPRIVATE
#define PASCAL      pascal
#endif

#ifndef _M_CEE_PURE
#ifndef WINAPI_INLINE
#define WINAPI_INLINE  WINAPI
#endif
#endif

#undef FAR
#undef  NEAR
#define FAR                 far
#define NEAR                near
#ifndef CONST
#define CONST               const
#endif

typedef unsigned long       DWORD;
typedef int                 BOOL;
typedef unsigned char       BYTE;
typedef unsigned short      WORD;
typedef float               FLOAT;
typedef FLOAT               *PFLOAT;
typedef BOOL near           *PBOOL;
typedef BOOL far            *LPBOOL;
typedef BYTE near           *PBYTE;
typedef BYTE far            *LPBYTE;
typedef int near            *PINT;
typedef int far             *LPINT;
typedef WORD near           *PWORD;
typedef WORD far            *LPWORD;
typedef long far            *LPLONG;
typedef DWORD near          *PDWORD;
typedef DWORD far           *LPDWORD;
typedef void far            *LPVOID;
typedef CONST void far      *LPCVOID;

typedef int                 INT;
typedef unsigned int        UINT;
typedef unsigned int        *PUINT;


#ifndef NT_INCLUDED
#include <winnt.h>
#endif /* NT_INCLUDED */

/* Types use for passing & returning polymorphic values */
typedef UINT_PTR            WPARAM;
typedef LONG_PTR            LPARAM;
typedef LONG_PTR            LRESULT;

#ifndef NOMINMAX

#ifndef max
#define max(a,b)            (((a) > (b)) ? (a) : (b))
#endif

#ifndef min
#define min(a,b)            (((a) < (b)) ? (a) : (b))
#endif

#endif  /* NOMINMAX */

#define MAKEWORD(a, b)      ((WORD)(((BYTE)(((DWORD_PTR)(a)) & 0xff)) | ((WORD)((BYTE)(((DWORD_PTR)(b)) & 0xff))) << 8))
#define MAKELONG(a, b)      ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
#define LOWORD(l)           ((WORD)(((DWORD_PTR)(l)) & 0xffff))
#define HIWORD(l)           ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff))
#define LOBYTE(w)           ((BYTE)(((DWORD_PTR)(w)) & 0xff))
#define HIBYTE(w)           ((BYTE)((((DWORD_PTR)(w)) >> 8) & 0xff))

typedef HANDLE NEAR         *SPHANDLE;
typedef HANDLE FAR          *LPHANDLE;
typedef HANDLE              HGLOBAL;
typedef HANDLE              HLOCAL;
typedef HANDLE              GLOBALHANDLE;
typedef HANDLE              LOCALHANDLE;

#ifndef _MANAGED
#if _MSC_VER >= 1200
#pragma warning(push)
#pragma warning(disable:4255) // () treated as (void)
#endif
#ifndef _MAC
#ifdef _WIN64
typedef INT_PTR (FAR WINAPI *FARPROC)();
typedef INT_PTR (NEAR WINAPI *NEARPROC)();
typedef INT_PTR (WINAPI *PROC)();
#else
typedef int (FAR WINAPI *FARPROC)();
typedef int (NEAR WINAPI *NEARPROC)();
typedef int (WINAPI *PROC)();
#endif  // _WIN64
#else
typedef int (CALLBACK *FARPROC)();
typedef int (CALLBACK *NEARPROC)();
typedef int (CALLBACK *PROC)();
#endif
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif
#else
typedef INT_PTR (WINAPI *FARPROC)(void);
typedef INT_PTR (WINAPI *NEARPROC)(void);
typedef INT_PTR (WINAPI *PROC)(void);
#endif

typedef WORD                ATOM;   //BUGBUG - might want to remove this from minwin

DECLARE_HANDLE(HKEY);
typedef HKEY *PHKEY;
DECLARE_HANDLE(HMETAFILE);
DECLARE_HANDLE(HINSTANCE);
typedef HINSTANCE HMODULE;      /* HMODULEs can be used in place of HINSTANCEs */
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HSPRITE);
DECLARE_HANDLE(HLSURF);
DECLARE_HANDLE(HSTR);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HKL);

#ifndef _MAC
typedef int HFILE;
#else
typedef short HFILE;
#endif

//
//  File System time stamps are represented with the following structure:
//

typedef struct _FILETIME {
   
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;
#define _FILETIME_

#ifdef __cplusplus
}
#endif

#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion

#endif // _MINWINDEF_
//C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\shared\minwindef.h
typedef WORD                ATOM;   //BUGBUG - might want to remove this from minwin

DECLARE_HANDLE(HKEY);
typedef HKEY *PHKEY;
DECLARE_HANDLE(HMETAFILE);
DECLARE_HANDLE(HINSTANCE);
typedef HINSTANCE HMODULE;      /* HMODULEs can be used in place of HINSTANCEs */
DECLARE_HANDLE(HRGN);
DECLARE_HANDLE(HRSRC);
DECLARE_HANDLE(HSPRITE);
DECLARE_HANDLE(HLSURF);
DECLARE_HANDLE(HSTR);
DECLARE_HANDLE(HTASK);
DECLARE_HANDLE(HWINSTA);
DECLARE_HANDLE(HKL);



//C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\um\winnt.h

//
// Handle to an Object
//

#ifdef STRICT
typedef void *HANDLE;
#if 0 && (_MSC_VER > 1000)
#define DECLARE_HANDLE(name) struct name##__; typedef struct name##__ *name
#else
#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
#endif
#else
typedef PVOID HANDLE;
#define DECLARE_HANDLE(name) typedef HANDLE name
#endif
typedef HANDLE *PHANDLE;

10 拿到所有窗体的方法QGuiApplication::allWindows()


void QWindowsWindow::handleWindowStateChange(Qt::WindowStates state)
{
   
    qCDebug(lcQpaWindow) << __FUNCTION__ << this << window()
                 << "\n    from " << m_windowState << " to " << state;
    m_windowState = state;
    QWindowSystemInterface::handleWindowStateChanged(window(), state);
    if (state & Qt::WindowMinimized) {
   
        handleHidden();
        QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); // Tell QQuickWindow to stop rendering now.
    } else {
   
        // QTBUG-17548: We send expose events when receiving WM_Paint, but for
        // layered windows and transient children, we won't receive any WM_Paint.
        QWindow *w = window();
        bool exposeEventsSent = false;
        if (isLayered()) {
   
            fireFullExpose();
            exposeEventsSent = true;
        }
        const QWindowList allWindows = QGuiApplication::allWindows();
        for (QWindow *child : allWindows) {
   
            if (child != w && child->isVisible() && child->transientParent() == w) {
   
                QWindowsWindow *platformWindow = QWindowsWindow::windowsWindowOf(child);
                if (platformWindow && platformWindow->isLayered()) {
   
                    platformWindow->fireFullExpose();
                    exposeEventsSent = true;
                }
            }
        }
        if (exposeEventsSent && !QWindowsContext::instance()->asyncExpose())
            QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
    }
}





/*!
    \brief Change the window state.

    \note Window frames change when maximized;
    the top margin shrinks somewhat but that cannot be obtained using
    AdjustWindowRectEx().

    \note Some calls to SetWindowLong require a subsequent call
    to ShowWindow.
*/

void QWindowsWindow::setWindowState_sys(Qt::WindowStates newState)
{
   
    const Qt::WindowStates oldState = m_windowState;
    if (oldState == newState)
        return;
    qCDebug(lcQpaWindow) << '>' << __FUNCTION__ << this << window()
        << " from " << oldState << " to " << newState;

    const bool visible = isVisible();
    auto stateChange = oldState ^ newState;

    if (stateChange & Qt::WindowFullScreen) {
   
        if (newState & Qt::WindowFullScreen) {
   
#ifndef Q_FLATTEN_EXPOSE
            UINT newStyle = WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_POPUP;
#else
            UINT newStyle = WS_POPUP;
#endif
            // Save geometry and style to be restored when fullscreen
            // is turned off again, since on Windows, it is not a real
            // Window state but emulated by changing geometry and style.
            if (!m_savedStyle) {
   
                m_savedStyle = style();
                if ((oldState & Qt::WindowMinimized) || (oldState & Qt::WindowMaximized)) {
   
                    const QRect nf = normalFrameGeometry(m_data.hwnd);
                    if (nf.isValid())
                        m_savedFrameGeometry = nf;
                } else {
   
                    m_savedFrameGeometry = frameGeometry_sys();
                }
            }
            if (newState & Qt::WindowMaximized)
                setFlag(MaximizeToFullScreen);
            if (m_savedStyle & WS_SYSMENU)
                newStyle |= WS_SYSMENU;
            if (visible)
                newStyle |= WS_VISIBLE;
            if (testFlag(HasBorderInFullScreen))
                newStyle |= WS_BORDER;
            setStyle(newStyle);
            // Use geometry of QWindow::screen() within creation or the virtual screen the
            // window is in (QTBUG-31166, QTBUG-30724).
            const QScreen *screen = window()->screen();
            if (!screen)
                screen = QGuiApplication::primaryScreen();
            const QRect r = screen ? QHighDpi::toNativePixels(screen->geometry(), window()) : m_savedFrameGeometry;

            if (newState & Qt::WindowMinimized) {
   
                setMinimizedGeometry(m_data.hwnd, r);
                if (stateChange & Qt::WindowMaximized)
                    setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
            } else {
   
                const UINT swpf = SWP_FRAMECHANGED | SWP_NOACTIVATE;
                const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
                setFlag(SynchronousGeometryChangeEvent);
                SetWindowPos(m_data.hwnd, HWND_TOP, r.left(), r.top(), r.width(), r.height(), swpf);
                if (!wasSync)
                    clearFlag(SynchronousGeometryChangeEvent);
                clearFlag(MaximizeToFullScreen);
                QWindowSystemInterface::handleGeometryChange(window(), r);
                QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
            }
        } else {
   
            // Restore saved state.
            unsigned newStyle = m_savedStyle ? m_savedStyle : style();
            if (visible)
                newStyle |= WS_VISIBLE;
            setStyle(newStyle);

            const QScreen *screen = window()->screen();
            if (!screen)
                screen = QGuiApplication::primaryScreen();
            // That area of the virtual desktop might not be covered by a screen anymore.
            if (const auto platformScreen = screen->handle()) {
   
                if (!platformScreen->geometry().intersects(m_savedFrameGeometry))
                    m_savedFrameGeometry.moveTo(platformScreen->geometry().topLeft());
            }

            if (newState & Qt::WindowMinimized) {
   
                setMinimizedGeometry(m_data.hwnd, m_savedFrameGeometry);
                if (stateChange & Qt::WindowMaximized)
                    setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
            } else {
   
                UINT swpf = SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOACTIVATE;
                if (!m_savedFrameGeometry.isValid())
                    swpf |= SWP_NOSIZE | SWP_NOMOVE;
                const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
                setFlag(SynchronousGeometryChangeEvent);
                // After maximized/fullscreen; the window can be in a maximized state. Clear
                // it before applying the normal geometry.
                if (windowVisibility_sys(m_data.hwnd) == QWindow::Maximized)
                    ShowWindow(m_data.hwnd, SW_SHOWNOACTIVATE);
                SetWindowPos(m_data.hwnd, nullptr, m_savedFrameGeometry.x(), m_savedFrameGeometry.y(),
                             m_savedFrameGeometry.width(), m_savedFrameGeometry.height(), swpf);
                if (!wasSync)
                    clearFlag(SynchronousGeometryChangeEvent);
                // preserve maximized state
                if (visible) {
   
                    setFlag(WithinMaximize);
                    ShowWindow(m_data.hwnd,
                               (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNA);
                    clearFlag(WithinMaximize);
                }
            }
            m_savedStyle = 0;
            m_savedFrameGeometry = QRect();
        }
    } else if ((oldState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
   
        if (visible && !(newState & Qt::WindowMinimized)) {
   
            setFlag(WithinMaximize);
            if (newState & Qt::WindowFullScreen)
                setFlag(MaximizeToFullScreen);
            ShowWindow(m_data.hwnd,
                       (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
            clearFlag(WithinMaximize);
            clearFlag(MaximizeToFullScreen);
        } else if (visible && (oldState & newState & Qt::WindowMinimized)) {
   
            // change of the maximized state while keeping minimized
            setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
        }
    }

    if (stateChange & Qt::WindowMinimized) {
   
        if (visible) {
   
            ShowWindow(m_data.hwnd,
                       (newState & Qt::WindowMinimized) ? SW_MINIMIZE :
                       (newState & Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNORMAL);
            if ((newState & Qt::WindowMinimized) && (stateChange & Qt::WindowMaximized))
                setRestoreMaximizedFlag(m_data.hwnd, newState & Qt::WindowMaximized);
        }
    }
    qCDebug(lcQpaWindow) << '<' << __FUNCTION__ << this << window() << newState;
}

11 QSharedPointer智能指针使用

using QWindowCreationContextPtr = QSharedPointer<QWindowCreationContext>;

static QPoint calcPosition(const QWindow *w, const QWindowCreationContextPtr &context, const QMargins &invMargins)

 const QWindowCreationContextPtr context(new QWindowCreationContext(w, screen, data.geometry,
                                                                       rect, data.customMargins,
                                                                       style, exStyle));


// Clear the creation context as the window can be found in QWindowsContext's map.
    QWindowCreationContextPtr creationContext =
        QWindowsContext::instance()->setWindowCreationContext(QWindowCreationContextPtr());
相关文章
|
11天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
8天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2522 18
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
8天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1525 15
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
4天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
10天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
590 14
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19283 30
|
10天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
491 49
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18842 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17530 13
Apache Paimon V0.9最新进展
|
2天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
367 4
叮咚!您有一份六大必做安全操作清单,请查收