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

📄 imagelist.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
        yOff1 = 0;
        yOff2 = dy;
    }
    else if (dy < 0) {
        cyDst = max (himl2->cy, himl1->cy - dy);
        yOff1 = -dy;
        yOff2 = 0;
    }
    else {
        cyDst = max (himl1->cy, himl2->cy);
        yOff1 = 0;
        yOff2 = 0;
    }

    himlDst = ImageList_Create (cxDst, cyDst, ILC_MASK | ILC_COLOR, 1, 1);

    if (himlDst)
    {
        imagelist_point_from_index( himl1, i1, &pt1 );
        imagelist_point_from_index( himl1, i2, &pt2 );

        /* copy image */
        BitBlt (himlDst->hdcImage, 0, 0, cxDst, cyDst, himl1->hdcImage, 0, 0, BLACKNESS);
        if (i1 >= 0 && i1 < himl1->cCurImage)
            BitBlt (himlDst->hdcImage, xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcImage, pt1.x, pt1.y, SRCCOPY);
        if (i2 >= 0 && i2 < himl2->cCurImage)
        {
            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask , pt2.x, pt2.y, SRCAND);
            BitBlt (himlDst->hdcImage, xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcImage, pt2.x, pt2.y, SRCPAINT);
        }

        /* copy mask */
        BitBlt (himlDst->hdcMask, 0, 0, cxDst, cyDst, himl1->hdcMask, 0, 0, WHITENESS);
        if (i1 >= 0 && i1 < himl1->cCurImage)
            BitBlt (himlDst->hdcMask,  xOff1, yOff1, himl1->cx, himl1->cy, himl1->hdcMask,  pt1.x, pt1.y, SRCCOPY);
        if (i2 >= 0 && i2 < himl2->cCurImage)
            BitBlt (himlDst->hdcMask,  xOff2, yOff2, himl2->cx, himl2->cy, himl2->hdcMask,  pt2.x, pt2.y, SRCAND);

	himlDst->cCurImage = 1;
    }

    return himlDst;
}


/***********************************************************************
 *           DIB_GetDIBWidthBytes
 *
 * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
 */
static int DIB_GetDIBWidthBytes( int width, int depth )
{
    int words;

    switch(depth)
    {
    case 1:  words = (width + 31) / 32; break;
    case 4:  words = (width + 7) / 8; break;
    case 8:  words = (width + 3) / 4; break;
    case 15:
    case 16: words = (width + 1) / 2; break;
    case 24: words = (width * 3 + 3)/4; break;

    default:
        WARN("(%d): Unsupported depth\n", depth );
        /* fall through */
    case 32:
        words = width;
        break;
    }
    return 4 * words;
}

/***********************************************************************
 *           DIB_GetDIBImageBytes
 *
 * Return the number of bytes used to hold the image in a DIB bitmap.
 */
static int DIB_GetDIBImageBytes( int width, int height, int depth )
{
    return DIB_GetDIBWidthBytes( width, depth ) * abs( height );
}


