void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool destroyOldWindow) { Q_Q(QWidget); Qt::WindowType type = q->windowType(); Qt::WindowFlags &flags = data.window_flags; QWidget *parentWidget = q->parentWidget(); 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); if (popup) flags |= Qt::WindowStaysOnTopHint; // a popup stays on top TRect clientRect = static_cast<CEikAppUi*>(S60->appUi())->ClientRect(); int sw = clientRect.Width(); int sh = clientRect.Height(); if (desktop) { TSize screenSize = S60->screenDevice()->SizeInPixels(); data.crect.setRect(0, 0, screenSize.iWidth, screenSize.iHeight); q->setAttribute(Qt::WA_DontShowOnScreen); } else if (topLevel && !q->testAttribute(Qt::WA_Resized)){ int width = sw; int height = sh; if (extra) { width = qMax(qMin(width, extra->maxw), extra->minw); height = qMax(qMin(height, extra->maxh), extra->minh); } data.crect.setSize(QSize(width, height)); } CCoeControl *const destroyw = destroyOldWindow ? data.winid : 0; createExtra(); if (window) { setWinId(window); TRect tr = window->Rect(); data.crect.setRect(tr.iTl.iX, tr.iTl.iY, tr.Width(), tr.Height()); } else if (topLevel) { if (!q->testAttribute(Qt::WA_Moved) && !q->testAttribute(Qt::WA_DontShowOnScreen)) data.crect.moveTopLeft(QPoint(clientRect.iTl.iX, clientRect.iTl.iY)); QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) ); QT_TRAP_THROWING(control->ConstructL(true, desktop)); control->SetMopParent(static_cast<CEikAppUi*>(S60->appUi())); // Symbian windows are always created in an inactive state // We perform this assignment for the case where the window is being re-created // as a result of a call to setParent_sys, on either this widget or one of its // ancestors. extra->activated = 0; if (!desktop) { TInt stackingFlags; if ((q->windowType() & Qt::Popup) == Qt::Popup) { stackingFlags = ECoeStackFlagRefusesAllKeys | ECoeStackFlagRefusesFocus; } else { stackingFlags = ECoeStackFlagStandard; } control->MakeVisible(false); QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags)); // Avoid keyboard focus to a hidden window. control->setFocusSafely(false); RDrawableWindow *const drawableWindow = control->DrawableWindow(); // Request mouse move events. drawableWindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); drawableWindow->EnableVisibilityChangeEvents(); } q->setAttribute(Qt::WA_WState_Created); int x, y, w, h; data.crect.getRect(&x, &y, &w, &h); control->SetRect(TRect(TPoint(x, y), TSize(w, h))); // We wait until the control is fully constructed before calling setWinId, because // this generates a WinIdChanged event. setWinId(control.take()); if (!desktop) s60UpdateIsOpaque(); // must be called after setWinId() } else if (q->testAttribute(Qt::WA_NativeWindow) || paintOnScreen()) { // create native child widget QScopedPointer<QSymbianControl> control( q_check_ptr(new QSymbianControl(q)) ); QT_TRAP_THROWING(control->ConstructL(!parentWidget)); // Symbian windows are always created in an inactive state // We perform this assignment for the case where the window is being re-created // as a result of a call to setParent_sys, on either this widget or one of its // ancestors. extra->activated = 0; TInt stackingFlags; if ((q->windowType() & Qt::Popup) == Qt::Popup) { stackingFlags = ECoeStackFlagRefusesAllKeys | ECoeStackFlagRefusesFocus; } else { stackingFlags = ECoeStackFlagStandard; } control->MakeVisible(false); QT_TRAP_THROWING(control->ControlEnv()->AppUi()->AddToStackL(control.data(), ECoeStackPriorityDefault, stackingFlags)); // Avoid keyboard focus to a hidden window. control->setFocusSafely(false); q->setAttribute(Qt::WA_WState_Created); int x, y, w, h; data.crect.getRect(&x, &y, &w, &h); control->SetRect(TRect(TPoint(x, y), TSize(w, h))); RDrawableWindow *const drawableWindow = control->DrawableWindow(); // Request mouse move events. drawableWindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); drawableWindow->EnableVisibilityChangeEvents(); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) { activateSymbianWindow(control.data()); control->MakeVisible(true); } // We wait until the control is fully constructed before calling setWinId, because // this generates a WinIdChanged event. setWinId(control.take()); } if (destroyw) { destroyw->ControlEnv()->AppUi()->RemoveFromStack(destroyw); // Delay deletion of the control in case this function is called in the // context of a CONE event handler such as // CCoeControl::ProcessPointerEventL QMetaObject::invokeMethod(q, "_q_delayedDestroy", Qt::QueuedConnection, Q_ARG(WId, destroyw)); } if (q->testAttribute(Qt::WA_AcceptTouchEvents)) registerTouchWindow(); }
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); } }