商道如狼道 发表于 2024-8-5 12:47:10

Qt之Gui

组件依赖关系

https://i-blog.csdnimg.cn/direct/60984287d7db4cbe9390b9d28d6aa2ea.png
应用

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

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

   在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;
}

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Qt之Gui