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());
相关文章
|
25天前
|
编解码 开发工具 UED
QT Widgets模块源码解析与实践
【9月更文挑战第20天】Qt Widgets 模块是 Qt 开发中至关重要的部分,提供了丰富的 GUI 组件,如按钮、文本框等,并支持布局管理、事件处理和窗口管理。这些组件基于信号与槽机制,实现灵活交互。通过对源码的解析及实践应用,可深入了解其类结构、布局管理和事件处理机制,掌握创建复杂 UI 界面的方法,提升开发效率和用户体验。
112 12
|
19天前
|
存储 Java C++
QT源码拾贝0-5(qimage和qpainter)
这篇文章介绍了在Qt源码中qimage和qpainter的使用,包括线程池的使用、智能指针的存储、std::exchange函数的应用、获取类对象的方法以及QChar字节操作。
QT源码拾贝0-5(qimage和qpainter)
|
2月前
|
存储 C++
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
【C++】C++ 基于QT实现散列表学生管理系统(源码+数据+课程论文)【独一无二】
|
2月前
|
存储 算法 C++
【C++】C++ QT实现Huffman编码器与解码器(源码+课程论文+文件)【独一无二】
【C++】C++ QT实现Huffman编码器与解码器(源码+课程论文+文件)【独一无二】
|
2月前
从源码角度分析Qt元对象系统2
从源码角度分析Qt元对象系统
48 0
|
2月前
|
存储
从源码角度分析Qt元对象系统1
从源码角度分析Qt元对象系统
67 0
|
2月前
|
存储 C++
【C++】C++ QT实现 学生信息管理系统(QT源码)【独一无二】
【C++】C++ QT实现 学生信息管理系统(QT源码)【独一无二】
|
3月前
|
JSON 自然语言处理 网络协议
基于QT实现的词典(附源码)
主要用到的技术:JSON字符串,堆栈窗体(方便以后加新功能),QTcpSocket,LcdNumber,时间戳的转换。 通信用的是TCP通信,将TCP封在了一个头文件中,哪个文件想去通过TCP链接发送消息就可以使用头文件 QT端写的是客户端,服务器还是在我笔记上次的Linux系统下写的服务器,做了一些小修改
|
5月前
|
人工智能 Ubuntu Shell
【Ubuntu工具】安装教程:Ubuntu系统上源码编译安装QT5.15.13(有坑)
【Ubuntu工具】安装教程:Ubuntu系统上源码编译安装QT5.15.13(有坑)
452 0
|
3月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
159 1
Qt(C++)开发一款图片防盗用水印制作小工具