Ejemplo n.º 1
0
void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyOldWindow)
{
    Q_Q(QWidget);

    Q_UNUSED(window);
    Q_UNUSED(initializeWindow);
    Q_UNUSED(destroyOldWindow);

    Qt::WindowFlags flags = data.window_flags;

    if (!q->testAttribute(Qt::WA_NativeWindow) && !q->isWindow())
        return; // we only care about real toplevels

    QWindow *win = topData()->window;
    // topData() ensures the extra is created but does not ensure 'window' is non-null
    // in case the extra was already valid.
    if (!win) {
        createTLSysExtra();
        win = topData()->window;
    }

    win->setFlags(data.window_flags);
    fixPosIncludesFrame();
    if (q->testAttribute(Qt::WA_Moved))
        win->setGeometry(q->geometry());
    else
        win->resize(q->size());
    win->setScreen(QGuiApplication::screens().value(topData()->screenIndex, 0));

    if (q->testAttribute(Qt::WA_TranslucentBackground)) {
        QSurfaceFormat format;
        format.setAlphaBufferSize(8);
        win->setFormat(format);
    }

    if (QWidget *nativeParent = q->nativeParentWidget()) {
        if (nativeParent->windowHandle()) {
            if (flags & Qt::Window) {
                win->setTransientParent(nativeParent->windowHandle());
                win->setParent(0);
            } else {
                win->setTransientParent(0);
                win->setParent(nativeParent->windowHandle());
            }
        }
    }

    qt_window_private(win)->positionPolicy = topData()->posIncludesFrame ?
        QWindowPrivate::WindowFrameInclusive : QWindowPrivate::WindowFrameExclusive;
    win->create();
    // Enable nonclient-area events for QDockWidget and other NonClientArea-mouse event processing.
    if ((flags & Qt::Desktop) == Qt::Window)
        win->handle()->setFrameStrutEventsEnabled(true);

    data.window_flags = win->flags();

    QBackingStore *store = q->backingStore();

    if (!store) {
        if (win && q->windowType() != Qt::Desktop)
            q->setBackingStore(new QBackingStore(win));
        else
            q->setAttribute(Qt::WA_PaintOnScreen, true);
    }

    setWindowModified_helper();
    setWinId(win->winId());

    // Check children and create windows for them if necessary
    q_createNativeChildrenAndSetParent(q);

    if (extra && !extra->mask.isEmpty())
        setMask_sys(extra->mask);

    // If widget is already shown, set window visible, too
    if (q->isVisible())
        win->setVisible(true);
}
Ejemplo n.º 2
0
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);
    }
}