⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qwindowsxpstyle.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 5 页
字号:
        // Clip away border region        QRegion extraClip = sysRgn;        if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {            if (themeData.noBorder) {                // extraClip &= area is already done                drawRECT = themeData.toRECT(area.adjusted(-borderSize, -borderSize, borderSize, borderSize));            }            // Clip away content region            if (themeData.noContent) {                QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);                extraClip ^= content;            }            // Set the clip region, if used..            if (themeData.noBorder || themeData.noContent)                SelectClipRgn(dc, extraClip.handle());        }        pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawRECT), &(drawOptions.rcClip));    }    SelectClipRgn(dc, 0);}/*! \internal    This function uses a secondary Native doublebuffer for painting parts.    It should only be used when the painteengine doesn't provide a proper    HDC for direct painting (e.g. when doing a grabWidget(), painting to    other pixmaps etc), or when special transformations are needed (e.g.    flips (horizonal mirroring only, vertical are handled by the theme    engine).*/void QWindowsXPStylePrivate::drawBackgroundThruNativeBuffer(XPThemeData &themeData){    QPainter *painter = themeData.painter;    QRect rect = themeData.rect;    if ((themeData.rotate + 90) % 180 == 0) { // Catch 90,270,etc.. degree flips.        rect = QRect(0, 0, rect.height(), rect.width());    }    rect.moveTo(0,0);    int partId = themeData.partId;    int stateId = themeData.stateId;    int w = rect.width();    int h = rect.height();    // Values initialized later, either from cached values, or from function calls    AlphaChannelType alphaType = UnknownAlpha;    bool stateHasData = true; // We assume so;    bool hasAlpha = false;    bool partIsTransparent;    bool inspectData;    bool potentialInvalidAlpha;    QString pixmapCacheKey = QString::fromLatin1("$qt_xp_%1p%2s%3s%4b%5c%6w%7h").arg(themeData.name)                             .arg(partId).arg(stateId).arg(!themeData.noBorder).arg(!themeData.noContent)                             .arg(w).arg(h);    QPixmap cachedPixmap;    ThemeMapKey key(themeData);    ThemeMapData data = alphaCache.value(key);    bool haveCachedPixmap = false;    bool isCached = data.dataValid;    if (isCached) {        if (!(stateHasData = data.hasAnyData))            return; // Cached NOOP        inspectData = data.wasAlphaSwapped;        partIsTransparent = data.partIsTransparent;        hasAlpha = data.hasAlphaChannel;        alphaType = data.alphaType;        potentialInvalidAlpha = data.hadInvalidAlpha;        haveCachedPixmap = QPixmapCache::find(pixmapCacheKey, cachedPixmap);#ifdef DEBUG_XP_STYLE        char buf[25];        ::sprintf(buf, "+ Pixmap(%3d, %3d) ]", w, h);        printf("---[ CACHED %s--------> Name(%-10s) Part(%d) State(%d)\n",               haveCachedPixmap ? buf : "]-------------------",               qPrintable(themeData.name), themeData.partId, themeData.stateId);#endif    } else {        // Not cached, so get values from Theme Engine        BOOL tmt_borderonly = false;        COLORREF tmt_transparentcolor = 0x0;        PROPERTYORIGIN proporigin = PO_NOTFOUND;        pGetThemeBool(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERONLY, &tmt_borderonly);        pGetThemeColor(themeData.handle(), themeData.partId, themeData.stateId, TMT_TRANSPARENTCOLOR, &tmt_transparentcolor);        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_CAPTIONMARGINS, &proporigin);        inspectData = (tmt_transparentcolor != 0 || tmt_borderonly || proporigin == PO_PART || proporigin == PO_STATE);        partIsTransparent = isTransparent(themeData);        potentialInvalidAlpha = false;        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &proporigin);        if (proporigin == PO_PART || proporigin == PO_STATE) {            int tmt_glyphtype = GT_NONE;            pGetThemeEnumValue(themeData.handle(), themeData.partId, themeData.stateId, TMT_GLYPHTYPE, &tmt_glyphtype);            potentialInvalidAlpha = partIsTransparent && !inspectData && tmt_glyphtype == GT_IMAGEGLYPH;        }#ifdef DEBUG_XP_STYLE        printf("---[ NOT CACHED ]-----------------------> Name(%-10s) Part(%d) State(%d)\n",               qPrintable(themeData.name), themeData.partId, themeData.stateId);        printf("-->partIsTransparen      = %d\n", partIsTransparent);        printf("-->inspectData           = %d\n", inspectData);        printf("-->potentialInvalidAlpha = %d\n", potentialInvalidAlpha);        showProperties(themeData);#endif    }    bool wasAlphaSwapped = false;    bool wasAlphaFixed = false;    // OLD PSDK Workaround ------------------------------------------------------------------------    // See if we need extra clipping for the older PSDK, which does    // not have a DrawThemeBackgroundEx function for DTGB_OMITBORDER    // and DTGB_OMITCONTENT    bool addBorderContentClipping = false;    QRegion extraClip;    QRect area = rect;    if (themeData.noBorder || themeData.noContent) {        extraClip = area;        // We are running on a system where the uxtheme.dll does not have        // the DrawThemeBackgroundEx function, so we need to clip away        // borders or contents manually.        int borderSize = 0;        PROPERTYORIGIN origin = PO_NOTFOUND;        pGetThemePropertyOrigin(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &origin);        pGetThemeInt(themeData.handle(), themeData.partId, themeData.stateId, TMT_BORDERSIZE, &borderSize);        // Clip away border region        if ((origin == PO_CLASS || origin == PO_PART || origin == PO_STATE) && borderSize > 0) {            if (themeData.noBorder) {                extraClip &= area;                area = area.adjusted(-borderSize, -borderSize, borderSize, borderSize);            }            // Clip away content region            if (themeData.noContent) {                QRegion content = area.adjusted(borderSize, borderSize, -borderSize, -borderSize);                extraClip ^= content;            }        }        addBorderContentClipping = (themeData.noBorder | themeData.noContent);    }    QImage img;    if (!haveCachedPixmap) { // If the pixmap is not cached, generate it! -------------------------        buffer(w, h); // Ensure a buffer of at least (w, h) in size        HDC dc = bufferHDC();        // Clear the buffer        if (alphaType != NoAlpha) {            // Consider have separate "memset" function for small chunks for more speedup            memset(bufferPixels, inspectData ? 0xFF : 0x00, bufferW * h * 4);        }        // Difference between area and rect        int dx = area.x() - rect.x();        int dy = area.y() - rect.y();        int dr = area.right() - rect.right();        int db = area.bottom() - rect.bottom();        // Adjust so painting rect starts from Origo        rect.moveTo(0,0);        area.moveTo(dx,dy);        DTBGOPTS drawOptions;        drawOptions.dwSize = sizeof(drawOptions);        drawOptions.rcClip = themeData.toRECT(rect);        drawOptions.dwFlags = DTBG_CLIPRECT                            | (themeData.noBorder ? DTBG_OMITBORDER : 0)                            | (themeData.noContent ? DTBG_OMITCONTENT : 0);        // Drawing the part into the backing store        if (pDrawThemeBackgroundEx != 0) {	    RECT rect(themeData.toRECT(area));            pDrawThemeBackgroundEx(themeData.handle(), dc, themeData.partId, themeData.stateId, &rect, &drawOptions);        } else {            // Set the clip region, if used..            if (addBorderContentClipping) {                SelectClipRgn(dc, extraClip.handle());                // Compensate for the noBorder area difference (noContent has the same area)                drawOptions.rcClip = themeData.toRECT(rect.adjusted(dx, dy, dr, db));            }            pDrawThemeBackground(themeData.handle(), dc, themeData.partId, themeData.stateId, &(drawOptions.rcClip), 0);            if (addBorderContentClipping)                SelectClipRgn(dc, 0);        }        // If not cached, analyze the buffer data to figure        // out alpha type, and if it contains data        if (!isCached) {            if (inspectData)                stateHasData = hasAnyData(rect);            // SHORTCUT: If the part's state has no data, cache it for NOOP later            if (!stateHasData) {                memset(&data, 0, sizeof(data));                data.dataValid = true;                alphaCache.insert(key, data);                return;            }            hasAlpha = hasAlphaChannel(rect);            if (!hasAlpha && partIsTransparent)                potentialInvalidAlpha = true;#if defined(DEBUG_XP_STYLE) && 1            dumpNativeDIB(w, h);#endif        }        // Swap alpha values, if needed        if (inspectData)            wasAlphaSwapped = swapAlphaChannel(rect);        // Fix alpha values, if needed        if (potentialInvalidAlpha)            wasAlphaFixed = fixAlphaChannel(rect);        QImage::Format format;        if ((partIsTransparent && !wasAlphaSwapped) || (!partIsTransparent && hasAlpha)) {            format = QImage::Format_ARGB32_Premultiplied;            alphaType = RealAlpha;        } else if (wasAlphaSwapped) {            format = QImage::Format_ARGB32_Premultiplied;            alphaType = MaskAlpha;        } else {            format = QImage::Format_RGB32;            alphaType = NoAlpha;        }#if defined(DEBUG_XP_STYLE) && 1        printf("Image format is: %s\n", alphaType == RealAlpha ? "Real Alpha" : alphaType == MaskAlpha ? "Masked Alpha" : "No Alpha");#endif        img = QImage(bufferPixels, bufferW, bufferH, format);    }    // Blitting backing store    bool useRegion = partIsTransparent && !hasAlpha && !wasAlphaSwapped;    QRegion newRegion;    QRegion oldRegion;    if (useRegion) {        newRegion = region(themeData);        oldRegion = painter->clipRegion();        painter->setClipRegion(newRegion);#if defined(DEBUG_XP_STYLE) && 0        printf("Using region:\n");        QVector<QRect> rects = newRegion.rects();        for (int i = 0; i < rects.count(); ++i) {            const QRect &r = rects.at(i);            printf("    (%d, %d, %d, %d)\n", r.x(), r.y(), r.right(), r.bottom());        }#endif    }    if (addBorderContentClipping)        painter->setClipRegion(extraClip, Qt::IntersectClip);    if (!themeData.mirrorHorizontally && !themeData.mirrorVertically && !themeData.rotate) {        if (!haveCachedPixmap)            painter->drawImage(themeData.rect, img, rect);        else            painter->drawPixmap(themeData.rect, cachedPixmap);    } else {        // This is _slow_!        // Make a copy containing only the necessary data, and mirror        // on all wanted axes. Then draw the copy.        // If cached, the normal pixmap is cached, instead of caching        // all possible orientations for each part and state.        QImage imgCopy;        if (!haveCachedPixmap)            imgCopy = img.copy(rect);        else            imgCopy = cachedPixmap.toImage();        if (themeData.rotate) {            QMatrix rotMatrix;            rotMatrix.rotate(themeData.rotate);            imgCopy = imgCopy.transformed(rotMatrix);        }        if (themeData.mirrorHorizontally || themeData.mirrorVertically) {            imgCopy = imgCopy.mirrored(themeData.mirrorHorizontally, themeData.mirrorVertically);        }        painter->drawImage(themeData.rect,                           imgCopy);    }    if (useRegion || addBorderContentClipping) {        if (oldRegion.isEmpty())            painter->setClipping(false);        else            painter->setClipRegion(oldRegion);    }    // Cache the pixmap to avoid expensive swapAlphaChannel() calls    if (!haveCachedPixmap && ((w * h) < 2000) && w && h) {        QPixmap pix = QPixmap::fromImage(img).copy(rect);        QPixmapCache::insert(pixmapCacheKey, pix);#ifdef DEBUG_XP_STYLE        printf("+++Adding pixmap to cache, size(%d, %d), wasAlphaSwapped(%d), wasAlphaFixed(%d), name(%s)\n",               w, h, wasAlphaSwapped, wasAlphaFixed, qPrintable(pixmapCacheKey));#endif    }    // Add to theme part cache    if (!isCached) {        memset(&data, 0, sizeof(data));        data.dataValid = true;        data.partIsTransparent = partIsTransparent;        data.alphaType = alphaType;        data.hasAlphaChannel = hasAlpha;        data.hasAnyData = stateHasData;        data.wasAlphaSwapped = wasAlphaSwapped;        data.hadInvalidAlpha = wasAlphaFixed;        alphaCache.insert(key, data);    }}// ------------------------------------------------------------------------------------------------/*!    \class QWindowsXPStyle    \brief The QWindowsXPStyle class provides a Microsoft Windows XP-like look and feel.    \ingroup appearance    \warning This style is only available on the Windows XP platform    because it makes use of Windows XP's style engine.    Most of the functions are documented in the base classes

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -