上一篇博客:
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());