Qt之Gui

组件依赖关系

在这里插入图片描述

应用

QGuiApplication
QApplication
QCoreApplication

QApplication:widget对应的应用
QGuiApplication :gui对应的应用
QCoreApplication :无gui对应的应用

widget

QWidget
QMainWindow
QWidgetWindow
QWindow
QPlatformIntegration
QPlatformWindow

QPlatformIntegration:平台抽象
QPlatformWindow :平台 抽象窗口

windows平台

QPlatformIntegration
QWindowsIntegration
QPlatformWindow
QWindowsBaseWindow
QWindowsWindow
QWindowsDesktopWindow
QWindowsForeignWindow
QWindowsContext

在QWindowsIntegration创建createPlatformWindow时,其先创建QWindowsWindowData::create

QWindowsWindowData
    WindowCreationData::create(const QWindow *w, const WindowData &data, QString title) const
{
    WindowData result;
    result.flags = flags;

    const auto appinst = reinterpret_cast<HINSTANCE>(GetModuleHandle(nullptr));

    const QString windowClassName = QWindowsContext::instance()->registerWindowClass(w);

    const QScreen *screen{};
    const QRect rect = QPlatformWindow::initialGeometry(w, data.geometry,
                                                        defaultWindowWidth, defaultWindowHeight,
                                                        &screen);

    if (title.isEmpty() && (result.flags & Qt::WindowTitleHint))
        title = topLevel ? qAppName() : w->objectName();

    const auto *titleUtf16 = reinterpret_cast<const wchar_t *>(title.utf16());
    const auto *classNameUtf16 = reinterpret_cast<const wchar_t *>(windowClassName.utf16());

    // Capture events before CreateWindowEx() returns. The context is cleared in
    // the QWindowsWindow constructor.
    const QWindowCreationContextPtr context(new QWindowCreationContext(w, screen, data.geometry,
                                                                       rect, data.customMargins,
                                                                       style, exStyle));
    QWindowsContext::instance()->setWindowCreationContext(context);

    const bool hasFrame = (style & (WS_DLGFRAME | WS_THICKFRAME));
    QMargins invMargins = topLevel && hasFrame && QWindowsGeometryHint::positionIncludesFrame(w)
            ? invisibleMargins(QPoint(context->frameX, context->frameY)) : QMargins();

    qCDebug(lcQpaWindows).nospace()
        << "CreateWindowEx: " << w << " class=" << windowClassName << " title=" << title
        << '\n' << *this << "\nrequested: " << rect << ": "
        << context->frameWidth << 'x' <<  context->frameHeight
        << '+' << context->frameX << '+' << context->frameY
        << " custom margins: " << context->customMargins
        << " invisible margins: " << invMargins;


    QPoint pos = calcPosition(w, context, invMargins);

    // Mirror the position when creating on a parent in RTL mode, ditto for the obtained geometry.
    int mirrorParentWidth = 0;
    if (!w->isTopLevel() && QWindowsBaseWindow::isRtlLayout(parentHandle)) {
        RECT rect;
        GetClientRect(parentHandle, &rect);
        mirrorParentWidth = rect.right;
    }
    if (mirrorParentWidth != 0 && pos.x() != CW_USEDEFAULT && context->frameWidth != CW_USEDEFAULT)
        pos.setX(mirrorParentWidth - context->frameWidth - pos.x());

    result.hwnd = CreateWindowEx(exStyle, classNameUtf16, titleUtf16,
                                 style,
                                 pos.x(), pos.y(),
                                 context->frameWidth, context->frameHeight,
                                 parentHandle, nullptr, appinst, nullptr);
    qCDebug(lcQpaWindows).nospace()
        << "CreateWindowEx: returns " << w << ' ' << result.hwnd << " obtained geometry: "
        << context->obtainedPos << context->obtainedSize << ' ' << context->margins;

    if (!result.hwnd) {
        qErrnoWarning("%s: CreateWindowEx failed", __FUNCTION__);
        return result;
    }

    if (mirrorParentWidth != 0) {
        context->obtainedPos.setX(mirrorParentWidth - context->obtainedSize.width()
                                  -  context->obtainedPos.x());
    }

    QRect obtainedGeometry(context->obtainedPos, context->obtainedSize);

    result.geometry = obtainedGeometry;
    result.fullFrameMargins = context->margins;
    result.embedded = embedded;
    result.hasFrame = hasFrame;
    result.customMargins = context->customMargins;

    return result;
}

内部会先注册registerWindowClass,设置窗口的处理函数registerWindowClass(cname, qWindowsWndProc, style, GetSysColorBrush(COLOR_WINDOW), icon);
qWindowsWndProc处理函数主要是调用 QWindowsContext的windowsProc

QString QWindowsContext::registerWindowClass(QString cname,
                                             WNDPROC proc,
                                             unsigned style,
                                             HBRUSH brush,
                                             bool icon)
{
    // since multiple Qt versions can be used in one process
    // each one has to have window class names with a unique name
    // The first instance gets the unmodified name; if the class
    // has already been registered by another instance of Qt then
    // add a UUID. The check needs to be performed for each name
    // in case new message windows are added (QTBUG-81347).
    const auto appInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
    WNDCLASS wcinfo;
    const bool classExists = GetClassInfo(appInstance, reinterpret_cast<LPCWSTR>(cname.utf16()), &wcinfo) == TRUE
        && wcinfo.lpfnWndProc != proc;

    if (classExists)
        cname += QUuid::createUuid().toString();

    if (d->m_registeredWindowClassNames.contains(cname))        // already registered in our list
        return cname;

    WNDCLASSEX wc;
    wc.cbSize       = sizeof(WNDCLASSEX);
    wc.style        = style;
    wc.lpfnWndProc  = proc;
    wc.cbClsExtra   = 0;
    wc.cbWndExtra   = 0;
    wc.hInstance    = appInstance;
    wc.hCursor      = nullptr;
    wc.hbrBackground = brush;
    if (icon) {
        wc.hIcon = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, 0, 0, LR_DEFAULTSIZE));
        if (wc.hIcon) {
            int sw = GetSystemMetrics(SM_CXSMICON);
            int sh = GetSystemMetrics(SM_CYSMICON);
            wc.hIconSm = static_cast<HICON>(LoadImage(appInstance, L"IDI_ICON1", IMAGE_ICON, sw, sh, 0));
        } else {
            wc.hIcon = static_cast<HICON>(LoadImage(nullptr, IDI_APPLICATION, IMAGE_ICON, 0, 0, LR_DEFAULTSIZE | LR_SHARED));
            wc.hIconSm = nullptr;
        }
    } else {
        wc.hIcon    = nullptr;
        wc.hIconSm  = nullptr;
    }

    wc.lpszMenuName  = nullptr;
    wc.lpszClassName = reinterpret_cast<LPCWSTR>(cname.utf16());
    ATOM atom = RegisterClassEx(&wc);
    if (!atom)
        qErrnoWarning("QApplication::regClass: Registering window class '%s' failed.",
                      qPrintable(cname));

    d->m_registeredWindowClassNames.insert(cname);
    qCDebug(lcQpaWindows).nospace() << __FUNCTION__ << ' ' << cname
        << " style=0x" << Qt::hex << style << Qt::dec
        << " brush=" << brush << " icon=" << icon << " atom=" << atom;
    return cname;
}
  • 8
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值