/* helper for ImageList_Read, see comments below */
static BOOL _read_bitmap(HIMAGELIST himl, HDC hdcIml, LPSTREAM pstm)
{
    BITMAPFILEHEADER	bmfh;
    int bitsperpixel, palspace;
    char bmi_buf[sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256];
    LPBITMAPINFO bmi = (LPBITMAPINFO)bmi_buf;
    int                result = FALSE;
    LPBYTE             bits = NULL;

    if (!SUCCEEDED(IStream_Read ( pstm, &bmfh, sizeof(bmfh), NULL)))
        return FALSE;

    if (bmfh.bfType != (('M'<<8)|'B'))
        return FALSE;

    if (!SUCCEEDED(IStream_Read ( pstm, &bmi->bmiHeader, sizeof(bmi->bmiHeader), NULL)))
        return FALSE;

    if ((bmi->bmiHeader.biSize != sizeof(bmi->bmiHeader)))
        return FALSE;

    TRACE("width %u, height %u, planes %u, bpp %u\n",
          bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
          bmi->bmiHeader.biPlanes, bmi->bmiHeader.biBitCount);

    bitsperpixel = bmi->bmiHeader.biPlanes * bmi->bmiHeader.biBitCount;
    if (bitsperpixel<=8)
        palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
    else
        palspace = 0;

    bmi->bmiHeader.biSizeImage = DIB_GetDIBImageBytes(bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight, bitsperpixel);

    /* read the palette right after the end of the bitmapinfoheader */
    if (palspace && !SUCCEEDED(IStream_Read(pstm, bmi->bmiColors, palspace, NULL)))
	goto error;

    bits = Alloc(bmi->bmiHeader.biSizeImage);
    if (!bits)
        goto error;
    if (!SUCCEEDED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
        goto error;

    if (!StretchDIBits(hdcIml, 0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
                  0, 0, bmi->bmiHeader.biWidth, bmi->bmiHeader.biHeight,
                  bits, bmi, DIB_RGB_COLORS, SRCCOPY))
        goto error;
    result = TRUE;

error:
    Free(bits);
    return result;
}

/*************************************************************************
 * ImageList_Read [COMCTL32.@]
 *
 * Reads an image list from a stream.
 *
 * PARAMS
 *     pstm [I] pointer to a stream
 *
 * RETURNS
 *     Success: handle to image list
 *     Failure: NULL
 *
 * The format is like this:
 *	ILHEAD			ilheadstruct;
 *
 * for the color image part:
 *	BITMAPFILEHEADER	bmfh;
 *	BITMAPINFOHEADER	bmih;
 * only if it has a palette:
 *	RGBQUAD		rgbs[nr_of_paletted_colors];
 *
 *	BYTE			colorbits[imagesize];
 *
 * the following only if the ILC_MASK bit is set in ILHEAD.ilFlags:
 *	BITMAPFILEHEADER	bmfh_mask;
 *	BITMAPINFOHEADER	bmih_mask;
 * only if it has a palette (it usually does not):
 *	RGBQUAD		rgbs[nr_of_paletted_colors];
 *
 *	BYTE			maskbits[imagesize];
 */
HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
{
    ILHEAD	ilHead;
    HIMAGELIST	himl;
    int		i;

    TRACE("%p\n", pstm);

    if (!SUCCEEDED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
	return NULL;
    if (ilHead.usMagic != (('L' << 8) | 'I'))
	return NULL;
    if (ilHead.usVersion != 0x101) /* probably version? */
	return NULL;

    TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
          ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);

    himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
    if (!himl)
	return NULL;

    if (!_read_bitmap(himl, himl->hdcImage, pstm))
    {
	WARN("failed to read bitmap from stream\n");
	return NULL;
    }
    if (ilHead.flags & ILC_MASK)
    {
        if (!_read_bitmap(himl, himl->hdcMask, pstm))
        {
            WARN("failed to read mask bitmap from stream\n");
	    return NULL;
	}
    }

    himl->cCurImage = ilHead.cCurImage;
    himl->cMaxImage = ilHead.cMaxImage;

    ImageList_SetBkColor(himl,ilHead.bkcolor);
    for (i=0;i<4;i++)
	ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
    return himl;
}


/*************************************************************************
 * ImageList_Remove [COMCTL32.@]
 *
 * Removes an image from an image list
 *
 * PARAMS
 *     himl [I] image list handle
 *     i    [I] image index
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 *
 * FIXME: as the image list storage test shows, native comctl32 simply shifts
 * images without creating a new bitmap.
 */
BOOL WINAPI
ImageList_Remove (HIMAGELIST himl, INT i)
{
    HBITMAP hbmNewImage, hbmNewMask;
    HDC     hdcBmp;
    SIZE    sz;

    TRACE("(himl=%p i=%d)\n", himl, i);

    if (!is_valid(himl)) {
        ERR("Invalid image list handle!\n");
        return FALSE;
    }

    if ((i < -1) || (i >= himl->cCurImage)) {
        TRACE("index out of range! %d\n", i);
        return FALSE;
    }

    if (i == -1) {
        INT nCount;

        /* remove all */
	if (himl->cCurImage == 0) {
	    /* remove all on empty ImageList is allowed */
	    TRACE("remove all on empty ImageList!\n");
	    return TRUE;
	}

        himl->cMaxImage = himl->cInitial + himl->cGrow - 1;
        himl->cCurImage = 0;
        for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
             himl->nOvlIdx[nCount] = -1;

        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage, himl->cx);
        SelectObject (himl->hdcImage, hbmNewImage);
        DeleteObject (himl->hbmImage);
        himl->hbmImage = hbmNewImage;

        if (himl->hbmMask) {

            imagelist_get_bitmap_size(himl, himl->cMaxImage, himl->cx, &sz);
            hbmNewMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
            SelectObject (himl->hdcMask, hbmNewMask);
            DeleteObject (himl->hbmMask);
            himl->hbmMask = hbmNewMask;
        }
    }
    else {
        /* delete one image */
        TRACE("Remove single image! %d\n", i);

        /* create new bitmap(s) */
        TRACE(" - Number of images: %d / %d (Old/New)\n",
                 himl->cCurImage, himl->cCurImage - 1);

        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage, himl->cx);

        imagelist_get_bitmap_size(himl, himl->cMaxImage, himl->cx, &sz );
        if (himl->hbmMask)
            hbmNewMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
        else
            hbmNewMask = 0;  /* Just to keep compiler happy! */

        hdcBmp = CreateCompatibleDC (0);

        /* copy all images and masks prior to the "removed" image */
        if (i > 0) {
            TRACE("Pre image copy: Copy %d images\n", i);

            SelectObject (hdcBmp, hbmNewImage);
            imagelist_copy_images( himl, himl->hdcImage, hdcBmp, 0, i, 0 );

            if (himl->hbmMask) {
                SelectObject (hdcBmp, hbmNewMask);
                imagelist_copy_images( himl, himl->hdcMask, hdcBmp, 0, i, 0 );
            }
        }

        /* copy all images and masks behind the removed image */
        if (i < himl->cCurImage - 1) {
            TRACE("Post image copy!\n");

            SelectObject (hdcBmp, hbmNewImage);
            imagelist_copy_images( himl, himl->hdcImage, hdcBmp, i + 1,
                                   (himl->cCurImage - i), i );

            if (himl->hbmMask) {
                SelectObject (hdcBmp, hbmNewMask);
                imagelist_copy_images( himl, himl->hdcMask, hdcBmp, i + 1,
                                       (himl->cCurImage - i), i );
            }
        }

        DeleteDC (hdcBmp);

        /* delete old images and insert new ones */
        SelectObject (himl->hdcImage, hbmNewImage);
        DeleteObject (himl->hbmImage);
        himl->hbmImage = hbmNewImage;
        if (himl->hbmMask) {
            SelectObject (himl->hdcMask, hbmNewMask);
            DeleteObject (himl->hbmMask);
            himl->hbmMask = hbmNewMask;
        }

        himl->cCurImage--;
    }

    return TRUE;
}


