QWindowsWindow::QWindowsWindow(QWindow *aWindow, const WindowData &data) : QPlatformWindow(aWindow), m_data(data), m_flags(0), m_hdc(0), m_windowState(aWindow->windowState()), m_opacity(1.0), m_mouseGrab(false), m_cursor(QWindowsScreen::screenOf(aWindow)->cursor().standardWindowCursor()), m_dropTarget(0) { if (aWindow->surfaceType() == QWindow::OpenGLSurface) setFlag(OpenGLSurface); QWindowsContext::instance()->addWindow(m_data.hwnd, this); if (aWindow->isTopLevel()) { switch (aWindow->windowType()) { case Qt::Window: case Qt::Dialog: case Qt::Sheet: case Qt::Drawer: case Qt::Popup: case Qt::Tool: registerDropSite(); break; default: break; } } }
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow) { Q_Q(QWidget); static int sw = -1, sh = -1; Qt::WindowType type = q->windowType(); Qt::WindowFlags flags = data.window_flags; bool topLevel = (flags & Qt::Window); bool popup = (type == Qt::Popup); bool dialog = (type == Qt::Dialog || type == Qt::Sheet || (flags & Qt::MSWindowsFixedSizeDialogHint)); bool desktop = (type == Qt::Desktop); bool tool = (type == Qt::Tool || type == Qt::Drawer); HINSTANCE appinst = qWinAppInst(); HWND parentw, destroyw = 0; WId id; QString windowClassName = qt_reg_winclass(q); if (!window) // always initialize initializeWindow = true; if (popup) flags |= Qt::WindowStaysOnTopHint; // a popup stays on top if (flags & (Qt::WindowSystemMenuHint | Qt::WindowMinMaxButtonsHint | Qt::WindowContextHelpButtonHint)) { flags |= Qt::WindowSystemMenuHint; flags |= Qt::WindowTitleHint; flags &= ~Qt::FramelessWindowHint; } if (sw < 0) { // get the (primary) screen size sw = GetSystemMetrics(SM_CXSCREEN); sh = GetSystemMetrics(SM_CYSCREEN); } if (desktop) { // desktop widget popup = false; // force this flags off data.crect.setRect(0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN)); } parentw = q->parentWidget() ? q->parentWidget()->effectiveWinId() : 0; QString title; int style = WS_CHILD; int exsty = WS_EX_NOPARENTNOTIFY; if (topLevel) { if (!(flags & Qt::FramelessWindowHint) && !tool && !q->testAttribute(Qt::WA_DontShowOnScreen)) style = (WS_OVERLAPPED) | WS_SYSMENU; else style = WS_POPUP; if ((type == Qt::ToolTip) || (type == Qt::SplashScreen)) { style = WS_POPUP; exsty |= WS_EX_NOANIMATION; } else { if (flags & Qt::WindowTitleHint) style |= WS_CAPTION; if (flags & Qt::WindowSystemMenuHint) style |= WS_SYSMENU; if (flags & Qt::WindowContextHelpButtonHint) exsty |= WS_EX_CONTEXTHELP; #ifndef Q_WS_WINCE_WM if (flags & Qt::WindowMinimizeButtonHint) style |= WS_MINIMIZEBOX; if (shouldShowMaximizeButton()) style |= WS_MAXIMIZEBOX; #endif if (tool) exsty |= WS_EX_TOOLWINDOW; } } if (dialog) { style = WS_BORDER | WS_CAPTION; if (flags & Qt::WindowOkButtonHint) exsty |= WS_EX_CAPTIONOKBTN; if (flags & Qt::WindowCancelButtonHint || flags & Qt::WA_DeleteOnClose) style |= WS_SYSMENU; if (flags & Qt::WindowContextHelpButtonHint) exsty |= WS_EX_CONTEXTHELP; } if (popup) { style = WS_POPUP; exsty |= WS_EX_NOANIMATION; } if (flags & Qt::WindowTitleHint) { title = q->isWindow() ? qAppName() : q->objectName(); } // The Qt::WA_WState_Created flag is checked by translateConfigEvent() in // qapplication_win.cpp. We switch it off temporarily to avoid move // and resize events during creationt q->setAttribute(Qt::WA_WState_Created, false); if (window) { // override the old window if (destroyOldWindow) destroyw = data.winid; id = window; setWinId(window); LONG res = SetWindowLong(window, GWL_STYLE, style); if (!res) qErrnoWarning("QWidget::create: Failed to set window style"); res = SetWindowLong( window, GWL_WNDPROC, (LONG)QtWndProc ); if (!res) qErrnoWarning("QWidget::create: Failed to set window procedure"); } else if (desktop) { // desktop widget id = GetDesktopWindow(); if (!id) { //Create a dummy desktop RECT r; SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0); id = CreateWindow(reinterpret_cast<const wchar_t *>(windowClassName.utf16()), reinterpret_cast<const wchar_t *>(title.utf16()), style, r.left, r.top, r.right - r.left, r.bottom - r.top, 0, 0, appinst, 0); } setWinId(id); } else if (topLevel) { // create top-level widget const bool wasMoved = q->testAttribute(Qt::WA_Moved); int x, y; if (qt_wince_is_mobile()) { x = wasMoved ? data.crect.left() : CW_USEDEFAULT; y = wasMoved ? data.crect.top() : CW_USEDEFAULT; } else { x = wasMoved ? data.crect.left() : 100; y = wasMoved ? data.crect.top() : 100; } int w = CW_USEDEFAULT; int h = CW_USEDEFAULT; // Adjust for framestrut when needed RECT rect = {0,0,0,0}; if (AdjustWindowRectEx(&rect, style, FALSE, exsty)) { QTLWExtra *td = maybeTopData(); if (wasMoved && (td && !td->posFromMove)) { x = data.crect.x() + rect.left; y = data.crect.y() + rect.top; } if (q->testAttribute(Qt::WA_Resized)) { w = data.crect.width() + (rect.right - rect.left); h = data.crect.height() + (rect.bottom - rect.top); } } id = CreateWindowEx(exsty, reinterpret_cast<const wchar_t *>(windowClassName.utf16()), reinterpret_cast<const wchar_t *>(title.utf16()), style, x, y, w, h, 0, 0, appinst, 0); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); setWinId(id); if ((flags & Qt::WindowStaysOnTopHint) || (type == Qt::ToolTip)) SetWindowPos(id, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create child widget id = CreateWindowEx(exsty, (wchar_t*)windowClassName.utf16(), (wchar_t*)title.utf16(), style, data.crect.left(), data.crect.top(), data.crect.width(), data.crect.height(), parentw, NULL, appinst, NULL); if (!id) qErrnoWarning("QWidget::create: Failed to create window"); SetWindowPos(id, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); setWinId(id); } if (desktop) { q->setAttribute(Qt::WA_WState_Visible); } else if (topLevel && !q->testAttribute(Qt::WA_DontShowOnScreen)) { RECT cr; GetClientRect(id, &cr); // one cannot trust cr.left and cr.top, use a correction POINT instead POINT pt; pt.x = 0; pt.y = 0; if (!q->testAttribute(Qt::WA_DontShowOnScreen) || q->testAttribute(Qt::WA_Moved)) ClientToScreen(id, &pt); data.crect = QRect(QPoint(pt.x, pt.y), QPoint(pt.x + cr.right - 1, pt.y + cr.bottom - 1)); if (data.fstrut_dirty) { // be nice to activeqt updateFrameStrut(); } } q->setAttribute(Qt::WA_WState_Created); // accept move/resize events hd = 0; // no display context if (window) { // got window from outside if (IsWindowVisible(window)) q->setAttribute(Qt::WA_WState_Visible); else q->setAttribute(Qt::WA_WState_Visible, false); } if (extra && !extra->mask.isEmpty()) setMask_sys(extra->mask); #if defined(QT_NON_COMMERCIAL) QT_NC_WIDGET_CREATE #endif if (q->hasFocus() && q->testAttribute(Qt::WA_InputMethodEnabled)) q->inputContext()->setFocusWidget(q); if (destroyw) { DestroyWindow(destroyw); } if (q != qt_tablet_widget && QWidgetPrivate::mapper) qt_tablet_init_wce(); if (q->testAttribute(Qt::WA_DropSiteRegistered)) registerDropSite(true); if (maybeTopData() && maybeTopData()->opacity != 255) q->setWindowOpacity(maybeTopData()->opacity/255.); if (!topLevel && q->testAttribute(Qt::WA_NativeWindow) && q->testAttribute(Qt::WA_Mapped)) { Q_ASSERT(q->internalWinId()); ShowWindow(q->internalWinId(), SW_SHOW); } }