Hello, this patch fixes the ImageList_Merge error I got with FreeSolitaire. The changes in ImageList_BeginDrag are speedup's/cosmetics: the new and old bitmap have always the same size, no need to use StretchBlt. Changelog: Michael Stefaniuc <mstefani@redhat.com> implementet ImageList_GetDragImage fixed ImageList_SetDragCursorImage and ImageList_Merge no need for StretchBlt in ImageList_BeginDrag added some traces bye michael -- Michael Stefaniuc Tel.: +49-711-96437-199 System Administration Fax.: +49-711-96437-111 Red Hat GmbH Email: mstefani@redhat.de Hauptstaetterstr. 58 http://www.redhat.de/ D-70178 Stuttgart
Index: imagelist.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/imagelist.c,v retrieving revision 1.43 diff -u -r1.43 imagelist.c --- imagelist.c 2001/09/10 23:09:04 1.43 +++ imagelist.c 2001/11/28 02:05:02 @@ -41,12 +41,14 @@ /* internal image list data used for Drag & Drop operations */ static HIMAGELIST himlInternalDrag = NULL; +/* offset of the Hotspot to the origin of the himlInternalDrag image */ static INT nInternalDragHotspotX = 0; static INT nInternalDragHotspotY = 0; static HWND hwndInternalDrag = 0; -static INT xInternalPos = 0; -static INT yInternalPos = 0; +/* coordinates of the Hotspot relative to the window origin */ +static INT nInternalDragPosX = 0; +static INT nInternalDragPosY = 0; static HDC hdcBackBuffer = 0; static HBITMAP hbmBackBuffer = 0; @@ -703,18 +705,22 @@ INT dxHotspot, INT dyHotspot) { HDC hdcSrc, hdcDst; + INT cx, cy; FIXME("partially implemented!\n"); + TRACE("(himlTrack=%p iTrack=%d dx=%d dy=%d)\n", himlTrack, iTrack, + dxHotspot, dyHotspot); if (himlTrack == NULL) return FALSE; + cx = himlTrack->cx; + cy = himlTrack->cy; + if (himlInternalDrag) ImageList_EndDrag (); - himlInternalDrag = - ImageList_Create (himlTrack->cx, himlTrack->cy, - himlTrack->flags, 1, 1); + himlInternalDrag = ImageList_Create (cx, cy, himlTrack->flags, 1, 1); if (himlInternalDrag == NULL) { ERR("Error creating drag image list!\n"); return FALSE; @@ -729,14 +735,12 @@ /* copy image */ SelectObject (hdcSrc, himlTrack->hbmImage); SelectObject (hdcDst, himlInternalDrag->hbmImage); - StretchBlt (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc, - iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY); + BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY); /* copy mask */ SelectObject (hdcSrc, himlTrack->hbmMask); SelectObject (hdcDst, himlInternalDrag->hbmMask); - StretchBlt (hdcDst, 0, 0, himlInternalDrag->cx, himlInternalDrag->cy, hdcSrc, - iTrack * himlTrack->cx, 0, himlTrack->cx, himlTrack->cy, SRCCOPY); + BitBlt (hdcDst, 0, 0, cx, cy, hdcSrc, iTrack * cx, 0, SRCCOPY); DeleteDC (hdcSrc); DeleteDC (hdcDst); @@ -1028,6 +1032,8 @@ BOOL WINAPI ImageList_DragEnter (HWND hwndLock, INT x, INT y) { + TRACE("(hwnd=%#x x=%d y=%d)\n", hwndLock, x, y); + if (himlInternalDrag == NULL) return FALSE; @@ -1036,8 +1042,8 @@ else hwndInternalDrag = GetDesktopWindow (); - xInternalPos = x; - yInternalPos = y; + nInternalDragPosX = x; + nInternalDragPosY = y; hdcBackBuffer = CreateCompatibleDC (0); hbmBackBuffer = CreateCompatibleBitmap (hdcBackBuffer, @@ -1100,10 +1106,12 @@ BOOL WINAPI ImageList_DragMove (INT x, INT y) { + TRACE("(x=%d y=%d)\n", x, y); + ImageList_DragShowNolock (FALSE); - xInternalPos = x; - yInternalPos = y; + nInternalDragPosX = x; + nInternalDragPosY = y; ImageList_DragShowNolock (TRUE); @@ -1457,10 +1465,17 @@ HIMAGELIST WINAPI ImageList_GetDragImage (POINT *ppt, POINT *pptHotspot) { - FIXME("semi-stub!\n"); - - if (himlInternalDrag) + if (himlInternalDrag) { + if (ppt) { + ppt->x = nInternalDragPosX; + ppt->y = nInternalDragPosY; + } + if (pptHotspot) { + pptHotspot->x = nInternalDragHotspotX; + pptHotspot->y = nInternalDragHotspotY; + } return (himlInternalDrag); + } return NULL; } @@ -1834,6 +1849,9 @@ INT xOff1, yOff1, xOff2, yOff2; INT nX1, nX2; + TRACE("(himl1=%p i1=%d himl2=%p i2=%d dx=%d dy=%d)\n", himl1, i1, himl2, + i2, dx, dy); + if ((himl1 == NULL) || (himl2 == NULL)) return NULL; @@ -1918,6 +1936,7 @@ DeleteDC (hdcSrcImage); DeleteDC (hdcDstImage); + himlDst->cCurImage = 1; } return himlDst; @@ -2479,8 +2498,7 @@ INT dxHotspot, INT dyHotspot) { HIMAGELIST himlTemp; - - FIXME("semi-stub!\n"); + INT dx, dy; if (himlInternalDrag == NULL) return FALSE; @@ -2488,16 +2506,28 @@ TRACE(" dxH=%d dyH=%d nX=%d nY=%d\n", dxHotspot, dyHotspot, nInternalDragHotspotX, nInternalDragHotspotY); - himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag, - dxHotspot, dyHotspot); + /* Calculate the offset between the origin of the old image and the + * origin of the second image. + * dxHotspot, dyHotspot is the offset of THE Hotspot (there is only one + * hotspot) to the origin of the second image (himlDrag). + * See M$DN for details */ + dx = nInternalDragHotspotX - dxHotspot; + dy = nInternalDragHotspotY - dyHotspot; + himlTemp = ImageList_Merge (himlInternalDrag, 0, himlDrag, iDrag, dx, dy); ImageList_Destroy (himlInternalDrag); himlInternalDrag = himlTemp; - nInternalDragHotspotX = dxHotspot; - nInternalDragHotspotY = dyHotspot; + /* update the InternalDragOffset, if the origin of the origin of the + * DragImage was changed by ImageList_Merge. */ + if (dx > nInternalDragHotspotX) { + nInternalDragHotspotX = dx; + } + if (dy > nInternalDragHotspotY) { + nInternalDragHotspotY = dy; + } - return FALSE; + return TRUE; }