Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Sam Joan Roque-Worcel
wine
Commits
3bc5ffd3
Commit
3bc5ffd3
authored
23 years ago
by
Michael Stefaniuc
Committed by
Alexandre Julliard
23 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Fixed/implemented the ImageList_*Drag* functions.
parent
a77f8d37
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
dlls/comctl32/imagelist.c
+201
-109
201 additions, 109 deletions
dlls/comctl32/imagelist.c
with
201 additions
and
109 deletions
dlls/comctl32/imagelist.c
+
201
−
109
View file @
3bc5ffd3
...
...
@@ -3,11 +3,11 @@
*
* Copyright 1998 Eric Kohl
* 2000 Jason Mawdsley.
* 2001 Michael Stefaniuc
*
* TODO:
* - Fix ImageList_DrawIndirect (xBitmap, yBitmap, rgbFg, rgbBk, dwRop).
* - Fix ImageList_GetIcon.
* - Fix drag functions.
* - Fix ImageList_Write.
* - Fix ImageList_SetFilter (undocumented).
* BTW does anybody know anything about this function???
...
...
@@ -23,6 +23,7 @@
* limited in functionality too.
*/
#include
<stdlib.h>
#include
<string.h>
#include
"winerror.h"
#include
"winbase.h"
...
...
@@ -37,21 +38,25 @@ DEFAULT_DEBUG_CHANNEL(imagelist);
#define MAX_OVERLAYIMAGE 15
/* internal image list data used for Drag & Drop operations */
typedef
struct
{
HWND
hwnd
;
HIMAGELIST
himl
;
/* position of the drag image relative to the window */
INT
x
;
INT
y
;
/* offset of the hotspot relative to the origin of the image */
INT
dxHotspot
;
INT
dyHotspot
;
/* is the drag image visible */
BOOL
bShow
;
/* saved background */
HBITMAP
hbmBg
;
}
INTERNALDRAG
;
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
;
/* coordinates of the Hotspot relative to the window origin */
static
INT
nInternalDragPosX
=
0
;
static
INT
nInternalDragPosY
=
0
;
static
INTERNALDRAG
InternalDrag
=
{
0
,
0
,
0
,
0
,
0
,
0
,
FALSE
,
0
};
static
HDC
hdcBackBuffer
=
0
;
static
HBITMAP
hbmBackBuffer
=
0
;
/*************************************************************************
...
...
@@ -76,7 +81,7 @@ IMAGELIST_InternalExpandBitmaps (HIMAGELIST himl, INT nImageCount, INT cx, INT c
HBITMAP
hbmNewBitmap
;
INT
nNewWidth
,
nNewCount
;
if
((
himl
->
cCurImage
+
nImageCount
<
himl
->
cMaxImage
)
if
((
himl
->
cCurImage
+
nImageCount
<
=
himl
->
cMaxImage
)
&&
(
himl
->
cy
>=
cy
))
return
;
...
...
@@ -459,9 +464,6 @@ IMAGELIST_InternalDrawOverlay(IMAGELISTDRAWPARAMS *pimldp, INT cx, INT cy)
}
/*************************************************************************
* ImageList_Add [COMCTL32.40]
*
...
...
@@ -707,45 +709,44 @@ ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
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
;
if
(
InternalDrag
.
himl
)
ImageList_EndDrag
();
cx
=
himlTrack
->
cx
;
cy
=
himlTrack
->
cy
;
if
(
himlInternalDrag
)
ImageList_EndDrag
();
himlInternalDrag
=
ImageList_Create
(
cx
,
cy
,
himlTrack
->
flags
,
1
,
1
);
if
(
himlInternalDrag
==
NULL
)
{
InternalDrag
.
himl
=
ImageList_Create
(
cx
,
cy
,
himlTrack
->
flags
,
1
,
1
);
if
(
InternalDrag
.
himl
==
NULL
)
{
ERR
(
"Error creating drag image list!
\n
"
);
return
FALSE
;
}
n
InternalDragHotspot
X
=
dxHotspot
;
n
InternalDragHotspot
Y
=
dyHotspot
;
InternalDrag
.
dx
Hotspot
=
dxHotspot
;
InternalDrag
.
dy
Hotspot
=
dyHotspot
;
hdcSrc
=
CreateCompatibleDC
(
0
);
hdcDst
=
CreateCompatibleDC
(
0
);
/* copy image */
SelectObject
(
hdcSrc
,
himlTrack
->
hbmImage
);
SelectObject
(
hdcDst
,
himl
InternalDrag
->
hbmImage
);
SelectObject
(
hdcDst
,
InternalDrag
.
himl
->
hbmImage
);
BitBlt
(
hdcDst
,
0
,
0
,
cx
,
cy
,
hdcSrc
,
iTrack
*
cx
,
0
,
SRCCOPY
);
/* copy mask */
SelectObject
(
hdcSrc
,
himlTrack
->
hbmMask
);
SelectObject
(
hdcDst
,
himl
InternalDrag
->
hbmMask
);
SelectObject
(
hdcDst
,
InternalDrag
.
himl
->
hbmMask
);
BitBlt
(
hdcDst
,
0
,
0
,
cx
,
cy
,
hdcSrc
,
iTrack
*
cx
,
0
,
SRCCOPY
);
DeleteDC
(
hdcSrc
);
DeleteDC
(
hdcDst
);
himl
InternalDrag
->
cCurImage
=
1
;
InternalDrag
.
himl
->
cCurImage
=
1
;
return
TRUE
;
}
...
...
@@ -1034,24 +1035,23 @@ ImageList_DragEnter (HWND hwndLock, INT x, INT y)
{
TRACE
(
"(hwnd=%#x x=%d y=%d)
\n
"
,
hwndLock
,
x
,
y
);
if
(
himl
InternalDrag
==
NULL
)
if
(
InternalDrag
.
himl
==
NULL
)
return
FALSE
;
if
(
hwndLock
)
hwnd
InternalDrag
=
hwndLock
;
InternalDrag
.
hwnd
=
hwndLock
;
else
hwndInternalDrag
=
GetDesktopWindow
();
nInternalDragPosX
=
x
;
nInternalDragPosY
=
y
;
InternalDrag
.
hwnd
=
GetDesktopWindow
();
hdcBackBuffer
=
CreateCompatibleDC
(
0
);
hbmBackBuffer
=
CreateCompatibleBitmap
(
hdcBackBuffer
,
himlInternalDrag
->
cx
,
himlInternalDrag
->
cy
);
InternalDrag
.
x
=
x
;
InternalDrag
.
y
=
y
;
ImageList_DragShowNolock
(
TRUE
);
/* draw the drag image and save the background */
if
(
!
ImageList_DragShowNolock
(
TRUE
))
{
return
FALSE
;
}
return
FALS
E
;
return
TRU
E
;
}
...
...
@@ -1072,15 +1072,12 @@ BOOL WINAPI
ImageList_DragLeave
(
HWND
hwndLock
)
{
if
(
hwndLock
)
hwnd
InternalDrag
=
hwndLock
;
InternalDrag
.
hwnd
=
hwndLock
;
else
hwnd
InternalDrag
=
GetDesktopWindow
();
InternalDrag
.
hwnd
=
GetDesktopWindow
();
ImageList_DragShowNolock
(
FALSE
);
DeleteDC
(
hdcBackBuffer
);
DeleteObject
(
hbmBackBuffer
);
return
TRUE
;
}
...
...
@@ -1101,6 +1098,9 @@ ImageList_DragLeave (HWND hwndLock)
* 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
...
...
@@ -1108,14 +1108,69 @@ ImageList_DragMove (INT x, INT y)
{
TRACE
(
"(x=%d y=%d)
\n
"
,
x
,
y
);
ImageList_DragShowNolock
(
FALSE
);
nInternalDragPosX
=
x
;
nInternalDragPosY
=
y
;
if
(
!
InternalDrag
.
himl
)
{
return
FALSE
;
}
ImageList_DragShowNolock
(
TRUE
);
/* 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
,
hdcOffScreen
,
origNewX
-
origRegX
,
origNewY
-
origRegY
,
SRCCOPY
);
/* draw the image */
/* FIXME: image should be drawn semitransparent */
ImageList_Draw
(
InternalDrag
.
himl
,
0
,
hdcOffScreen
,
origNewX
-
origRegX
,
origNewY
-
origRegY
,
ILD_NORMAL
);
/* draw the update region to the screen */
BitBlt
(
hdcDrag
,
origRegX
,
origRegY
,
sizeRegX
,
sizeRegY
,
hdcOffScreen
,
0
,
0
,
SRCCOPY
);
DeleteDC
(
hdcBg
);
DeleteDC
(
hdcOffScreen
);
ReleaseDC
(
InternalDrag
.
hwnd
,
hdcDrag
);
}
/* update the image position */
InternalDrag
.
x
=
x
;
InternalDrag
.
y
=
y
;
return
FALS
E
;
return
TRU
E
;
}
...
...
@@ -1131,39 +1186,59 @@ ImageList_DragMove (INT x, INT y)
* Success: TRUE
* Failure: FALSE
*
*
FIXME
*
semi-stub
.
*
BUGS
*
The drag image should be drawn semitransparent
.
*/
BOOL
WINAPI
ImageList_DragShowNolock
(
BOOL
bShow
)
{
HDC
hdcDrag
;
HDC
hdcBg
;
INT
x
,
y
;
FIXME
(
"semi-stub!
\n
"
);
TRACE
(
"bShow=0x%X!
\n
"
,
bShow
);
hdcDrag
=
GetDCEx
(
hwndInternalDrag
,
0
,
DCX_WINDOW
|
DCX_CACHE
|
DCX_LOCKWINDOWUPDATE
);
if
(
bShow
)
{
/* show drag image */
/* save background */
/* draw drag image */
/* DragImage is already visible/hidden */
if
((
InternalDrag
.
bShow
&&
bShow
)
||
(
!
InternalDrag
.
bShow
&&
!
bShow
))
{
return
FALSE
;
}
else
{
/* hide drag image */
/* restore background */
/* position of the origin of the DragImage */
x
=
InternalDrag
.
x
-
InternalDrag
.
dxHotspot
;
y
=
InternalDrag
.
y
-
InternalDrag
.
dyHotspot
;
hdcDrag
=
GetDCEx
(
InternalDrag
.
hwnd
,
0
,
DCX_WINDOW
|
DCX_CACHE
|
DCX_LOCKWINDOWUPDATE
);
if
(
!
hdcDrag
)
{
return
FALSE
;
}
ReleaseDC
(
hwndInternalDrag
,
hdcDrag
);
return
FALSE
;
hdcBg
=
CreateCompatibleDC
(
hdcDrag
);
if
(
!
InternalDrag
.
hbmBg
)
{
InternalDrag
.
hbmBg
=
CreateCompatibleBitmap
(
hdcDrag
,
InternalDrag
.
himl
->
cx
,
InternalDrag
.
himl
->
cy
);
}
SelectObject
(
hdcBg
,
InternalDrag
.
hbmBg
);
if
(
bShow
)
{
/* save the background */
BitBlt
(
hdcBg
,
0
,
0
,
InternalDrag
.
himl
->
cx
,
InternalDrag
.
himl
->
cy
,
hdcDrag
,
x
,
y
,
SRCCOPY
);
/* show the image */
/* FIXME: this should be drawn semitransparent */
ImageList_Draw
(
InternalDrag
.
himl
,
0
,
hdcDrag
,
x
,
y
,
ILD_NORMAL
);
}
else
{
/* hide the image */
BitBlt
(
hdcDrag
,
x
,
y
,
InternalDrag
.
himl
->
cx
,
InternalDrag
.
himl
->
cy
,
hdcBg
,
0
,
0
,
SRCCOPY
);
}
InternalDrag
.
bShow
=
!
InternalDrag
.
bShow
;
DeleteDC
(
hdcBg
);
ReleaseDC
(
InternalDrag
.
hwnd
,
hdcDrag
);
return
TRUE
;
}
...
...
@@ -1397,26 +1472,25 @@ ImageList_Duplicate (HIMAGELIST himlSrc)
* RETURNS
* Success: TRUE
* Failure: FALSE
*
* BUGS
* semi-stub.
*/
BOOL
WINAPI
ImageList_EndDrag
(
void
)
{
FIXME
(
"semi-stub!
\n
"
);
if
(
himlInternalDrag
)
{
ImageList_Destroy
(
himlInternalDrag
);
himlInternalDrag
=
NULL
;
nInternalDragHotspotX
=
0
;
nInternalDragHotspotY
=
0
;
}
/* hide the drag image */
ImageList_DragShowNolock
(
FALSE
);
/* cleanup the InternalDrag struct */
InternalDrag
.
hwnd
=
0
;
ImageList_Destroy
(
InternalDrag
.
himl
);
InternalDrag
.
himl
=
0
;
InternalDrag
.
x
=
0
;
InternalDrag
.
y
=
0
;
InternalDrag
.
dxHotspot
=
0
;
InternalDrag
.
dyHotspot
=
0
;
InternalDrag
.
bShow
=
FALSE
;
DeleteObject
(
InternalDrag
.
hbmBg
);
InternalDrag
.
hbmBg
=
0
;
return
TRUE
;
}
...
...
@@ -1457,24 +1531,21 @@ ImageList_GetBkColor (HIMAGELIST himl)
* RETURNS
* Success: Handle of the drag image list.
* Failure: NULL.
*
* BUGS
* semi-stub.
*/
HIMAGELIST
WINAPI
ImageList_GetDragImage
(
POINT
*
ppt
,
POINT
*
pptHotspot
)
{
if
(
himl
InternalDrag
)
{
if
(
InternalDrag
.
himl
)
{
if
(
ppt
)
{
ppt
->
x
=
n
InternalDrag
PosX
;
ppt
->
y
=
n
InternalDrag
PosY
;
ppt
->
x
=
InternalDrag
.
x
;
ppt
->
y
=
InternalDrag
.
y
;
}
if
(
pptHotspot
)
{
pptHotspot
->
x
=
n
InternalDragHotspot
X
;
pptHotspot
->
y
=
n
InternalDragHotspot
Y
;
pptHotspot
->
x
=
InternalDrag
.
dx
Hotspot
;
pptHotspot
->
y
=
InternalDrag
.
dy
Hotspot
;
}
return
(
himl
InternalDrag
);
return
(
InternalDrag
.
himl
);
}
return
NULL
;
...
...
@@ -2395,7 +2466,7 @@ ImageList_ReplaceIcon (HIMAGELIST himl, INT i, HICON hIcon)
GetObjectA
(
ii
.
hbmMask
,
sizeof
(
BITMAP
),
(
LPVOID
)
&
bmp
);
if
(
i
==
-
1
)
{
if
(
himl
->
cCurImage
+
1
>
=
himl
->
cMaxImage
)
if
(
himl
->
cCurImage
+
1
>
himl
->
cMaxImage
)
IMAGELIST_InternalExpandBitmaps
(
himl
,
1
,
0
,
0
);
nIndex
=
himl
->
cCurImage
;
...
...
@@ -2489,8 +2560,10 @@ ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
* Success: TRUE
* Failure: FALSE
*
* BUGS
* semi-stub.
* NOTES
* When this function is called and the drag image is visible, a
* short flickering occurs but this matches the Win9x behavior. It is
* possible to fix the flickering using code like in ImageList_DragMove.
*/
BOOL
WINAPI
...
...
@@ -2499,32 +2572,51 @@ ImageList_SetDragCursorImage (HIMAGELIST himlDrag, INT iDrag,
{
HIMAGELIST
himlTemp
;
INT
dx
,
dy
;
BOOL
visible
;
if
(
himl
InternalDrag
==
NULL
)
if
(
InternalDrag
.
himl
==
NULL
)
return
FALSE
;
TRACE
(
" dxH=%d dyH=%d nX=%d nY=%d
\n
"
,
dxHotspot
,
dyHotspot
,
nInternalDragHotspotX
,
nInternalDragHotspotY
);
dxHotspot
,
dyHotspot
,
InternalDrag
.
dxHotspot
,
InternalDrag
.
dyHotspot
);
visible
=
InternalDrag
.
bShow
;
/* 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)
.
* hotspot) to the origin of the second image.
* See M$DN for details */
dx
=
nInternalDragHotspotX
-
dxHotspot
;
dy
=
nInternalDragHotspotY
-
dyHotspot
;
dx
=
InternalDrag
.
dxHotspot
-
dxHotspot
;
dy
=
InternalDrag
.
dyHotspot
-
dyHotspot
;
himlTemp
=
ImageList_Merge
(
InternalDrag
.
himl
,
0
,
himlDrag
,
iDrag
,
dx
,
dy
);
himlTemp
=
ImageList_Merge
(
himlInternalDrag
,
0
,
himlDrag
,
iDrag
,
dx
,
dy
);
ImageList_Destroy
(
himlInternalDrag
);
himlInternalDrag
=
himlTemp
;
if
(
visible
)
{
/* hide the drag image */
ImageList_DragShowNolock
(
FALSE
);
}
if
((
InternalDrag
.
himl
->
cx
!=
himlTemp
->
cx
)
||
(
InternalDrag
.
himl
->
cy
!=
himlTemp
->
cy
))
{
/* the size of the drag image changed, invalidate the buffer */
DeleteObject
(
InternalDrag
.
hbmBg
);
InternalDrag
.
hbmBg
=
0
;
}
/* update the InternalDragOffset, if the origin of the origin of the
ImageList_Destroy
(
InternalDrag
.
himl
);
InternalDrag
.
himl
=
himlTemp
;
/* update the InternalDragOffset, if the origin of the
* DragImage was changed by ImageList_Merge. */
if
(
dx
>
nInternalDragHotspotX
)
{
nInternalDragHotspotX
=
dx
;
if
(
dx
>
InternalDrag
.
dxHotspot
)
{
InternalDrag
.
dxHotspot
=
dx
;
}
if
(
dy
>
InternalDrag
.
dyHotspot
)
{
InternalDrag
.
dyHotspot
=
dy
;
}
if
(
dy
>
nInternalDragHotspotY
)
{
nInternalDragHotspotY
=
dy
;
if
(
visible
)
{
/* show the drag image */
ImageList_DragShowNolock
(
TRUE
);
}
return
TRUE
;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment