https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cc25a266f2717fc8fa763…
commit cc25a266f2717fc8fa7637c7569cfdcb7d027457
Author: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
AuthorDate: Mon Dec 31 02:28:18 2018 +0200
Commit: Giannis Adamopoulos <gadamopoulos(a)reactos.org>
CommitDate: Wed Jun 12 19:20:44 2019 +0300
[COMCTL32] imagelist: Make the exported functions use the internal IImageList2
- Add a hack to rename the exported functions and use the Internal_ prefix for them so
that the IImageList can use them with minimal code changes.
- Add the correct implementation of the affected exported functions making them now
use the IImageList of the passed HIMAGELIST.
This indirection is possible because an HIMAGELIST is also a IImageList*.
This indirection is also needed because we can end up using image lists created by
either comctl32 v5 or comctl32 v6.
This is how windows manage to use an HIMAGELIST created by comctl32 v5 when it is
passed to comctl32 v6.
What really happens in this scenario is that the exported functions of both versions
end up using the interface
stored in the object without checking if this interface is the version provided in the
same dll or in the other.
---
dll/win32/comctl32/imagelist.c | 379 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 377 insertions(+), 2 deletions(-)
diff --git a/dll/win32/comctl32/imagelist.c b/dll/win32/comctl32/imagelist.c
index 1f119f3504e..11ad5080f0a 100644
--- a/dll/win32/comctl32/imagelist.c
+++ b/dll/win32/comctl32/imagelist.c
@@ -51,6 +51,35 @@ WINE_DEFAULT_DEBUG_CHANNEL(imagelist);
#define MAX_OVERLAYIMAGE 15
+#ifdef __REACTOS__
+//The big bad reactos image list hack!
+BOOL is_valid2(HIMAGELIST himl);
+INT WINAPI Internal_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon);
+BOOL WINAPI Internal_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp);
+COLORREF WINAPI Internal_SetBkColor (HIMAGELIST himl, COLORREF clrBk);
+BOOL WINAPI Internal_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay);
+
+#define ImageList_Add Internal_Add
+#define ImageList_ReplaceIcon Internal_ReplaceIcon
+#define ImageList_SetOverlayImage Internal_SetOverlayImage
+#define ImageList_Replace Internal_Replace
+#define ImageList_AddMasked Internal_AddMasked
+#define ImageList_Remove Internal_Remove
+#define ImageList_GetIcon Internal_GetIcon
+#define ImageList_GetImageInfo Internal_GetImageInfo
+#define ImageList_Copy Internal_Copy
+#define ImageList_Merge Internal_Merge
+#define ImageList_Duplicate Internal_Duplicate
+#define ImageList_GetIconSize Internal_GetIconSize
+#define ImageList_SetIconSize Internal_SetIconSize
+#define ImageList_GetImageCount Internal_GetImageCount
+#define ImageList_SetImageCount Internal_SetImageCount
+#define ImageList_SetBkColor Internal_SetBkColor
+#define ImageList_GetBkColor Internal_GetBkColor
+#define ImageList_BeginDrag Internal_BeginDrag
+#define ImageList_DrawIndirect Internal_DrawIndirect
+#endif
+
struct _IMAGELIST
{
IImageList2 IImageList2_iface; /* 00: IImageList vtable */
@@ -72,6 +101,9 @@ struct _IMAGELIST
INT nOvlIdx[MAX_OVERLAYIMAGE]; /* 38: overlay images index */
/* not yet found out */
+ #ifdef __REACTOS__
+ ULONG usMagic;
+ #endif
HBRUSH hbrBlend25;
HBRUSH hbrBlend50;
INT cInitial;
@@ -1843,8 +1875,13 @@ DWORD WINAPI
ImageList_GetFlags(HIMAGELIST himl)
{
TRACE("%p\n", himl);
-
+#ifdef __REACTOS__
+ if(!is_valid2(himl))
+ return 0;
+ return himl->flags;
+#else
return is_valid(himl) ? himl->flags : 0;
+#endif
}
@@ -2032,6 +2069,12 @@ ImageList_GetImageInfo (HIMAGELIST himl, INT i, IMAGEINFO
*pImageInfo)
BOOL WINAPI
ImageList_GetImageRect (HIMAGELIST himl, INT i, LPRECT lpRect)
{
+#ifdef __REACTOS__
+ IMAGEINFO ImageInfo;
+ if (!ImageList_GetImageInfo(himl, i, &ImageInfo))
+ return FALSE;
+ *lpRect = ImageInfo.rcImage;
+#else
POINT pt;
if (!is_valid(himl) || (lpRect == NULL))
@@ -2044,7 +2087,7 @@ ImageList_GetImageRect (HIMAGELIST himl, INT i, LPRECT lpRect)
lpRect->top = pt.y;
lpRect->right = pt.x + himl->cx;
lpRect->bottom = pt.y + himl->cy;
-
+#endif
return TRUE;
}
@@ -3300,6 +3343,10 @@ static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT
count)
UINT WINAPI
ImageList_SetColorTable(HIMAGELIST himl, UINT uStartIndex, UINT cEntries, const RGBQUAD
*prgb)
{
+#ifdef __REACTOS__
+ if(!is_valid2(himl))
+ return 0;
+#endif
TRACE("(%p, %d, %d, %p)\n", himl, uStartIndex, cEntries, prgb);
himl->color_table_set = TRUE;
return SetDIBColorTable(himl->hdcImage, uStartIndex, cEntries, prgb);
@@ -3526,6 +3573,12 @@ static HRESULT WINAPI ImageListImpl_Copy(IImageList2 *iface, int
dst_index,
if (!unk_src)
return E_FAIL;
+#ifdef __REACTOS__
+ /* Make sure that the second image list uses the same implementation with the first
*/
+ if (!is_valid2((HIMAGELIST)unk_src))
+ return E_FAIL;
+#endif
+
/* TODO: Add test for IID_ImageList2 too */
if (FAILED(IUnknown_QueryInterface(unk_src, &IID_IImageList,
(void **) &src)))
@@ -3550,6 +3603,12 @@ static HRESULT WINAPI ImageListImpl_Merge(IImageList2 *iface, int
i1,
TRACE("(%p)->(%d %p %d %d %d %s %p)\n", iface, i1, punk2, i2, dx, dy,
debugstr_guid(riid), ppv);
+#ifdef __REACTOS__
+ /* Make sure that the second image list uses the same implementation with the first
*/
+ if (!is_valid2((HIMAGELIST)punk2))
+ return E_FAIL;
+#endif
+
/* TODO: Add test for IID_ImageList2 too */
if (FAILED(IUnknown_QueryInterface(punk2, &IID_IImageList,
(void **) &iml2)))
@@ -3879,7 +3938,12 @@ static BOOL is_valid(HIMAGELIST himl)
BOOL valid;
__TRY
{
+ #ifdef __REACTOS__
+ valid = himl && himl->usMagic == IMAGELIST_MAGIC;
+ #else
valid = himl && himl->IImageList2_iface.lpVtbl ==
&ImageListImpl_Vtbl;
+ #endif
+
}
__EXCEPT_PAGE_FAULT
{
@@ -3926,6 +3990,9 @@ static HRESULT ImageListImpl_CreateInstance(const IUnknown
*pUnkOuter, REFIID ii
if (!This) return E_OUTOFMEMORY;
This->IImageList2_iface.lpVtbl = &ImageListImpl_Vtbl;
+#ifdef __REACTOS__
+ This->usMagic = IMAGELIST_MAGIC;
+#endif
This->ref = 1;
ret = IImageList2_QueryInterface(&This->IImageList2_iface, iid, ppv);
@@ -3933,3 +4000,311 @@ static HRESULT ImageListImpl_CreateInstance(const IUnknown
*pUnkOuter, REFIID ii
return ret;
}
+
+
+
+#ifdef __REACTOS__
+//The big bad reactos image list hack!
+#undef ImageList_Add
+#undef ImageList_ReplaceIcon
+#undef ImageList_SetOverlayImage
+#undef ImageList_Replace
+#undef ImageList_AddMasked
+#undef ImageList_Remove
+#undef ImageList_GetIcon
+#undef ImageList_GetImageInfo
+#undef ImageList_Copy
+#undef ImageList_Merge
+#undef ImageList_Duplicate
+#undef ImageList_GetIconSize
+#undef ImageList_SetIconSize
+#undef ImageList_GetImageCount
+#undef ImageList_SetImageCount
+#undef ImageList_SetBkColor
+#undef ImageList_GetBkColor
+#undef ImageList_BeginDrag
+#undef ImageList_DrawIndirect
+
+static inline IImageList2* IImageList2_from_impl(HIMAGELIST himl)
+{
+ if (is_valid(himl))
+ {
+ return &himl->IImageList2_iface;
+ }
+ return NULL;
+}
+
+BOOL is_valid2(HIMAGELIST himl)
+{
+ BOOL valid;
+ __TRY
+ {
+ valid = himl &&
+ himl->IImageList2_iface.lpVtbl == &ImageListImpl_Vtbl &&
+ himl->usMagic == IMAGELIST_MAGIC;
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ valid = FALSE;
+ }
+ __ENDTRY
+ return valid;
+}
+
+INT WINAPI
+ImageList_Add (HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
+{
+ int res;
+ HRESULT hr;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return -1;
+
+ hr = piml->lpVtbl->Add(piml, hbmImage, hbmMask, &res);
+ if (FAILED(hr))
+ return -1;
+
+ return res;
+}
+
+INT WINAPI
+ImageList_ReplaceIcon (HIMAGELIST himl, INT nIndex, HICON hIcon)
+{
+ int res;
+ HRESULT hr;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return -1;
+
+ hr = piml->lpVtbl->ReplaceIcon(piml, nIndex, hIcon, &res);
+ if (FAILED(hr))
+ return -1;
+
+ return res;
+}
+
+BOOL WINAPI
+ImageList_SetOverlayImage (HIMAGELIST himl, INT iImage, INT iOverlay)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->SetOverlayImage(piml, iImage, iOverlay) == S_OK) ? TRUE :
FALSE;
+}
+
+BOOL WINAPI
+ImageList_Replace (HIMAGELIST himl, INT i, HBITMAP hbmImage,
+ HBITMAP hbmMask)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->Replace(piml, i, hbmImage, hbmMask) == S_OK) ? TRUE :
FALSE;
+}
+
+INT WINAPI
+ImageList_AddMasked (HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
+{
+ int res;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ HRESULT hr;
+ if (!piml)
+ return -1;
+
+ hr = piml->lpVtbl->AddMasked(piml, hBitmap, clrMask, &res);
+ if (FAILED(hr))
+ return -1;
+
+ return res;
+}
+
+BOOL WINAPI
+ImageList_Remove (HIMAGELIST himl, INT i)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return -1;
+
+ return (piml->lpVtbl->Remove(piml, i) == S_OK) ? TRUE : FALSE;
+}
+
+HICON WINAPI
+ImageList_GetIcon (HIMAGELIST himl, INT i, UINT fStyle)
+{
+ HICON res;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ HRESULT hr;
+ if (!piml)
+ return NULL;
+
+ hr = piml->lpVtbl->GetIcon(piml, i, fStyle, &res);
+ if (FAILED(hr))
+ return NULL;
+
+ return res;
+}
+
+BOOL WINAPI
+ImageList_GetImageInfo (HIMAGELIST himl, INT i, IMAGEINFO *pImageInfo)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->GetImageInfo(piml, i, pImageInfo) == S_OK) ? TRUE :
FALSE;
+}
+
+BOOL WINAPI
+ImageList_Copy (HIMAGELIST himlDst, INT iDst, HIMAGELIST himlSrc,
+ INT iSrc, UINT uFlags)
+{
+ IImageList2 *pimlDst, *pimlSrc;
+ pimlDst = IImageList2_from_impl(himlDst);
+ pimlSrc = IImageList2_from_impl(himlSrc);
+ if (!pimlDst || !pimlSrc)
+ return FALSE;
+
+ return (pimlDst->lpVtbl->Copy(pimlDst, iDst, (IUnknown*)pimlSrc, iSrc, uFlags)
== S_OK) ? TRUE : FALSE;
+}
+
+HIMAGELIST WINAPI
+ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
+ INT dx, INT dy)
+{
+ HRESULT hr;
+ IImageList2 *piml1, *piml2, *pimlMerged;
+ piml1 = IImageList2_from_impl(himl1);
+ piml2 = IImageList2_from_impl(himl2);
+ if (!piml1 || !piml2)
+ return NULL;
+
+ hr = piml1->lpVtbl->Merge(piml1, i1, (IUnknown*)piml2, i2, dx, dy,
&IID_IImageList2, (void**)&pimlMerged);
+ if (FAILED(hr))
+ return NULL;
+
+ return (HIMAGELIST)pimlMerged;
+}
+
+HIMAGELIST WINAPI
+ImageList_Duplicate (HIMAGELIST himlSrc)
+{
+ HRESULT hr;
+ IImageList2 *piml, *pimlCloned;
+ piml = IImageList2_from_impl(himlSrc);
+ if (!piml)
+ return FALSE;
+
+ hr = piml->lpVtbl->Clone(piml, &IID_IImageList2, (void**)&pimlCloned);
+ if (FAILED(hr))
+ return NULL;
+
+ return (HIMAGELIST)pimlCloned;
+}
+
+BOOL WINAPI
+ImageList_GetIconSize (HIMAGELIST himl, INT *cx, INT *cy)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->GetIconSize(piml, cx, cy) == S_OK) ? TRUE : FALSE;
+}
+
+BOOL WINAPI
+ImageList_SetIconSize (HIMAGELIST himl, INT cx, INT cy)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->SetIconSize(piml, cx, cy) == S_OK) ? TRUE : FALSE;
+}
+
+INT WINAPI
+ImageList_GetImageCount (HIMAGELIST himl)
+{
+ int res;
+ HRESULT hr;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return 0;
+
+ hr = piml->lpVtbl->GetImageCount(piml, &res);
+ if (FAILED(hr))
+ return 0;
+
+ return res;
+}
+
+BOOL WINAPI
+ImageList_SetImageCount (HIMAGELIST himl, UINT iImageCount)
+{
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->SetImageCount(piml, iImageCount) == S_OK) ? TRUE :
FALSE;
+}
+
+COLORREF WINAPI
+ImageList_SetBkColor (HIMAGELIST himl, COLORREF clrBk)
+{
+ COLORREF res;
+ HRESULT hr;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return CLR_NONE;
+
+ hr = piml->lpVtbl->SetBkColor(piml, clrBk, &res);
+ if (FAILED(hr))
+ return CLR_NONE;
+
+ return res;
+}
+
+COLORREF WINAPI
+ImageList_GetBkColor (HIMAGELIST himl)
+{
+ COLORREF res;
+ HRESULT hr;
+ IImageList2* piml = IImageList2_from_impl(himl);
+ if (!piml)
+ return CLR_NONE;
+
+ hr = piml->lpVtbl->GetBkColor(piml, &res);
+ if (FAILED(hr))
+ return CLR_NONE;
+
+ return res;
+}
+
+BOOL WINAPI
+ImageList_BeginDrag (HIMAGELIST himlTrack, INT iTrack,
+ INT dxHotspot, INT dyHotspot)
+{
+ IImageList2* piml = IImageList2_from_impl(himlTrack);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->BeginDrag(piml, iTrack, dxHotspot, dyHotspot) == S_OK) ?
TRUE : FALSE;
+}
+
+BOOL WINAPI
+ImageList_DrawIndirect (IMAGELISTDRAWPARAMS *pimldp)
+{
+ IImageList2* piml;
+
+ if (!pimldp)
+ return FALSE;
+
+ piml = IImageList2_from_impl(pimldp->himl);
+ if (!piml)
+ return FALSE;
+
+ return (piml->lpVtbl->Draw(piml, pimldp) == S_OK) ? TRUE : FALSE;
+}
+
+#endif