📄 imagelist.c
字号:
BitBlt (InternalDrag.himl->hdcMask, 0, 0, cx, cy, himlTrack->hdcMask, iTrack * cx, 0, SRCCOPY);
InternalDrag.himl->cCurImage = 1;
return TRUE;
}
/*************************************************************************
* ImageList_Copy [COMCTL32.@]
*
* Copies an image of the source image list to an image of the
* destination image list. Images can be copied or swapped.
*
* PARAMS
* himlDst [I] handle to the destination image list
* iDst [I] destination image index.
* himlSrc [I] handle to the source image list
* iSrc [I] source image index
* uFlags [I] flags for the copy operation
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* Copying from one image list to another is possible. The original
* implementation just copies or swaps within one image list.
* Could this feature become a bug??? ;-)
*/
BOOL WINAPI
ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
INT iSrc, UINT uFlags)
{
POINT ptSrc, ptDst;
TRACE("himlDst=%p iDst=%d himlSrc=%p iSrc=%d\n", himlDst, iDst, himlSrc, iSrc);
if (!is_valid(himlSrc) || !is_valid(himlDst))
return FALSE;
if ((iDst < 0) || (iDst >= himlDst->cCurImage))
return FALSE;
if ((iSrc < 0) || (iSrc >= himlSrc->cCurImage))
return FALSE;
imagelist_point_from_index( himlDst, iDst, &ptDst );
imagelist_point_from_index( himlSrc, iSrc, &ptSrc );
if (uFlags & ILCF_SWAP) {
/* swap */
HDC hdcBmp;
HBITMAP hbmTempImage, hbmTempMask;
hdcBmp = CreateCompatibleDC (0);
/* create temporary bitmaps */
hbmTempImage = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
himlSrc->uBitsPixel, NULL);
hbmTempMask = CreateBitmap (himlSrc->cx, himlSrc->cy, 1,
1, NULL);
/* copy (and stretch) destination to temporary bitmaps.(save) */
/* image */
SelectObject (hdcBmp, hbmTempImage);
StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
SRCCOPY);
/* mask */
SelectObject (hdcBmp, hbmTempMask);
StretchBlt (hdcBmp, 0, 0, himlSrc->cx, himlSrc->cy,
himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
SRCCOPY);
/* copy (and stretch) source to destination */
/* image */
StretchBlt (himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* mask */
StretchBlt (himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* copy (without stretching) temporary bitmaps to source (restore) */
/* mask */
BitBlt (himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
hdcBmp, 0, 0, SRCCOPY);
/* image */
BitBlt (himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
hdcBmp, 0, 0, SRCCOPY);
/* delete temporary bitmaps */
DeleteObject (hbmTempMask);
DeleteObject (hbmTempImage);
DeleteDC(hdcBmp);
}
else {
/* copy image */
StretchBlt (himlDst->hdcImage, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
himlSrc->hdcImage, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
SRCCOPY);
/* copy mask */
StretchBlt (himlDst->hdcMask, ptDst.x, ptDst.y, himlDst->cx, himlDst->cy,
himlSrc->hdcMask, ptSrc.x, ptSrc.y, himlSrc->cx, himlSrc->cy,
SRCCOPY);
}
return TRUE;
}
/*************************************************************************
* ImageList_Create [COMCTL32.@]
*
* Creates a new image list.
*
* PARAMS
* cx [I] image height
* cy [I] image width
* flags [I] creation flags
* cInitial [I] initial number of images in the image list
* cGrow [I] number of images by which image list grows
*
* RETURNS
* Success: Handle to the created image list
* Failure: NULL
*/
HIMAGELIST WINAPI
ImageList_Create (INT cx, INT cy, UINT flags,
INT cInitial, INT cGrow)
{
HIMAGELIST himl;
INT nCount;
HBITMAP hbmTemp;
UINT ilc = (flags & 0xFE);
static const WORD aBitBlend25[] =
{0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00};
static const WORD aBitBlend50[] =
{0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA};
TRACE("(%d %d 0x%x %d %d)\n", cx, cy, flags, cInitial, cGrow);
himl = (HIMAGELIST)Alloc (sizeof(struct _IMAGELIST));
if (!himl)
return NULL;
cGrow = (cGrow < 4) ? 4 : (cGrow + 3) & ~3;
himl->magic = IMAGELIST_MAGIC;
himl->cx = cx;
himl->cy = cy;
himl->flags = flags;
himl->cMaxImage = cInitial + cGrow;
himl->cInitial = cInitial;
himl->cGrow = cGrow;
himl->clrFg = CLR_DEFAULT;
himl->clrBk = CLR_NONE;
/* initialize overlay mask indices */
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
himl->nOvlIdx[nCount] = -1;
/* Create Image & Mask DCs */
himl->hdcImage = CreateCompatibleDC (0);
if (!himl->hdcImage)
goto cleanup;
if (himl->flags & ILC_MASK){
himl->hdcMask = CreateCompatibleDC(0);
if (!himl->hdcMask)
goto cleanup;
}
/* Default to ILC_COLOR4 if none of the ILC_COLOR* flags are specified */
if (ilc == ILC_COLOR)
ilc = ILC_COLOR4;
if (ilc >= ILC_COLOR4 && ilc <= ILC_COLOR32)
himl->uBitsPixel = ilc;
else
himl->uBitsPixel = (UINT)GetDeviceCaps (himl->hdcImage, BITSPIXEL);
if (himl->cMaxImage > 0) {
himl->hbmImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage, cy);
SelectObject(himl->hdcImage, himl->hbmImage);
} else
himl->hbmImage = 0;
if ((himl->cMaxImage > 0) && (himl->flags & ILC_MASK)) {
SIZE sz;
imagelist_get_bitmap_size(himl, himl->cMaxImage, himl->cy, &sz);
himl->hbmMask = CreateBitmap (sz.cx, sz.cy, 1, 1, NULL);
if (himl->hbmMask == 0) {
ERR("Error creating mask bitmap!\n");
goto cleanup;
}
SelectObject(himl->hdcMask, himl->hbmMask);
}
else
himl->hbmMask = 0;
/* create blending brushes */
hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend25);
himl->hbrBlend25 = CreatePatternBrush (hbmTemp);
DeleteObject (hbmTemp);
hbmTemp = CreateBitmap (8, 8, 1, 1, &aBitBlend50);
himl->hbrBlend50 = CreatePatternBrush (hbmTemp);
DeleteObject (hbmTemp);
TRACE("created imagelist %p\n", himl);
return himl;
cleanup:
if (himl) ImageList_Destroy(himl);
return NULL;
}
/*************************************************************************
* ImageList_Destroy [COMCTL32.@]
*
* Destroys an image list.
*
* PARAMS
* himl [I] handle to image list
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI
ImageList_Destroy (HIMAGELIST himl)
{
if (!is_valid(himl))
return FALSE;
/* delete image bitmaps */
if (himl->hbmImage)
DeleteObject (himl->hbmImage);
if (himl->hbmMask)
DeleteObject (himl->hbmMask);
/* delete image & mask DCs */
if (himl->hdcImage)
DeleteDC(himl->hdcImage);
if (himl->hdcMask)
DeleteDC(himl->hdcMask);
/* delete blending brushes */
if (himl->hbrBlend25)
DeleteObject (himl->hbrBlend25);
if (himl->hbrBlend50)
DeleteObject (himl->hbrBlend50);
ZeroMemory(himl, sizeof(*himl));
Free (himl);
return TRUE;
}
/*************************************************************************
* ImageList_DragEnter [COMCTL32.@]
*
* Locks window update and displays the drag image at the given position.
*
* PARAMS
* hwndLock [I] handle of the window that owns the drag image.
* x [I] X position of the drag image.
* y [I] Y position of the drag image.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* The position of the drag image is relative to the window, not
* the client area.
*/
BOOL WINAPI
ImageList_DragEnter (HWND hwndLock, INT x, INT y)
{
TRACE("(hwnd=%p x=%d y=%d)\n", hwndLock, x, y);
if (!is_valid(InternalDrag.himl))
return FALSE;
if (hwndLock)
InternalDrag.hwnd = hwndLock;
else
InternalDrag.hwnd = GetDesktopWindow ();
InternalDrag.x = x;
InternalDrag.y = y;
/* draw the drag image and save the background */
if (!ImageList_DragShowNolock(TRUE)) {
return FALSE;
}
return TRUE;
}
/*************************************************************************
* ImageList_DragLeave [COMCTL32.@]
*
* Unlocks window update and hides the drag image.
*
* PARAMS
* hwndLock [I] handle of the window that owns the drag image.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI
ImageList_DragLeave (HWND hwndLock)
{
/* As we don't save drag info in the window this can lead to problems if
an app does not supply the same window as DragEnter */
/* if (hwndLock)
InternalDrag.hwnd = hwndLock;
else
InternalDrag.hwnd = GetDesktopWindow (); */
if(!hwndLock)
hwndLock = GetDesktopWindow();
if(InternalDrag.hwnd != hwndLock)
FIXME("DragLeave hWnd != DragEnter hWnd\n");
ImageList_DragShowNolock (FALSE);
return TRUE;
}
/*************************************************************************
* ImageList_InternalDragDraw [Internal]
*
* Draws the drag image.
*
* PARAMS
* hdc [I] device context to draw into.
* x [I] X position of the drag image.
* y [I] Y position of the drag image.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* The position of the drag image is relative to the window, not
* the client area.
*
*/
static inline void
ImageList_InternalDragDraw (HDC hdc, INT x, INT y)
{
IMAGELISTDRAWPARAMS imldp;
ZeroMemory (&imldp, sizeof(imldp));
imldp.cbSize = sizeof(imldp);
imldp.himl = InternalDrag.himl;
imldp.i = 0;
imldp.hdcDst = hdc,
imldp.x = x;
imldp.y = y;
imldp.rgbBk = CLR_DEFAULT;
imldp.rgbFg = CLR_DEFAULT;
imldp.fStyle = ILD_NORMAL;
imldp.fState = ILS_ALPHA;
imldp.Frame = 128;
/* FIXME: instead of using the alpha blending, we should
* create a 50% mask, and draw it semitransparantly that way */
ImageList_DrawIndirect (&imldp);
}
/*************************************************************************
* ImageList_DragMove [COMCTL32.@]
*
* Moves the drag image.
*
* PARAMS
* x [I] X position of the drag image.
* y [I] Y position of the drag image.
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* NOTES
* The position of the drag image is relative to the window, not
* the client area.
*
* BUGS
* The drag image should be drawn semitransparent.
*/
BOOL WINAPI
ImageList_DragMove (INT x, INT y)
{
TRACE("(x=%d y=%d)\n", x, y);
if (!is_valid(InternalDrag.himl))
return FALSE;
/* draw/update the drag image */
if (InternalDrag.bShow) {
HDC hdcDrag;
HDC hdcOffScreen;
HDC hdcBg;
HBITMAP hbmOffScreen;
INT origNewX, origNewY;
INT origOldX, origOldY;
INT origRegX, origRegY;
INT sizeRegX, sizeRegY;
/* calculate the update region */
origNewX = x - InternalDrag.dxHotspot;
origNewY = y - InternalDrag.dyHotspot;
origOldX = InternalDrag.x - InternalDrag.dxHotspot;
origOldY = InternalDrag.y - InternalDrag.dyHotspot;
origRegX = min(origNewX, origOldX);
origRegY = min(origNewY, origOldY);
sizeRegX = InternalDrag.himl->cx + abs(x - InternalDrag.x);
sizeRegY = InternalDrag.himl->cy + abs(y - InternalDrag.y);
hdcDrag = GetDCEx(InternalDrag.hwnd, 0,
DCX_WINDOW | DCX_CACHE | DCX_LOCKWINDOWUPDATE);
hdcOffScreen = CreateCompatibleDC(hdcDrag);
hdcBg = CreateCompatibleDC(hdcDrag);
hbmOffScreen = CreateCompatibleBitmap(hdcDrag, sizeRegX, sizeRegY);
SelectObject(hdcOffScreen, hbmOffScreen);
SelectObject(hdcBg, InternalDrag.hbmBg);
/* get the actual background of the update region */
BitBlt(hdcOffScreen, 0, 0, sizeRegX, sizeRegY, hdcDrag,
origRegX, origRegY, SRCCOPY);
/* erase the old image */
BitBlt(hdcOffScreen, origOldX - origRegX, origOldY - origRegY,
InternalDrag.himl->cx, InternalDrag.himl->cy, hdcBg, 0, 0,
SRCCOPY);
/* save the background */
BitBlt(hdcBg, 0, 0, InternalDrag.himl->cx, InternalDrag.himl->cy,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -