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

📄 imagelist.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
        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;
}


/* helper for _read_bitmap currently unused */
#if 0
static int may_use_dibsection(HDC hdc) {
    int bitspixel = GetDeviceCaps(hdc,BITSPIXEL)*GetDeviceCaps(hdc,PLANES);
    if (bitspixel>8)
	return TRUE;
    if (bitspixel<=4)
	return FALSE;
    return GetDeviceCaps(hdc,CAPS1) & C1_DIBENGINE;
}
#endif

/* helper for ImageList_Read, see comments below */
static BOOL _read_bitmap(HIMAGELIST himl, HDC hdcIml, LPSTREAM pstm, int ilcFlag)
{
    HDC                 xdc = 0;
    BITMAPFILEHEADER	bmfh;
    BITMAPINFOHEADER	bmih;
    int			bitsperpixel,palspace,longsperline,width,height;
    LPBITMAPINFO       bmi = NULL;
    int                result = FALSE;
    HBITMAP            hDIB = 0;
    LPBYTE             bits = NULL;
    int i, j, nheight, nRows, nCols;
    POINT pt;
    int cy = himl->cy;

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

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

    if (!SUCCEEDED(IStream_Read ( pstm, &bmih, sizeof(bmih), NULL)))
        return result;

    if ((bmih.biSize != sizeof(bmih)))
	return 0;

    bitsperpixel = bmih.biPlanes * bmih.biBitCount;
    if (bitsperpixel<=8)
        palspace = (1<<bitsperpixel)*sizeof(RGBQUAD);
    else
        palspace = 0;
    width = bmih.biWidth;
    height = bmih.biHeight;
    bmi = Alloc(sizeof(bmih)+palspace);
    if (!bmi)
        return result;

    memcpy(bmi, &bmih, sizeof(bmih));
    longsperline = ((width*bitsperpixel+31)&~0x1f)>>5;
    bmi->bmiHeader.biSizeImage = (longsperline*height)<<2;

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

    xdc = GetDC(0);

    nheight = cy;
    nRows = height/cy;
    nCols = width/himl->cx;

    hDIB = CreateDIBSection(xdc, bmi, 0, (LPVOID*) &bits, 0, 0);
    if (!hDIB)
        goto error;
    if (!SUCCEEDED(IStream_Read(pstm, bits, bmi->bmiHeader.biSizeImage, NULL)))
        goto error;

    /* Copy the NxM bitmap into a 1x(N*M) bitmap we need, linewise */
    /* Do not forget that windows bitmaps are bottom->top */
    for (i=0; i < nRows; i++) {
        for (j=0; j < nCols; j++) {
            imagelist_point_from_index(himl, i*nCols + j, &pt);
            StretchDIBits(hdcIml, pt.x, pt.y, himl->cx, cy,
                      j*himl->cx, (nRows - 1 - i)*himl->cy, himl->cx, cy, bits,
                      bmi, DIB_RGB_COLORS, SRCCOPY);
        }
    }

    result = TRUE;
error:
    if (xdc)	ReleaseDC(0,xdc);
    Free(bmi);
    if (hDIB)   DeleteObject(hDIB);
    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];
 *
 * CAVEAT: Those images are within a NxM bitmap, not the 1xN we expect.
 *         _read_bitmap needs to convert them.
 */
HIMAGELIST WINAPI ImageList_Read (LPSTREAM pstm)
{
    ILHEAD	ilHead;
    HIMAGELIST	himl;
    HBITMAP	hbmColor=0,hbmMask=0;
    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;

    himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
    if (!himl) {
	DeleteObject(hbmColor);
	DeleteObject(hbmMask);
	return NULL;
    }
    if (!_read_bitmap(himl, himl->hdcImage, pstm, ilHead.flags & ~ILC_MASK)) {
	WARN("failed to read bitmap from stream\n");
	return NULL;
    }
    if (ilHead.flags & ILC_MASK) {
	if (!_read_bitmap(himl, himl->hdcMask, pstm, 0)) {
	    DeleteObject(hbmColor);
	    return NULL;
	}
    }

    SelectObject(himl->hdcImage, hbmColor);
    DeleteObject(himl->hbmImage);
    himl->hbmImage = hbmColor;
    if (hbmMask){
        SelectObject(himl->hdcMask, hbmMask);
        DeleteObject(himl->hbmMask);
        himl->hbmMask = hbmMask;
    }
    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
 */

BOOL WINAPI
ImageList_Remove (HIMAGELIST himl, INT i)
{
    HBITMAP hbmNewImage, hbmNewMask;
    HDC     hdcBmp;
    INT     nCount;
    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) {
        /* 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;
        himl->cCurImage = 0;
        for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
             himl->nOvlIdx[nCount] = -1;

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

        if (himl->hbmMask) {

            imagelist_get_bitmap_size(himl, himl->cMaxImage, himl->cy, &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) */
        nCount = (himl->cCurImage + himl->cGrow - 1);

        TRACE(" - Number of images: %d / %d (Old/New)\n",
                 himl->cCurImage, himl->cCurImage - 1);
        TRACE(" - Max. number of images: %d / %d (Old/New)\n",
                 himl->cMaxImage, himl->cCurImage + himl->cGrow - 1);

        hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, nCount, himl->cy);

        imagelist_get_bitmap_size(himl, nCount, himl->cy, &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,
                                   (himl->cCurImage - i - 1), i + 1 );

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

        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--;
        himl->cMaxImage = himl->cCurImage + himl->cGrow;
    }

    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 i, HICON hIcon)
{
    HDC     hdcImage;
    INT     nIndex;
    HICON   hBestFitIcon;
    HBITMAP hbmOldSrc;
    ICONINFO  ii;
    BITMAP  bmp;
    BOOL    ret;
    POINT   pt;

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

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

    h

⌨️ 快捷键说明

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