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