/*************************************************************************
 * ImageList_Replace [COMCTL32.@]
 *
 * Replaces an image in an image list with a new image.
 *
 * PARAMS
 *     himl     [I] handle to image list
 *     i        [I] image index
 *     hbmImage [I] handle to image bitmap
 *     hbmMask  [I] handle to mask bitmap. Can be NULL.
 *
 * RETURNS
 *     Success: TRUE
 *     Failure: FALSE
 */

BOOL WINAPI
ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
		   HBITMAP hbmMask)
{
    HDC hdcImage;
    BITMAP bmp;
    HBITMAP hOldBitmap;
    POINT pt;

    TRACE("%p %d %p %p\n", himl, i, hbmImage, hbmMask);

    if (!is_valid(himl)) {
        ERR("Invalid image list handle!\n");
        return FALSE;
    }

    if ((i >= himl->cMaxImage) || (i < 0)) {
        ERR("Invalid image index!\n");
        return FALSE;
    }

    if (!GetObjectW(hbmImage, sizeof(BITMAP), (LPVOID)&bmp))
        return FALSE;

    hdcImage = CreateCompatibleDC (0);

    /* Replace Image */
    hOldBitmap = SelectObject (hdcImage, hbmImage);

    imagelist_point_from_index(himl, i, &pt);
    StretchBlt (himl->hdcImage, pt.x, pt.y, himl->cx, himl->cy,
                  hdcImage, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);

    if (himl->hbmMask)
    {
        HDC hdcTemp;
        HBITMAP hOldBitmapTemp;

        hdcTemp   = CreateCompatibleDC(0);
        hOldBitmapTemp = SelectObject(hdcTemp, hbmMask);

        StretchBlt (himl->hdcMask, pt.x, pt.y, himl->cx, himl->cy,
                      hdcTemp, 0, 0, bmp.bmWidth, bmp.bmHeight, SRCCOPY);
        SelectObject(hdcTemp, hOldBitmapTemp);
        DeleteDC(hdcTemp);

        /* Remove the background from the image
        */
        BitBlt (himl->hdcImage, pt.x, pt.y, bmp.bmWidth, bmp.bmHeight,
                himl->hdcMask, pt.x, pt.y, 0x220326); /* NOTSRCAND */
    }

    SelectObject (hdcImage, hOldBitmap);
    DeleteDC (hdcImage);

    return TRUE;
}


/*************************************************************************
 * ImageList_ReplaceIcon [COMCTL32.@]
 *
 * Replaces an image in an image list using an icon.
 *
 * PARAMS
 *     himl  [I] handle to image list
 *     i     [I] image index
 *     hIcon [I] handle to icon
 *
 * RETURNS
 *     Success: index of the replaced image
 *     Failure: -1
 */

INT WINAPI
ImageList_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon)
{
    HDC     hdcImage;
    HICON   hBestFitIcon;
    HBITMAP hbmOldSrc;
    ICONINFO  ii;
    BITMAP  bmp;
    BOOL    ret;
    POINT   pt;

    TRACE("(%p %d %p)\n", himl, nIndex, hIcon);

    if (!is_valid(himl)) {
        ERR("invalid image list\n");
        return -1;
    }
    if ((nIndex >= himl->cMaxImage) || (nIndex < -1)) {
        ERR("invalid image index %d / %d\n", nIndex, himl

⌨️ 快捷键说明

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