Esempio n. 1
0
// static
HPOINTER QPixmap::toPmHPOINTER(const QIcon &icon, bool isPointer,
                               int hotX, int hotY, bool embedRealAlpha,
                               bool isMini)
{
    if (icon.isNull())
        return NULLHANDLE;

    // get the system icon size
    int w = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CXPOINTER : SV_CXICON);
    int h = WinQuerySysValue(HWND_DESKTOP, isPointer ? SV_CYPOINTER : SV_CYICON);
    if (!isPointer && isMini) {
        w = w / 2;
        h = h / 2;
    }

    // obtain the closest (but never larger) icon size we have
    QSize size = icon.actualSize(QSize(w, h));

    QPixmap pm = icon.pixmap(size);
    if (pm.isNull())
        return NULLHANDLE;

    // if we got a smaller pixmap then center it inside the box matching the
    // system size instead of letting WinCreatePointerIndirect() scale (this
    // covers a usual case when we get 32/16 px pixmaps on a 120 DPI system
    // where the icon size is 40/20 px respectively): scaling such small images
    // looks really ugly.
    if (!pm.isNull() && (pm.width() < w || pm.height() < h)) {
        Q_ASSERT(pm.width() <= w && pm.height() <= h);
        QPixmap pmNew(w, h);
        pmNew.fill(Qt::transparent);
        QPainter painter(&pmNew);
        int dx = (w - pm.width()) / 2;
        int dy = (h - pm.height()) / 2;
        painter.drawPixmap(dx, dy, pm);
        pm = pmNew;
        hotX += dx;
        hotY += dy;
    }

    POINTERINFO info;
    info.fPointer = isPointer;
    info.xHotspot = hotX;
    info.yHotspot = pm.height() - hotY - 1;
    info.hbmColor = pm.toPmHBITMAP(&info.hbmPointer, embedRealAlpha);
    info.hbmMiniPointer = NULLHANDLE;
    info.hbmMiniColor = NULLHANDLE;

    HPOINTER hIcon = WinCreatePointerIndirect(HWND_DESKTOP, &info);

    GpiDeleteBitmap(info.hbmPointer);
    GpiDeleteBitmap(info.hbmColor);

    return hIcon;
}
Esempio n. 2
0
static HPOINTER combineTwoCursors(LONG idOver, LONG idUnder)
{
    HPOINTER hptr = NULLHANDLE;

    POINTERINFO piOver, piUnder;
    HPOINTER hOver = WinQuerySysPointer(HWND_DESKTOP, idOver, FALSE);
    WinQueryPointerInfo(hOver, &piOver);
    HPOINTER hUnder = WinQuerySysPointer(HWND_DESKTOP, idUnder, FALSE);
    WinQueryPointerInfo(hUnder, &piUnder);
    if (piOver.hbmColor) {
        HPS hpsPtr, hpsTmp, hpsMask;
        HBITMAP hbmPtr, hbmTmp, hbmMask;
        qt_alloc_ps_with_bitmap(32, 32, false, hpsPtr, hbmPtr);
        qt_alloc_ps_with_bitmap(32, 32, false, hpsTmp, hbmTmp);
        qt_alloc_ps_with_bitmap(32, 64, true, hpsMask, hbmMask);
        // copy the overlying pointer
        POINTL ptls[] = { { 0, 0 }, { 31, 31 }, { 0, 0 }, { 32, 32 } };
        GpiWCBitBlt(hpsTmp, piOver.hbmColor, 4, ptls, ROP_SRCCOPY, BBO_IGNORE);
        // make its transparent pixels black
        ptls[2].y += 32; ptls[3].y += 32;
        GpiSetColor(hpsTmp, CLR_TRUE);
        GpiSetBackColor(hpsTmp, CLR_FALSE);
        GpiWCBitBlt(hpsTmp, piOver.hbmPointer, 4, ptls, 0x22, BBO_IGNORE);
        // copy the underlying pointer
        ptls[2].y -= 32; ptls[3].y -= 32;
        GpiWCBitBlt(hpsPtr, piUnder.hbmColor, 4, ptls, ROP_SRCCOPY, BBO_IGNORE);
        // make non-transparent pixels from the overlying pointer black
        ptls[2].y += 32; ptls[3].y += 32;
        GpiSetColor(hpsPtr, CLR_TRUE);
        GpiSetBackColor(hpsPtr, CLR_FALSE);
        GpiWCBitBlt(hpsPtr, piOver.hbmPointer, 4, ptls, ROP_SRCAND, BBO_IGNORE);
        // put the overlying pointer there
        ptls[2].y -= 32; ptls[3].y -= 32;
        ptls[1].x ++; ptls[1].y ++;
        GpiBitBlt(hpsPtr, hpsTmp, 4, ptls, ROP_SRCPAINT, BBO_IGNORE);
        // copy both underlying pointer's masks
        ptls[1].x --; ptls[1].y --;
        ptls[1].y += 32; ptls[3].y += 32;
        GpiWCBitBlt(hpsMask, piUnder.hbmPointer, 4, ptls, ROP_SRCCOPY, BBO_IGNORE);
        // add overlying pointer's XOR mask
        ptls[1].y -= 32; ptls[3].y -= 32;
        GpiWCBitBlt(hpsMask, piOver.hbmPointer, 4, ptls, ROP_SRCPAINT, BBO_IGNORE);
        // add overlying pointer's AND mask
        ptls[0].y += 32; ptls[2].y += 32;
        ptls[1].y += 32; ptls[3].y += 32;
        GpiWCBitBlt(hpsMask, piOver.hbmPointer, 4, ptls, ROP_SRCAND, BBO_IGNORE);
        // create the new pointer
        GpiSetBitmap(hpsPtr, NULLHANDLE);
        GpiSetBitmap(hpsMask, NULLHANDLE);
        piOver.hbmColor = hbmPtr;
        piOver.hbmPointer = hbmMask;
        piOver.hbmMiniColor = NULLHANDLE;
        piOver.hbmMiniPointer = NULLHANDLE;
        hptr = WinCreatePointerIndirect(HWND_DESKTOP, &piOver);
        qt_free_ps_with_bitmap(hpsMask,  hbmMask);
        qt_free_ps_with_bitmap(hpsTmp,  hbmTmp);
        qt_free_ps_with_bitmap(hpsPtr,  hbmPtr);
    } else {
        HPS hps;
        HBITMAP hbm;
        qt_alloc_ps_with_bitmap(32, 64, true, hps, hbm);
        POINTL ptls[] = { { 0, 0 }, { 31, 63 }, { 0, 0 }, { 32, 64 } };
        // make a copy of the underlying pointer
        GpiWCBitBlt(hps, piUnder.hbmPointer, 4, ptls, ROP_SRCCOPY, BBO_IGNORE);
        // combine AND masks
        ptls[0].y += 32; ptls[2].y += 32;
        GpiWCBitBlt(hps, piOver.hbmPointer, 4, ptls, ROP_SRCAND, BBO_IGNORE);
        // apply the overlying AND mask to the underlying XOR mask
        ptls[0].y -= 32; ptls[1].y -= 32;
        GpiWCBitBlt(hps, piOver.hbmPointer, 4, ptls, ROP_SRCAND, BBO_IGNORE);
        // apply the overlying XOR mask to the underlying XOR mask
        ptls[2].y -= 32; ptls[3].y -= 32;
        GpiWCBitBlt(hps, piOver.hbmPointer, 4, ptls, ROP_SRCINVERT, BBO_IGNORE);
        // create the new pointer
        GpiSetBitmap(hps, 0);
        hptr = WinCreatePointer(HWND_DESKTOP, hbm, TRUE,
                                piOver.xHotspot, piOver.yHotspot);
        qt_free_ps_with_bitmap(hps, hbm);
    }

    Q_ASSERT(hptr);
    return hptr;
}