[COMCTL32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Sat, 27 Sep 2014 00:19:40 +0000 (00:19 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sat, 27 Sep 2014 00:19:40 +0000 (00:19 +0000)
* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64322

reactos/dll/win32/comctl32/imagelist.c
reactos/dll/win32/comctl32/listview.c
reactos/dll/win32/comctl32/pager.c
reactos/dll/win32/comctl32/progress.c
reactos/dll/win32/comctl32/toolbar.c
reactos/dll/win32/comctl32/treeview.c
reactos/media/doc/README.WINE

index 54b0ff8..dbbb494 100644 (file)
@@ -48,8 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(imagelist);
 
 struct _IMAGELIST
 {
-    const struct IImageListVtbl *lpVtbl; /* 00: IImageList vtable */
-
+    IImageList2 IImageList2_iface;         /* 00: IImageList vtable */
     INT         cCurImage;                 /* 04: ImageCount */
     INT         cMaxImage;                 /* 08: maximages */
     INT         cGrow;                     /* 0C: cGrow */
@@ -116,9 +115,14 @@ typedef struct
 
 static INTERNALDRAG InternalDrag = { 0, 0, 0, 0, 0, 0, 0, FALSE, 0 };
 
+static inline HIMAGELIST impl_from_IImageList2(IImageList2 *iface)
+{
+    return CONTAINING_RECORD(iface, struct _IMAGELIST, IImageList2_iface);
+}
+
 static HBITMAP ImageList_CreateImage(HDC hdc, HIMAGELIST himl, UINT count);
 static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID iid, void** ppv);
-static inline BOOL is_valid(HIMAGELIST himl);
+static BOOL is_valid(HIMAGELIST himl);
 
 /*
  * An imagelist with N images is tiled like this:
@@ -2053,13 +2057,13 @@ ImageList_LoadImageW (HINSTANCE hi, LPCWSTR lpbmp, INT cx, INT cGrow,
  * RETURNS
  *     Success: The newly created image list. It contains a single image
  *              consisting of the second image merged with the first.
- *     Failure: NULL, if either himl1 or himl2 are invalid.
+ *     Failure: NULL, if either himl1 or himl2 is invalid.
  *
  * NOTES
  *   - The returned image list should be deleted by the caller using
  *     ImageList_Destroy() when it is no longer required.
- *   - If either i1 or i2 are not valid image indices they will be treated
- *     as a blank image.
+ *   - If either i1 or i2 is not a valid image index, they will be treated
+ *     as blank images.
  */
 HIMAGELIST WINAPI
 ImageList_Merge (HIMAGELIST himl1, INT i1, HIMAGELIST himl2, INT i2,
@@ -2363,6 +2367,12 @@ ImageList_Remove (HIMAGELIST himl, INT i)
         for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
              himl->nOvlIdx[nCount] = -1;
 
+        if (himl->has_alpha)
+        {
+            HeapFree( GetProcessHeap(), 0, himl->has_alpha );
+            himl->has_alpha = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, himl->cMaxImage );
+        }
+
         hbmNewImage = ImageList_CreateImage(himl->hdcImage, himl, himl->cMaxImage);
         SelectObject (himl->hdcImage, hbmNewImage);
         DeleteObject (himl->hbmImage);
@@ -3183,38 +3193,43 @@ ImageList_CoCreateInstance (REFCLSID rclsid, const IUnknown *punkOuter, REFIID r
  * IImageList implementation
  */
 
-static HRESULT WINAPI ImageListImpl_QueryInterface(IImageList *iface,
+static HRESULT WINAPI ImageListImpl_QueryInterface(IImageList2 *iface,
     REFIID iid, void **ppv)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+
     TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);
 
     if (!ppv) return E_INVALIDARG;
 
-    if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IImageList, iid))
-        *ppv = This;
+    if (IsEqualIID(&IID_IUnknown, iid) ||
+        IsEqualIID(&IID_IImageList, iid) ||
+        IsEqualIID(&IID_IImageList2, iid))
+    {
+        *ppv = &imgl->IImageList2_iface;
+    }
     else
     {
         *ppv = NULL;
         return E_NOINTERFACE;
     }
 
-    IUnknown_AddRef((IUnknown*)*ppv);
+    IImageList2_AddRef(iface);
     return S_OK;
 }
 
-static ULONG WINAPI ImageListImpl_AddRef(IImageList *iface)
+static ULONG WINAPI ImageListImpl_AddRef(IImageList2 *iface)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
-    ULONG ref = InterlockedIncrement(&This->ref);
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    ULONG ref = InterlockedIncrement(&imgl->ref);
 
     TRACE("(%p) refcount=%u\n", iface, ref);
     return ref;
 }
 
-static ULONG WINAPI ImageListImpl_Release(IImageList *iface)
+static ULONG WINAPI ImageListImpl_Release(IImageList2 *iface)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST This = impl_from_IImageList2(iface);
     ULONG ref = InterlockedDecrement(&This->ref);
 
     TRACE("(%p) refcount=%u\n", iface, ref);
@@ -3233,7 +3248,7 @@ static ULONG WINAPI ImageListImpl_Release(IImageList *iface)
         if (This->hbrBlend25) DeleteObject (This->hbrBlend25);
         if (This->hbrBlend50) DeleteObject (This->hbrBlend50);
 
-        This->lpVtbl = NULL;
+        This->IImageList2_iface.lpVtbl = NULL;
         HeapFree(GetProcessHeap(), 0, This->has_alpha);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -3241,16 +3256,16 @@ static ULONG WINAPI ImageListImpl_Release(IImageList *iface)
     return ref;
 }
 
-static HRESULT WINAPI ImageListImpl_Add(IImageList *iface, HBITMAP hbmImage,
+static HRESULT WINAPI ImageListImpl_Add(IImageList2 *iface, HBITMAP hbmImage,
     HBITMAP hbmMask, int *pi)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     int ret;
 
     if (!pi)
         return E_FAIL;
 
-    ret = ImageList_Add(This, hbmImage, hbmMask);
+    ret = ImageList_Add(imgl, hbmImage, hbmMask);
 
     if (ret == -1)
         return E_FAIL;
@@ -3259,16 +3274,16 @@ static HRESULT WINAPI ImageListImpl_Add(IImageList *iface, HBITMAP hbmImage,
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_ReplaceIcon(IImageList *iface, int i,
+static HRESULT WINAPI ImageListImpl_ReplaceIcon(IImageList2 *iface, int i,
     HICON hicon, int *pi)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     int ret;
 
     if (!pi)
         return E_FAIL;
 
-    ret = ImageList_ReplaceIcon(This, i, hicon);
+    ret = ImageList_ReplaceIcon(imgl, i, hicon);
 
     if (ret == -1)
         return E_FAIL;
@@ -3277,30 +3292,30 @@ static HRESULT WINAPI ImageListImpl_ReplaceIcon(IImageList *iface, int i,
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_SetOverlayImage(IImageList *iface,
+static HRESULT WINAPI ImageListImpl_SetOverlayImage(IImageList2 *iface,
     int iImage, int iOverlay)
 {
-    return ImageList_SetOverlayImage((HIMAGELIST) iface, iImage, iOverlay)
-        ? S_OK : E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_SetOverlayImage(imgl, iImage, iOverlay) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_Replace(IImageList *iface, int i,
+static HRESULT WINAPI ImageListImpl_Replace(IImageList2 *iface, int i,
     HBITMAP hbmImage, HBITMAP hbmMask)
 {
-    return ImageList_Replace((HIMAGELIST) iface, i, hbmImage, hbmMask) ? S_OK :
-        E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_Replace(imgl, i, hbmImage, hbmMask) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_AddMasked(IImageList *iface, HBITMAP hbmImage,
+static HRESULT WINAPI ImageListImpl_AddMasked(IImageList2 *iface, HBITMAP hbmImage,
     COLORREF crMask, int *pi)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     int ret;
 
     if (!pi)
         return E_FAIL;
 
-    ret = ImageList_AddMasked(This, hbmImage, crMask);
+    ret = ImageList_AddMasked(imgl, hbmImage, crMask);
 
     if (ret == -1)
         return E_FAIL;
@@ -3309,17 +3324,17 @@ static HRESULT WINAPI ImageListImpl_AddMasked(IImageList *iface, HBITMAP hbmImag
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_Draw(IImageList *iface,
+static HRESULT WINAPI ImageListImpl_Draw(IImageList2 *iface,
     IMAGELISTDRAWPARAMS *pimldp)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     HIMAGELIST old_himl;
     int ret;
 
     /* As far as I can tell, Windows simply ignores the contents of pimldp->himl
        so we shall simulate the same */
     old_himl = pimldp->himl;
-    pimldp->himl = This;
+    pimldp->himl = imgl;
 
     ret = ImageList_DrawIndirect(pimldp);
 
@@ -3327,20 +3342,22 @@ static HRESULT WINAPI ImageListImpl_Draw(IImageList *iface,
     return ret ? S_OK : E_INVALIDARG;
 }
 
-static HRESULT WINAPI ImageListImpl_Remove(IImageList *iface, int i)
+static HRESULT WINAPI ImageListImpl_Remove(IImageList2 *iface, int i)
 {
-    return (ImageList_Remove((HIMAGELIST) iface, i) == 0) ? E_INVALIDARG : S_OK;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return (ImageList_Remove(imgl, i) == 0) ? E_INVALIDARG : S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_GetIcon(IImageList *iface, int i, UINT flags,
+static HRESULT WINAPI ImageListImpl_GetIcon(IImageList2 *iface, int i, UINT flags,
     HICON *picon)
 {
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     HICON hIcon;
 
     if (!picon)
         return E_FAIL;
 
-    hIcon = ImageList_GetIcon((HIMAGELIST) iface, i, flags);
+    hIcon = ImageList_GetIcon(imgl, i, flags);
 
     if (hIcon == NULL)
         return E_FAIL;
@@ -3349,28 +3366,29 @@ static HRESULT WINAPI ImageListImpl_GetIcon(IImageList *iface, int i, UINT flags
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_GetImageInfo(IImageList *iface, int i,
+static HRESULT WINAPI ImageListImpl_GetImageInfo(IImageList2 *iface, int i,
     IMAGEINFO *pImageInfo)
 {
-    return ImageList_GetImageInfo((HIMAGELIST) iface, i, pImageInfo) ? S_OK : E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_GetImageInfo(imgl, i, pImageInfo) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_Copy(IImageList *iface, int iDst,
-    IUnknown *punkSrc, int iSrc, UINT uFlags)
+static HRESULT WINAPI ImageListImpl_Copy(IImageList2 *iface, int dst_index,
+    IUnknown *unk_src, int src_index, UINT flags)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     IImageList *src = NULL;
     HRESULT ret;
 
-    if (!punkSrc)
+    if (!unk_src)
         return E_FAIL;
 
     /* TODO: Add test for IID_ImageList2 too */
-    if (FAILED(IUnknown_QueryInterface(punkSrc, &IID_IImageList,
+    if (FAILED(IUnknown_QueryInterface(unk_src, &IID_IImageList,
             (void **) &src)))
         return E_FAIL;
 
-    if (ImageList_Copy(This, iDst, (HIMAGELIST) src, iSrc, uFlags))
+    if (ImageList_Copy(imgl, dst_index, (HIMAGELIST) src, src_index, flags))
         ret = S_OK;
     else
         ret = E_FAIL;
@@ -3379,12 +3397,12 @@ static HRESULT WINAPI ImageListImpl_Copy(IImageList *iface, int iDst,
     return ret;
 }
 
-static HRESULT WINAPI ImageListImpl_Merge(IImageList *iface, int i1,
+static HRESULT WINAPI ImageListImpl_Merge(IImageList2 *iface, int i1,
     IUnknown *punk2, int i2, int dx, int dy, REFIID riid, void **ppv)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     IImageList *iml2 = NULL;
-    HIMAGELIST hNew;
+    HIMAGELIST merged;
     HRESULT ret = E_FAIL;
 
     TRACE("(%p)->(%d %p %d %d %d %s %p)\n", iface, i1, punk2, i2, dx, dy, debugstr_guid(riid), ppv);
@@ -3394,126 +3412,126 @@ static HRESULT WINAPI ImageListImpl_Merge(IImageList *iface, int i1,
             (void **) &iml2)))
         return E_FAIL;
 
-    hNew = ImageList_Merge(This, i1, (HIMAGELIST) iml2, i2, dx, dy);
+    merged = ImageList_Merge(imgl, i1, (HIMAGELIST) iml2, i2, dx, dy);
 
     /* Get the interface for the new image list */
-    if (hNew)
+    if (merged)
     {
-        IImageList *imerge = (IImageList*)hNew;
-
-        ret = HIMAGELIST_QueryInterface(hNew, riid, ppv);
-        IImageList_Release(imerge);
+        ret = HIMAGELIST_QueryInterface(merged, riid, ppv);
+        ImageList_Destroy(merged);
     }
 
     IImageList_Release(iml2);
     return ret;
 }
 
-static HRESULT WINAPI ImageListImpl_Clone(IImageList *iface, REFIID riid, void **ppv)
+static HRESULT WINAPI ImageListImpl_Clone(IImageList2 *iface, REFIID riid, void **ppv)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     HIMAGELIST clone;
     HRESULT ret = E_FAIL;
 
     TRACE("(%p)->(%s %p)\n", iface, debugstr_guid(riid), ppv);
 
-    clone = ImageList_Duplicate(This);
+    clone = ImageList_Duplicate(imgl);
 
     /* Get the interface for the new image list */
     if (clone)
     {
-        IImageList *iclone = (IImageList*)clone;
-
         ret = HIMAGELIST_QueryInterface(clone, riid, ppv);
-        IImageList_Release(iclone);
+        ImageList_Destroy(clone);
     }
 
     return ret;
 }
 
-static HRESULT WINAPI ImageListImpl_GetImageRect(IImageList *iface, int i,
+static HRESULT WINAPI ImageListImpl_GetImageRect(IImageList2 *iface, int i,
     RECT *prc)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
     IMAGEINFO info;
 
     if (!prc)
         return E_FAIL;
 
-    if (!ImageList_GetImageInfo(This, i, &info))
+    if (!ImageList_GetImageInfo(imgl, i, &info))
         return E_FAIL;
 
     return CopyRect(prc, &info.rcImage) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_GetIconSize(IImageList *iface, int *cx,
+static HRESULT WINAPI ImageListImpl_GetIconSize(IImageList2 *iface, int *cx,
     int *cy)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
-
-    return ImageList_GetIconSize(This, cx, cy) ? S_OK : E_INVALIDARG;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_GetIconSize(imgl, cx, cy) ? S_OK : E_INVALIDARG;
 }
 
-static HRESULT WINAPI ImageListImpl_SetIconSize(IImageList *iface, int cx,
+static HRESULT WINAPI ImageListImpl_SetIconSize(IImageList2 *iface, int cx,
     int cy)
 {
-    return ImageList_SetIconSize((HIMAGELIST) iface, cx, cy) ? S_OK : E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_SetIconSize(imgl, cx, cy) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_GetImageCount(IImageList *iface, int *pi)
+static HRESULT WINAPI ImageListImpl_GetImageCount(IImageList2 *iface, int *pi)
 {
-    *pi = ImageList_GetImageCount((HIMAGELIST) iface);
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    *pi = ImageList_GetImageCount(imgl);
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_SetImageCount(IImageList *iface,
-    UINT uNewCount)
+static HRESULT WINAPI ImageListImpl_SetImageCount(IImageList2 *iface, UINT count)
 {
-    return ImageList_SetImageCount((HIMAGELIST) iface, uNewCount) ? S_OK : E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_SetImageCount(imgl, count) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_SetBkColor(IImageList *iface, COLORREF clrBk,
+static HRESULT WINAPI ImageListImpl_SetBkColor(IImageList2 *iface, COLORREF clrBk,
     COLORREF *pclr)
 {
-    *pclr = ImageList_SetBkColor((HIMAGELIST) iface, clrBk);
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    *pclr = ImageList_SetBkColor(imgl, clrBk);
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_GetBkColor(IImageList *iface, COLORREF *pclr)
+static HRESULT WINAPI ImageListImpl_GetBkColor(IImageList2 *iface, COLORREF *pclr)
 {
-    *pclr = ImageList_GetBkColor((HIMAGELIST) iface);
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    *pclr = ImageList_GetBkColor(imgl);
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_BeginDrag(IImageList *iface, int iTrack,
+static HRESULT WINAPI ImageListImpl_BeginDrag(IImageList2 *iface, int iTrack,
     int dxHotspot, int dyHotspot)
 {
-    return ImageList_BeginDrag((HIMAGELIST) iface, iTrack, dxHotspot, dyHotspot) ? S_OK : E_FAIL;
+    HIMAGELIST imgl = impl_from_IImageList2(iface);
+    return ImageList_BeginDrag(imgl, iTrack, dxHotspot, dyHotspot) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_EndDrag(IImageList *iface)
+static HRESULT WINAPI ImageListImpl_EndDrag(IImageList2 *iface)
 {
     ImageList_EndDrag();
     return S_OK;
 }
 
-static HRESULT WINAPI ImageListImpl_DragEnter(IImageList *iface, HWND hwndLock,
+static HRESULT WINAPI ImageListImpl_DragEnter(IImageList2 *iface, HWND hwndLock,
     int x, int y)
 {
     return ImageList_DragEnter(hwndLock, x, y) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_DragLeave(IImageList *iface, HWND hwndLock)
+static HRESULT WINAPI ImageListImpl_DragLeave(IImageList2 *iface, HWND hwndLock)
 {
     return ImageList_DragLeave(hwndLock) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_DragMove(IImageList *iface, int x, int y)
+static HRESULT WINAPI ImageListImpl_DragMove(IImageList2 *iface, int x, int y)
 {
     return ImageList_DragMove(x, y) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_SetDragCursorImage(IImageList *iface,
+static HRESULT WINAPI ImageListImpl_SetDragCursorImage(IImageList2 *iface,
     IUnknown *punk, int iDrag, int dxHotspot, int dyHotspot)
 {
     IImageList *iml2 = NULL;
@@ -3535,12 +3553,12 @@ static HRESULT WINAPI ImageListImpl_SetDragCursorImage(IImageList *iface,
     return ret ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_DragShowNolock(IImageList *iface, BOOL fShow)
+static HRESULT WINAPI ImageListImpl_DragShowNolock(IImageList2 *iface, BOOL fShow)
 {
     return ImageList_DragShowNolock(fShow) ? S_OK : E_FAIL;
 }
 
-static HRESULT WINAPI ImageListImpl_GetDragImage(IImageList *iface, POINT *ppt,
+static HRESULT WINAPI ImageListImpl_GetDragImage(IImageList2 *iface, POINT *ppt,
     POINT *pptHotspot, REFIID riid, PVOID *ppv)
 {
     HRESULT ret = E_FAIL;
@@ -3563,17 +3581,17 @@ static HRESULT WINAPI ImageListImpl_GetDragImage(IImageList *iface, POINT *ppt,
     return ret;
 }
 
-static HRESULT WINAPI ImageListImpl_GetItemFlags(IImageList *iface, int i,
+static HRESULT WINAPI ImageListImpl_GetItemFlags(IImageList2 *iface, int i,
     DWORD *dwFlags)
 {
     FIXME("STUB: %p %d %p\n", iface, i, dwFlags);
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI ImageListImpl_GetOverlayImage(IImageList *iface, int iOverlay,
+static HRESULT WINAPI ImageListImpl_GetOverlayImage(IImageList2 *iface, int iOverlay,
     int *piIndex)
 {
-    HIMAGELIST This = (HIMAGELIST) iface;
+    HIMAGELIST This = impl_from_IImageList2(iface);
     int i;
 
     if ((iOverlay < 0) || (iOverlay > This->cCurImage))
@@ -3591,8 +3609,80 @@ static HRESULT WINAPI ImageListImpl_GetOverlayImage(IImageList *iface, int iOver
     return E_FAIL;
 }
 
+static HRESULT WINAPI ImageListImpl_Resize(IImageList2 *iface, INT cx, INT cy)
+{
+    FIXME("(%p)->(%d %d): stub\n", iface, cx, cy);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_GetOriginalSize(IImageList2 *iface, INT image, DWORD flags, INT *cx, INT *cy)
+{
+    FIXME("(%p)->(%d %x %p %p): stub\n", iface, image, flags, cx, cy);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_SetOriginalSize(IImageList2 *iface, INT image, INT cx, INT cy)
+{
+    FIXME("(%p)->(%d %d %d): stub\n", iface, image, cx, cy);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_SetCallback(IImageList2 *iface, IUnknown *callback)
+{
+    FIXME("(%p)->(%p): stub\n", iface, callback);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_GetCallback(IImageList2 *iface, REFIID riid, void **ppv)
+{
+    FIXME("(%p)->(%s %p): stub\n", iface, debugstr_guid(riid), ppv);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_ForceImagePresent(IImageList2 *iface, INT image, DWORD flags)
+{
+    FIXME("(%p)->(%d %x): stub\n", iface, image, flags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_DiscardImages(IImageList2 *iface, INT first_image, INT last_image, DWORD flags)
+{
+    FIXME("(%p)->(%d %d %x): stub\n", iface, first_image, last_image, flags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_PreloadImages(IImageList2 *iface, IMAGELISTDRAWPARAMS *params)
+{
+    FIXME("(%p)->(%p): stub\n", iface, params);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_GetStatistics(IImageList2 *iface, IMAGELISTSTATS *stats)
+{
+    FIXME("(%p)->(%p): stub\n", iface, stats);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_Initialize(IImageList2 *iface, INT cx, INT cy, UINT flags, INT initial, INT grow)
+{
+    FIXME("(%p)->(%d %d %d %d %d): stub\n", iface, cx, cy, flags, initial, grow);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_Replace2(IImageList2 *iface, INT i, HBITMAP image, HBITMAP mask, IUnknown *unk, DWORD flags)
+{
+    FIXME("(%p)->(%d %p %p %p %x): stub\n", iface, i, image, mask, unk, flags);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ImageListImpl_ReplaceFromImageList(IImageList2 *iface, INT i, IImageList *imagelist, INT src,
+    IUnknown *unk, DWORD flags)
+{
+    FIXME("(%p)->(%d %p %d %p %x): stub\n", iface, i, imagelist, src, unk, flags);
+    return E_NOTIMPL;
+}
 
-static const IImageListVtbl ImageListImpl_Vtbl = {
+static const IImageList2Vtbl ImageListImpl_Vtbl = {
     ImageListImpl_QueryInterface,
     ImageListImpl_AddRef,
     ImageListImpl_Release,
@@ -3624,7 +3714,19 @@ static const IImageListVtbl ImageListImpl_Vtbl = {
     ImageListImpl_DragShowNolock,
     ImageListImpl_GetDragImage,
     ImageListImpl_GetItemFlags,
-    ImageListImpl_GetOverlayImage
+    ImageListImpl_GetOverlayImage,
+    ImageListImpl_Resize,
+    ImageListImpl_GetOriginalSize,
+    ImageListImpl_SetOriginalSize,
+    ImageListImpl_SetCallback,
+    ImageListImpl_GetCallback,
+    ImageListImpl_ForceImagePresent,
+    ImageListImpl_DiscardImages,
+    ImageListImpl_PreloadImages,
+    ImageListImpl_GetStatistics,
+    ImageListImpl_Initialize,
+    ImageListImpl_Replace2,
+    ImageListImpl_ReplaceFromImageList
 };
 
 static BOOL is_valid(HIMAGELIST himl)
@@ -3632,7 +3734,7 @@ static BOOL is_valid(HIMAGELIST himl)
     BOOL valid;
     __TRY
     {
-        valid = himl && himl->lpVtbl == &ImageListImpl_Vtbl;
+        valid = himl && himl->IImageList2_iface.lpVtbl == &ImageListImpl_Vtbl;
     }
     __EXCEPT_PAGE_FAULT
     {
@@ -3661,7 +3763,7 @@ HRESULT WINAPI
 HIMAGELIST_QueryInterface (HIMAGELIST himl, REFIID riid, void **ppv)
 {
     TRACE("(%p,%s,%p)\n", himl, debugstr_guid(riid), ppv);
-    return IImageList_QueryInterface((IImageList *) himl, riid, ppv);
+    return IImageList2_QueryInterface((IImageList2 *) himl, riid, ppv);
 }
 
 static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID iid, void** ppv)
@@ -3678,11 +3780,11 @@ static HRESULT ImageListImpl_CreateInstance(const IUnknown *pUnkOuter, REFIID ii
     This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct _IMAGELIST));
     if (!This) return E_OUTOFMEMORY;
 
-    This->lpVtbl = &ImageListImpl_Vtbl;
+    This->IImageList2_iface.lpVtbl = &ImageListImpl_Vtbl;
     This->ref = 1;
 
-    ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv);
-    IUnknown_Release((IUnknown*)This);
+    ret = IImageList2_QueryInterface(&This->IImageList2_iface, iid, ppv);
+    IImageList2_Release(&This->IImageList2_iface);
 
     return ret;
 }
index 199626b..73d0fb5 100644 (file)
@@ -6,7 +6,7 @@
  * Copyright 2000 Jason Mawdsley
  * Copyright 2001 CodeWeavers Inc.
  * Copyright 2002 Dimitrie O. Paun
- * Copyright 2009-2013 Nikolay Sivov
+ * Copyright 2009-2014 Nikolay Sivov
  * Copyright 2009 Owen Rudge for CodeWeavers
  * Copyright 2012-2013 Daniel Jelinski
  *
@@ -313,7 +313,6 @@ typedef struct tagLISTVIEW_INFO
   WCHAR szSearchParam[ MAX_PATH ];
 
   /* painting */
-  DWORD cditemmode;        /* Keep the custom draw flags for an item/row */
   BOOL bIsDrawing;         /* Drawing in progress */
   INT nMeasureItemHeight;  /* WM_MEASUREITEM result */
   BOOL bRedraw;            /* WM_SETREDRAW switch */
@@ -767,6 +766,7 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, NMHEADERW *lp
         if (lpnmh->pitem->mask & HDI_TEXT)
         {
             text = (LPCWSTR)lpnmh->pitem->pszText;
+            lpnmh->pitem->pszText = NULL;
             Str_SetPtrWtoA(&lpnmh->pitem->pszText, text);
         }
         /* convert filter text */
@@ -774,6 +774,7 @@ static LRESULT notify_forward_header(const LISTVIEW_INFO *infoPtr, NMHEADERW *lp
              lpnmh->pitem->pvFilter)
         {
             filter = (LPCWSTR)((HD_TEXTFILTERA*)lpnmh->pitem->pvFilter)->pszText;
+            ((HD_TEXTFILTERA*)lpnmh->pitem->pvFilter)->pszText = NULL;
             Str_SetPtrWtoA(&((HD_TEXTFILTERA*)lpnmh->pitem->pvFilter)->pszText, filter);
         }
     }
@@ -1034,10 +1035,7 @@ static inline DWORD notify_customdraw (const LISTVIEW_INFO *infoPtr, DWORD dwDra
 
 static void prepaint_setup (const LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRAW *lpnmlvcd, BOOL SubItem)
 {
-    if (lpnmlvcd->clrTextBk == CLR_DEFAULT)
-        lpnmlvcd->clrTextBk = comctl32_color.clrWindow;
-    if (lpnmlvcd->clrText == CLR_DEFAULT)
-        lpnmlvcd->clrText = comctl32_color.clrWindowText;
+    COLORREF backcolor, textcolor;
 
     /* apparently, for selected items, we have to override the returned values */
     if (!SubItem)
@@ -1057,15 +1055,23 @@ static void prepaint_setup (const LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRA
         }
     }
 
+    backcolor = lpnmlvcd->clrTextBk;
+    textcolor = lpnmlvcd->clrText;
+
+    if (backcolor == CLR_DEFAULT)
+        backcolor = comctl32_color.clrWindow;
+    if (textcolor == CLR_DEFAULT)
+        textcolor = comctl32_color.clrWindowText;
+
     /* Set the text attributes */
-    if (lpnmlvcd->clrTextBk != CLR_NONE)
+    if (backcolor != CLR_NONE)
     {
        SetBkMode(hdc, OPAQUE);
-       SetBkColor(hdc,lpnmlvcd->clrTextBk);
+       SetBkColor(hdc, backcolor);
     }
     else
        SetBkMode(hdc, TRANSPARENT);
-    SetTextColor(hdc, lpnmlvcd->clrText);
+    SetTextColor(hdc, textcolor);
 }
 
 static inline DWORD notify_postpaint (const LISTVIEW_INFO *infoPtr, NMLVCUSTOMDRAW *lpnmlvcd)
@@ -4536,87 +4542,28 @@ static inline BOOL LISTVIEW_FillBkgnd(const LISTVIEW_INFO *infoPtr, HDC hdc, con
     return FillRect(hdc, lprcBox, infoPtr->hBkBrush);
 }
 
-/***
- * DESCRIPTION:
- * Draws an item.
- *
- * PARAMETER(S):
- * [I] infoPtr : valid pointer to the listview structure
- * [I] hdc : device context handle
- * [I] nItem : item index
- * [I] nSubItem : subitem index
- * [I] pos : item position in client coordinates
- * [I] cdmode : custom draw mode
- *
- * RETURN:
- *   Success: TRUE
- *   Failure: FALSE
- */
-static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nSubItem, POINT pos, DWORD cdmode)
+/* Draw main item or subitem */
+static void LISTVIEW_DrawItemPart(LISTVIEW_INFO *infoPtr, LVITEMW *item, const NMLVCUSTOMDRAW *nmlvcd, const POINT *pos)
 {
-    UINT uFormat;
-    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
-    static WCHAR szCallback[] = { '(', 'c', 'a', 'l', 'l', 'b', 'a', 'c', 'k', ')', 0 };
-    DWORD cdsubitemmode = CDRF_DODEFAULT;
-    LPRECT lprcFocus;
-    RECT rcSelect, rcBox, rcIcon, rcLabel, rcStateIcon;
-    NMLVCUSTOMDRAW nmlvcd;
+    RECT rcSelect, rcLabel, rcBox, rcStateIcon, rcIcon;
     HIMAGELIST himl;
-    LVITEMW lvItem;
-
-    TRACE("(hdc=%p, nItem=%d, nSubItem=%d, pos=%s)\n", hdc, nItem, nSubItem, wine_dbgstr_point(&pos));
-
-    /* get information needed for drawing the item */
-    lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
-    if (nSubItem == 0) lvItem.mask |= LVIF_STATE;
-    if (infoPtr->uView == LV_VIEW_DETAILS) lvItem.mask |= LVIF_INDENT;
-    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT | LVIS_OVERLAYMASK;
-    lvItem.iItem = nItem;
-    lvItem.iSubItem = nSubItem;
-    lvItem.state = 0;
-    lvItem.lParam = 0;
-    lvItem.cchTextMax = DISP_TEXT_SIZE;
-    lvItem.pszText = szDispText;
-    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
-    if (nSubItem > 0 && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 
-       lvItem.state = LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED);
-    if (lvItem.pszText == LPSTR_TEXTCALLBACKW) lvItem.pszText = szCallback;
-    TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
+    UINT format;
+    RECT *focus;
 
     /* now check if we need to update the focus rectangle */
-    lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
-
-    if (!lprcFocus) lvItem.state &= ~LVIS_FOCUSED;
-    LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcSelect, &rcIcon, &rcStateIcon, &rcLabel);
-    OffsetRect(&rcBox, pos.x, pos.y);
-    OffsetRect(&rcSelect, pos.x, pos.y);
-    OffsetRect(&rcIcon, pos.x, pos.y);
-    OffsetRect(&rcStateIcon, pos.x, pos.y);
-    OffsetRect(&rcLabel, pos.x, pos.y);
+    focus = infoPtr->bFocus && (item->state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
+    if (!focus) item->state &= ~LVIS_FOCUSED;
+
+    LISTVIEW_GetItemMetrics(infoPtr, item, &rcBox, &rcSelect, &rcIcon, &rcStateIcon, &rcLabel);
+    OffsetRect(&rcBox, pos->x, pos->y);
+    OffsetRect(&rcSelect, pos->x, pos->y);
+    OffsetRect(&rcIcon, pos->x, pos->y);
+    OffsetRect(&rcStateIcon, pos->x, pos->y);
+    OffsetRect(&rcLabel, pos->x, pos->y);
     TRACE("    rcBox=%s, rcSelect=%s, rcIcon=%s. rcLabel=%s\n",
         wine_dbgstr_rect(&rcBox), wine_dbgstr_rect(&rcSelect),
         wine_dbgstr_rect(&rcIcon), wine_dbgstr_rect(&rcLabel));
 
-    /* fill in the custom draw structure */
-    customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox, &lvItem);
-
-    if (nSubItem > 0) cdmode = infoPtr->cditemmode;
-    if (cdmode & CDRF_SKIPDEFAULT) goto postpaint;
-    if (cdmode & CDRF_NOTIFYITEMDRAW)
-        cdsubitemmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
-    if (nSubItem == 0) infoPtr->cditemmode = cdsubitemmode;
-    if (cdsubitemmode & CDRF_SKIPDEFAULT) goto postpaint;
-    /* we have to send a CDDS_SUBITEM customdraw explicitly for subitem 0 */
-    if (nSubItem == 0 && (cdsubitemmode & CDRF_NOTIFYITEMDRAW) != 0)
-    {
-        cdsubitemmode = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPREPAINT, &nmlvcd);
-        if (cdsubitemmode & CDRF_SKIPDEFAULT) goto postpaint;
-    }
-    if (nSubItem == 0 || (cdmode & CDRF_NOTIFYITEMDRAW))
-        prepaint_setup(infoPtr, hdc, &nmlvcd, FALSE);
-    else if ((infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) == FALSE)
-        prepaint_setup(infoPtr, hdc, &nmlvcd, TRUE);
-
     /* FIXME: temporary hack */
     rcSelect.left = rcLabel.left;
 
@@ -4625,16 +4572,15 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
     /* in detail mode, we want to paint background for label rect when
      * item is not selected or listview has full row select; otherwise paint
      * background for text only */
-    if (infoPtr->uView == LV_VIEW_ICON ||
-        (infoPtr->uView == LV_VIEW_DETAILS &&
-        (!(lvItem.state & LVIS_SELECTED) ||
-        (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT) != 0)))
+    if ( infoPtr->uView == LV_VIEW_ICON ||
+        (infoPtr->uView == LV_VIEW_DETAILS && (!(item->state & LVIS_SELECTED) ||
+        (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))))
         rcSelect = rcLabel;
 
-    if (nmlvcd.clrTextBk != CLR_NONE)
-        ExtTextOutW(hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, NULL, 0, NULL);
+    if (nmlvcd->clrTextBk != CLR_NONE)
+        ExtTextOutW(nmlvcd->nmcd.hdc, rcSelect.left, rcSelect.top, ETO_OPAQUE, &rcSelect, NULL, 0, NULL);
 
-    if(nSubItem == 0 && infoPtr->nFocusedItem == nItem)
+    if (item->state & LVIS_FOCUSED)
     {
        if (infoPtr->uView == LV_VIEW_DETAILS && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
        {
@@ -4646,7 +4592,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
 
                if ((leftmost = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX, 0, 0)))
                {
-                   INT Originx = pos.x - LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left;
+                   INT Originx = pos->x - LISTVIEW_GetColumnInfo(infoPtr, 0)->rcHeader.left;
                    INT index = SendMessageW(infoPtr->hwndHeader, HDM_ORDERTOINDEX,
                                DPA_GetPtrCount(infoPtr->hdpaColumns) - 1, 0);
 
@@ -4663,73 +4609,201 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
     }
 
     /* state icons */
-    if (infoPtr->himlState && STATEIMAGEINDEX(lvItem.state) && (nSubItem == 0))
+    if (infoPtr->himlState && STATEIMAGEINDEX(item->state) && (item->iSubItem == 0))
     {
-        UINT uStateImage = STATEIMAGEINDEX(lvItem.state);
-        if (uStateImage)
+        UINT stateimage = STATEIMAGEINDEX(item->state);
+        if (stateimage)
        {
-            TRACE("uStateImage=%d\n", uStateImage);
-            ImageList_Draw(infoPtr->himlState, uStateImage - 1, hdc,
-                rcStateIcon.left, rcStateIcon.top, ILD_NORMAL);
+            TRACE("stateimage=%d\n", stateimage);
+            ImageList_Draw(infoPtr->himlState, stateimage-1, nmlvcd->nmcd.hdc, rcStateIcon.left, rcStateIcon.top, ILD_NORMAL);
        }
     }
 
     /* item icons */
     himl = (infoPtr->uView == LV_VIEW_ICON ? infoPtr->himlNormal : infoPtr->himlSmall);
-    if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon))
+    if (himl && item->iImage >= 0 && !IsRectEmpty(&rcIcon))
     {
         UINT style;
 
-        TRACE("iImage=%d\n", lvItem.iImage);
+        TRACE("iImage=%d\n", item->iImage);
 
-        if (lvItem.state & (LVIS_SELECTED | LVIS_CUT) && infoPtr->bFocus)
+        if (item->state & (LVIS_SELECTED | LVIS_CUT) && infoPtr->bFocus)
             style = ILD_SELECTED;
         else
             style = ILD_NORMAL;
 
-        ImageList_DrawEx(himl, lvItem.iImage, hdc, rcIcon.left, rcIcon.top,
+        ImageList_DrawEx(himl, item->iImage, nmlvcd->nmcd.hdc, rcIcon.left, rcIcon.top,
                          rcIcon.right - rcIcon.left, rcIcon.bottom - rcIcon.top, infoPtr->clrBk,
-                         lvItem.state & LVIS_CUT ? RGB(255, 255, 255) : CLR_DEFAULT,
-                         style | (lvItem.state & LVIS_OVERLAYMASK));
+                         item->state & LVIS_CUT ? RGB(255, 255, 255) : CLR_DEFAULT,
+                         style | (item->state & LVIS_OVERLAYMASK));
     }
 
     /* Don't bother painting item being edited */
-    if (infoPtr->hwndEdit && nItem == infoPtr->nEditLabelItem && nSubItem == 0) goto postpaint;
-   
+    if (infoPtr->hwndEdit && item->iItem == infoPtr->nEditLabelItem && item->iSubItem == 0) return;
+
     /* figure out the text drawing flags */
-    uFormat = (infoPtr->uView == LV_VIEW_ICON ? (lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS) : LV_SL_DT_FLAGS);
+    format = (infoPtr->uView == LV_VIEW_ICON ? (focus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS) : LV_SL_DT_FLAGS);
     if (infoPtr->uView == LV_VIEW_ICON)
-       uFormat = (lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS);
-    else if (nSubItem)
+       format = (focus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS);
+    else if (item->iSubItem)
     {
-       switch (LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->fmt & LVCFMT_JUSTIFYMASK)
+       switch (LISTVIEW_GetColumnInfo(infoPtr, item->iSubItem)->fmt & LVCFMT_JUSTIFYMASK)
        {
-       case LVCFMT_RIGHT:  uFormat |= DT_RIGHT;  break;
-       case LVCFMT_CENTER: uFormat |= DT_CENTER; break;
-       default:            uFormat |= DT_LEFT;
+       case LVCFMT_RIGHT:  format |= DT_RIGHT;  break;
+       case LVCFMT_CENTER: format |= DT_CENTER; break;
+       default:            format |= DT_LEFT;
        }
     }
-    if (!(uFormat & (DT_RIGHT | DT_CENTER)))
+    if (!(format & (DT_RIGHT | DT_CENTER)))
     {
-        if (himl && lvItem.iImage >= 0 && !IsRectEmpty(&rcIcon)) rcLabel.left += IMAGE_PADDING;
+        if (himl && item->iImage >= 0 && !IsRectEmpty(&rcIcon)) rcLabel.left += IMAGE_PADDING;
         else rcLabel.left += LABEL_HOR_PADDING;
     }
-    else if (uFormat & DT_RIGHT) rcLabel.right -= LABEL_HOR_PADDING;
+    else if (format & DT_RIGHT) rcLabel.right -= LABEL_HOR_PADDING;
 
     /* for GRIDLINES reduce the bottom so the text formats correctly */
     if (infoPtr->uView == LV_VIEW_DETAILS && infoPtr->dwLvExStyle & LVS_EX_GRIDLINES)
         rcLabel.bottom--;
 
 #ifdef __REACTOS__
-    if ((!(lvItem.state & LVIS_SELECTED) || !infoPtr->bFocus) && (infoPtr->dwLvExStyle & LVS_EX_TRANSPARENTSHADOWTEXT))
-        DrawShadowText(hdc, lvItem.pszText, -1, &rcLabel, uFormat, RGB(255, 255, 255), RGB(0, 0, 0), 2, 2);
+    if ((!(item->state & LVIS_SELECTED) || !infoPtr->bFocus) && (infoPtr->dwLvExStyle & LVS_EX_TRANSPARENTSHADOWTEXT))
+        DrawShadowText(nmlvcd->nmcd.hdc, item->pszText, -1, &rcLabel, format, RGB(255, 255, 255), RGB(0, 0, 0), 2, 2);
     else
 #endif
-        DrawTextW(hdc, lvItem.pszText, -1, &rcLabel, uFormat);
+        DrawTextW(nmlvcd->nmcd.hdc, item->pszText, -1, &rcLabel, format);
+}
+
+/***
+ * DESCRIPTION:
+ * Draws an item.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] hdc : device context handle
+ * [I] nItem : item index
+ * [I] nSubItem : subitem index
+ * [I] pos : item position in client coordinates
+ * [I] cdmode : custom draw mode
+ *
+ * RETURN:
+ *   Success: TRUE
+ *   Failure: FALSE
+ */
+static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERATOR *subitems, POINT pos, DWORD cdmode)
+{
+    WCHAR szDispText[DISP_TEXT_SIZE] = { '\0' };
+    static WCHAR callbackW[] = { '(', 'c', 'a', 'l', 'l', 'b', 'a', 'c', 'k', ')', 0 };
+    DWORD cdsubitemmode = CDRF_DODEFAULT;
+    RECT *focus, rcBox;
+    NMLVCUSTOMDRAW nmlvcd;
+    LVITEMW lvItem;
+
+    TRACE("(hdc=%p, nItem=%d, subitems=%p, pos=%s)\n", hdc, nItem, subitems, wine_dbgstr_point(&pos));
+
+    /* get information needed for drawing the item */
+    lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
+    if (infoPtr->uView == LV_VIEW_DETAILS) lvItem.mask |= LVIF_INDENT;
+    lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT | LVIS_OVERLAYMASK;
+    lvItem.iItem = nItem;
+    lvItem.iSubItem = 0;
+    lvItem.state = 0;
+    lvItem.lParam = 0;
+    lvItem.cchTextMax = DISP_TEXT_SIZE;
+    lvItem.pszText = szDispText;
+    if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
+    if (lvItem.pszText == LPSTR_TEXTCALLBACKW) lvItem.pszText = callbackW;
+    TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
+
+    /* now check if we need to update the focus rectangle */
+    focus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0;
+    if (!focus) lvItem.state &= ~LVIS_FOCUSED;
+
+    LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, NULL, NULL, NULL, NULL);
+    OffsetRect(&rcBox, pos.x, pos.y);
+
+    /* Full custom draw stage sequence looks like this:
+
+       LV_VIEW_DETAILS:
+
+       - CDDS_ITEMPREPAINT
+       - CDDS_ITEMPREPAINT|CDDS_SUBITEM   | => sent n times, where n is number of subitems,
+         CDDS_ITEMPOSTPAINT|CDDS_SUBITEM  |    including item iself
+       - CDDS_ITEMPOSTPAINT
+
+       other styles:
+
+       - CDDS_ITEMPREPAINT
+       - CDDS_ITEMPOSTPAINT
+    */
+
+    /* fill in the custom draw structure */
+    customdraw_fill(&nmlvcd, infoPtr, hdc, &rcBox, &lvItem);
+    if (cdmode & CDRF_NOTIFYITEMDRAW)
+        cdsubitemmode = notify_customdraw(infoPtr, CDDS_ITEMPREPAINT, &nmlvcd);
+    if (cdsubitemmode & CDRF_SKIPDEFAULT) goto postpaint;
+
+    if (subitems)
+    {
+        while (iterator_next(subitems))
+        {
+            DWORD subitemstage = CDRF_DODEFAULT;
+
+            /* We need to query for each subitem, item's data (subitem == 0) is already here at this point */
+            if (subitems->nItem)
+            {
+                lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_INDENT;
+                lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT | LVIS_OVERLAYMASK;
+                lvItem.iItem = nItem;
+                lvItem.iSubItem = subitems->nItem;
+                lvItem.state = 0;
+                lvItem.lParam = 0;
+                lvItem.cchTextMax = DISP_TEXT_SIZE;
+                lvItem.pszText = szDispText;
+                if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE;
+                if (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)
+                   lvItem.state = LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED);
+                if (lvItem.pszText == LPSTR_TEXTCALLBACKW) lvItem.pszText = callbackW;
+                TRACE("   lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
+
+                /* update custom draw data */
+                LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &nmlvcd.nmcd.rc, NULL, NULL, NULL, NULL);
+                OffsetRect(&nmlvcd.nmcd.rc, pos.x, pos.y);
+                nmlvcd.iSubItem = subitems->nItem;
+            }
+
+            if (cdsubitemmode & CDRF_NOTIFYSUBITEMDRAW)
+                subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPREPAINT, &nmlvcd);
+            else
+            {
+                nmlvcd.clrTextBk = infoPtr->clrTextBk;
+                nmlvcd.clrText   = infoPtr->clrText;
+            }
+
+            if (subitems->nItem == 0 || (cdmode & CDRF_NOTIFYITEMDRAW))
+                prepaint_setup(infoPtr, hdc, &nmlvcd, FALSE);
+            else if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
+                prepaint_setup(infoPtr, hdc, &nmlvcd, TRUE);
+
+            if (!(subitemstage & CDRF_SKIPDEFAULT))
+                LISTVIEW_DrawItemPart(infoPtr, &lvItem, &nmlvcd, &pos);
+
+            if (subitemstage & CDRF_NOTIFYPOSTPAINT)
+                subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPOSTPAINT, &nmlvcd);
+        }
+    }
+    else
+    {
+        prepaint_setup(infoPtr, hdc, &nmlvcd, FALSE);
+        LISTVIEW_DrawItemPart(infoPtr, &lvItem, &nmlvcd, &pos);
+    }
 
 postpaint:
     if (cdsubitemmode & CDRF_NOTIFYPOSTPAINT)
-        notify_postpaint(infoPtr, &nmlvcd);
+    {
+        nmlvcd.iSubItem = 0;
+        notify_customdraw(infoPtr, CDDS_ITEMPOSTPAINT, &nmlvcd);
+    }
+
     return TRUE;
 }
 
@@ -4856,10 +4930,15 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
     /* iterate through the invalidated rows */
     while(iterator_next(i))
     {
+        RANGES subitems;
+        ITERATOR k;
+
         SelectObject(hdc, infoPtr->hFont);
        LISTVIEW_GetItemOrigin(infoPtr, i->nItem, &Position);
        Position.y += Origin.y;
 
+        subitems = ranges_create(DPA_GetPtrCount(infoPtr->hdpaColumns));
+
        /* iterate through the invalidated columns */
        while(iterator_next(&j))
        {
@@ -4874,8 +4953,12 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc,
                if (!RectVisible(hdc, &rcItem)) continue;
            }
 
-           LISTVIEW_DrawItem(infoPtr, hdc, i->nItem, j.nItem, Position, cdmode);
+            ranges_additem(subitems, j.nItem);
        }
+
+        iterator_rangesitems(&k, subitems);
+        LISTVIEW_DrawItem(infoPtr, hdc, i->nItem, &k, Position, cdmode);
+        iterator_destroy(&k);
     }
     iterator_destroy(&j);
 }
@@ -5009,7 +5092,7 @@ static void LISTVIEW_RefreshList(LISTVIEW_INFO *infoPtr, ITERATOR *i, HDC hdc, D
        Position.x += Origin.x;
        Position.y += Origin.y;
 
-        LISTVIEW_DrawItem(infoPtr, hdc, i->nItem, 0, Position, cdmode);
+        LISTVIEW_DrawItem(infoPtr, hdc, i->nItem, NULL, Position, cdmode);
     }
 }
 
@@ -5085,8 +5168,6 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc, const RECT *prcEra
                hdcOrig, infoPtr->rcList.left, infoPtr->rcList.top, SRCCOPY);
     }
 
-    infoPtr->cditemmode = CDRF_DODEFAULT;
-
     GetClientRect(infoPtr->hwndSelf, &rcClient);
     customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0);
     cdmode = notify_customdraw(infoPtr, CDDS_PREPAINT, &nmlvcd);
@@ -5352,7 +5433,7 @@ static HIMAGELIST LISTVIEW_CreateDragImage(LISTVIEW_INFO *infoPtr, INT iItem, LP
     FillRect(hdc, &rcItem, infoPtr->hBkBrush);
     
     pos.x = pos.y = 0;
-    if (LISTVIEW_DrawItem(infoPtr, hdc, iItem, 0, pos, infoPtr->cditemmode))
+    if (LISTVIEW_DrawItem(infoPtr, hdc, iItem, NULL, pos, CDRF_DODEFAULT))
     {
         dragList = ImageList_Create(size.cx, size.cy, ILC_COLOR, 10, 10);
         SelectObject(hdc, hOldbmp);
index 9a98de2..660e550 100644 (file)
@@ -744,7 +744,7 @@ static LRESULT
 PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
 {
     POINT clpt, pt;
-    RECT wnrect, *btnrect = NULL;
+    RECT wnrect;
     BOOL topLeft = FALSE;
     INT btnstate = 0;
     INT hit;
@@ -757,8 +757,9 @@ PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
     ClientToScreen(infoPtr->hwndSelf, &pt);
     GetWindowRect(infoPtr->hwndSelf, &wnrect);
     if (PtInRect(&wnrect, pt)) {
-        RECT TLbtnrect, BRbtnrect;
-        PAGER_GetButtonRects(infoPtr, &TLbtnrect, &BRbtnrect, FALSE);
+       RECT topleft, bottomright, *rect = NULL;
+
+       PAGER_GetButtonRects(infoPtr, &topleft, &bottomright, FALSE);
 
        clpt = pt;
        MapWindowPoints(0, infoPtr->hwndSelf, &clpt, 1);
@@ -766,23 +767,23 @@ PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
        if ((hit == PGB_TOPORLEFT) && (infoPtr->TLbtnState == PGF_NORMAL))
        {
            topLeft = TRUE;
-           btnrect = &TLbtnrect;
+           rect = &topleft;
            infoPtr->TLbtnState = PGF_HOT;
            btnstate = infoPtr->TLbtnState;
        }
        else if ((hit == PGB_BOTTOMORRIGHT) && (infoPtr->BRbtnState == PGF_NORMAL))
        {
            topLeft = FALSE;
-           btnrect = &BRbtnrect;
+           rect = &bottomright;
            infoPtr->BRbtnState = PGF_HOT;
            btnstate = infoPtr->BRbtnState;
        }
 
        /* If in one of the buttons the capture and draw buttons */
-       if (btnrect)
+       if (rect)
        {
             TRACE("[%p] draw btn (%s), Capture %s, style %08x\n",
-                  infoPtr->hwndSelf, wine_dbgstr_rect(btnrect),
+                  infoPtr->hwndSelf, wine_dbgstr_rect(rect),
                  (infoPtr->bCapture) ? "TRUE" : "FALSE",
                  infoPtr->dwStyle);
            if (!infoPtr->bCapture)
@@ -795,7 +796,7 @@ PAGER_MouseMove (PAGER_INFO* infoPtr, INT keys, INT x, INT y)
                SetTimer(infoPtr->hwndSelf, TIMERID1, 0x3e, 0);
            hdc = GetWindowDC(infoPtr->hwndSelf);
            /* OffsetRect(wnrect, 0 | 1, 0 | 1) */
-           PAGER_DrawButton(hdc, infoPtr->clrBk, *btnrect,
+           PAGER_DrawButton(hdc, infoPtr->clrBk, *rect,
                             infoPtr->dwStyle & PGS_HORZ, topLeft, btnstate);
            ReleaseDC(infoPtr->hwndSelf, hdc);
            return 0;
@@ -976,16 +977,17 @@ PAGER_EraseBackground (const PAGER_INFO* infoPtr, HDC hdc)
 {
     POINT pt, ptorig;
     HWND parent;
+    LRESULT ret;
 
     pt.x = 0;
     pt.y = 0;
     parent = GetParent(infoPtr->hwndSelf);
     MapWindowPoints(infoPtr->hwndSelf, parent, &pt, 1);
     OffsetWindowOrgEx (hdc, pt.x, pt.y, &ptorig);
-    SendMessageW (parent, WM_ERASEBKGND, (WPARAM)hdc, 0);
+    ret = SendMessageW (parent, WM_ERASEBKGND, (WPARAM)hdc, 0);
     SetWindowOrgEx (hdc, ptorig.x, ptorig.y, 0);
 
-    return 0;
+    return ret;
 }
 
 
index 1c52316..18aa4c9 100644 (file)
@@ -57,6 +57,7 @@ typedef struct
 #define LED_GAP           2
 #define MARQUEE_LEDS      5
 #define ID_MARQUEE_TIMER  1
+#define DEFAULT_MARQUEE_PERIOD 30
 
 /* Helper to obtain size of a progress bar chunk ("led"). */
 static inline int get_led_size ( const PROGRESS_INFO *infoPtr, LONG style,
@@ -436,40 +437,32 @@ static LRESULT PROGRESS_Paint (PROGRESS_INFO *infoPtr, HDC hdc)
 
 
 /***********************************************************************
- * PROGRESS_Timer
- * Handle the marquee timer messages
+ * Advance marquee progress by one step.
  */
-static LRESULT PROGRESS_Timer (PROGRESS_INFO *infoPtr, INT idTimer)
+static void PROGRESS_UpdateMarquee (PROGRESS_INFO *infoPtr)
 {
-    if(idTimer == ID_MARQUEE_TIMER)
-    {
-        LONG style = GetWindowLongW (infoPtr->Self, GWL_STYLE);
-        RECT rect;
-        int ledWidth, leds;
-        HTHEME theme = GetWindowTheme (infoPtr->Self);
-        BOOL barSmooth = (style & PBS_SMOOTH) && !theme;
+    LONG style = GetWindowLongW (infoPtr->Self, GWL_STYLE);
+    RECT rect;
+    int ledWidth, leds;
+    HTHEME theme = GetWindowTheme (infoPtr->Self);
+    BOOL smooth = (style & PBS_SMOOTH) && !theme;
 
-        get_client_rect (infoPtr->Self, &rect);
+    get_client_rect (infoPtr->Self, &rect);
 
-        if(!barSmooth)
-            ledWidth = get_led_size( infoPtr, style, &rect ) + 
-                get_led_gap( infoPtr );
-        else
-            ledWidth = 1;
+    if (smooth)
+        ledWidth = 1;
+    else
+        ledWidth = get_led_size( infoPtr, style, &rect ) + get_led_gap( infoPtr );
 
-        leds = (get_bar_size( style, &rect ) + ledWidth - 1) / 
-            ledWidth;
+    leds = (get_bar_size( style, &rect ) + ledWidth - 1) /
+        ledWidth;
 
-        /* increment the marquee progress */
-        if(++infoPtr->MarqueePos >= leds)
-        {
-            infoPtr->MarqueePos = 0;
-        }
+    /* increment the marquee progress */
+    if (++infoPtr->MarqueePos >= leds)
+        infoPtr->MarqueePos = 0;
 
-        InvalidateRect(infoPtr->Self, &rect, FALSE);
-        UpdateWindow(infoPtr->Self);
-    }
-    return 0;
+    InvalidateRect(infoPtr->Self, &rect, TRUE);
+    UpdateWindow(infoPtr->Self);
 }
 
 
@@ -512,6 +505,30 @@ static DWORD PROGRESS_SetRange (PROGRESS_INFO *infoPtr, int low, int high)
     return res;
 }
 
+static UINT PROGRESS_SetPos (PROGRESS_INFO *infoPtr, INT pos)
+{
+    DWORD style = GetWindowLongW(infoPtr->Self, GWL_STYLE);
+
+    if (style & PBS_MARQUEE)
+    {
+        PROGRESS_UpdateMarquee(infoPtr);
+        return 1;
+    }
+    else
+    {
+        UINT oldVal;
+        oldVal = infoPtr->CurVal;
+        if (oldVal != pos) {
+           infoPtr->CurVal = pos;
+           PROGRESS_CoercePos(infoPtr);
+           TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
+            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
+            UpdateWindow( infoPtr->Self );
+        }
+        return oldVal;
+    }
+}
+
 /***********************************************************************
  *           ProgressWindowProc
  */
@@ -586,7 +603,9 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
         return PROGRESS_Paint (infoPtr, (HDC)wParam);
 
     case WM_TIMER:
-        return PROGRESS_Timer (infoPtr, (INT)wParam);
+        if (wParam == ID_MARQUEE_TIMER)
+            PROGRESS_UpdateMarquee (infoPtr);
+        return 0;
 
     case WM_THEMECHANGED:
     {
@@ -622,18 +641,7 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
     }
 
     case PBM_SETPOS:
-    {
-        UINT oldVal;
-        oldVal = infoPtr->CurVal;
-        if(oldVal != wParam) {
-           infoPtr->CurVal = (INT)wParam;
-           PROGRESS_CoercePos(infoPtr);
-           TRACE("PBM_SETPOS: current pos changed from %d to %d\n", oldVal, infoPtr->CurVal);
-            PROGRESS_Invalidate( infoPtr, oldVal, infoPtr->CurVal );
-            UpdateWindow( infoPtr->Self );
-        }
-        return oldVal;
-    }
+        return PROGRESS_SetPos(infoPtr, wParam);
 
     case PBM_SETRANGE:
         return PROGRESS_SetRange (infoPtr, (int)LOWORD(lParam), (int)HIWORD(lParam));
@@ -713,8 +721,9 @@ static LRESULT WINAPI ProgressWindowProc(HWND hwnd, UINT message,
     case PBM_SETMARQUEE:
        if(wParam != 0)
         {
+            UINT period = lParam ? (UINT)lParam : DEFAULT_MARQUEE_PERIOD;
             infoPtr->Marquee = TRUE;
-            SetTimer(infoPtr->Self, ID_MARQUEE_TIMER, (UINT)lParam, NULL);
+            SetTimer(infoPtr->Self, ID_MARQUEE_TIMER, period, NULL);
         }
         else
         {
index 3a1f5c5..1bcdfc9 100644 (file)
@@ -734,10 +734,10 @@ TOOLBAR_DrawImage(const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, INT left, I
 
 /* draws a blank frame for a toolbar button */
 static void
-TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, const NMTBCUSTOMDRAW *tbcd, DWORD dwItemCDFlag)
+TOOLBAR_DrawFrame(const TOOLBAR_INFO *infoPtr, const NMTBCUSTOMDRAW *tbcd, const RECT *rect, DWORD dwItemCDFlag)
 {
     HDC hdc = tbcd->nmcd.hdc;
-    RECT rc = tbcd->nmcd.rc;
+    RECT rc = *rect;
     /* if the state is disabled or indeterminate then the button
      * cannot have an interactive look like pressed or hot */
     BOOL non_interactive_state = (tbcd->nmcd.uItemState & CDIS_DISABLED) ||
@@ -940,7 +940,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
     tbcd.rcText.bottom = rcText.bottom - rc.top;
     tbcd.nmcd.uItemState = TOOLBAR_TranslateState(btnPtr);
     tbcd.nmcd.hdc = hdc;
-    tbcd.nmcd.rc = rc;
+    tbcd.nmcd.rc = btnPtr->rect;
     tbcd.hbrMonoDither = COMCTL32_hPattern55AABrush;
 
     /* FIXME: what are these used for? */
@@ -958,7 +958,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
        ntfret = TOOLBAR_SendNotify(&tbcd.nmcd.hdr, infoPtr, NM_CUSTOMDRAW);
         /* reset these fields so the user can't alter the behaviour like native */
         tbcd.nmcd.hdc = hdc;
-        tbcd.nmcd.rc = rc;
+        tbcd.nmcd.rc = btnPtr->rect;
 
        dwItemCustDraw = ntfret & 0xffff;
        dwItemCDFlag = ntfret & 0xffff0000;
@@ -1007,10 +1007,10 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
             || (drawSepDropDownArrow && btnPtr->bDropDownPressed))
             stateId = TS_HOT;
             
-        DrawThemeBackground (theme, hdc, partId, stateId, &tbcd.nmcd.rc, NULL);
+        DrawThemeBackground (theme, hdc, partId, stateId, &rc, NULL);
     }
     else
-        TOOLBAR_DrawFrame(infoPtr, &tbcd, dwItemCDFlag);
+        TOOLBAR_DrawFrame(infoPtr, &tbcd, &rc, dwItemCDFlag);
 
     if (drawSepDropDownArrow)
     {
index 73e5ca0..986b04f 100644 (file)
@@ -477,24 +477,22 @@ static INT get_notifycode(const TREEVIEW_INFO *infoPtr, INT code)
 }
 
 static inline BOOL
-TREEVIEW_SendRealNotify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPNMHDR pnmh)
+TREEVIEW_SendRealNotify(const TREEVIEW_INFO *infoPtr, UINT code, NMHDR *hdr)
 {
-    TRACE("wParam=%ld, lParam=%p\n", wParam, pnmh);
-    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, wParam, (LPARAM)pnmh);
+    TRACE("code=%d, hdr=%p\n", code, hdr);
+
+    hdr->hwndFrom = infoPtr->hwnd;
+    hdr->idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
+    hdr->code = get_notifycode(infoPtr, code);
+
+    return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)hdr);
 }
 
 static BOOL
 TREEVIEW_SendSimpleNotify(const TREEVIEW_INFO *infoPtr, UINT code)
 {
-    NMHDR nmhdr;
-    HWND hwnd = infoPtr->hwnd;
-
-    TRACE("%d\n", code);
-    nmhdr.hwndFrom = hwnd;
-    nmhdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    nmhdr.code = get_notifycode(infoPtr, code);
-
-    return TREEVIEW_SendRealNotify(infoPtr, nmhdr.idFrom, &nmhdr);
+    NMHDR hdr;
+    return TREEVIEW_SendRealNotify(infoPtr, code, &hdr);
 }
 
 static VOID
@@ -534,18 +532,13 @@ static BOOL
 TREEVIEW_SendTreeviewNotify(const TREEVIEW_INFO *infoPtr, UINT code, UINT action,
                            UINT mask, HTREEITEM oldItem, HTREEITEM newItem)
 {
-    HWND hwnd = infoPtr->hwnd;
     NMTREEVIEWW nmhdr;
     BOOL ret;
 
     TRACE("code:%d action:%x olditem:%p newitem:%p\n",
          code, action, oldItem, newItem);
 
-    ZeroMemory(&nmhdr, sizeof(NMTREEVIEWW));
-
-    nmhdr.hdr.hwndFrom = hwnd;
-    nmhdr.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    nmhdr.hdr.code = get_notifycode(infoPtr, code);
+    memset(&nmhdr, 0, sizeof(NMTREEVIEWW));
     nmhdr.action = action;
 
     if (oldItem)
@@ -557,7 +550,7 @@ TREEVIEW_SendTreeviewNotify(const TREEVIEW_INFO *infoPtr, UINT code, UINT action
     nmhdr.ptDrag.x = 0;
     nmhdr.ptDrag.y = 0;
 
-    ret = TREEVIEW_SendRealNotify(infoPtr, nmhdr.hdr.idFrom, &nmhdr.hdr);
+    ret = TREEVIEW_SendRealNotify(infoPtr, code, &nmhdr.hdr);
     if (!infoPtr->bNtfUnicode)
     {
        Free(nmhdr.itemOld.pszText);
@@ -570,14 +563,10 @@ static BOOL
 TREEVIEW_SendTreeviewDnDNotify(const TREEVIEW_INFO *infoPtr, UINT code,
                               HTREEITEM dragItem, POINT pt)
 {
-    HWND hwnd = infoPtr->hwnd;
     NMTREEVIEWW nmhdr;
 
     TRACE("code:%d dragitem:%p\n", code, dragItem);
 
-    nmhdr.hdr.hwndFrom = hwnd;
-    nmhdr.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    nmhdr.hdr.code = get_notifycode(infoPtr, code);
     nmhdr.action = 0;
     nmhdr.itemNew.mask = TVIF_STATE | TVIF_PARAM | TVIF_HANDLE;
     nmhdr.itemNew.hItem = dragItem;
@@ -587,7 +576,7 @@ TREEVIEW_SendTreeviewDnDNotify(const TREEVIEW_INFO *infoPtr, UINT code,
     nmhdr.ptDrag.x = pt.x;
     nmhdr.ptDrag.y = pt.y;
 
-    return TREEVIEW_SendRealNotify(infoPtr, nmhdr.hdr.idFrom, &nmhdr.hdr);
+    return TREEVIEW_SendRealNotify(infoPtr, code, &nmhdr.hdr);
 }
 
 
@@ -595,16 +584,12 @@ static BOOL
 TREEVIEW_SendCustomDrawNotify(const TREEVIEW_INFO *infoPtr, DWORD dwDrawStage,
                              HDC hdc, RECT rc)
 {
-    HWND hwnd = infoPtr->hwnd;
     NMTVCUSTOMDRAW nmcdhdr;
-    LPNMCUSTOMDRAW nmcd;
+    NMCUSTOMDRAW *nmcd;
 
     TRACE("drawstage:%x hdc:%p\n", dwDrawStage, hdc);
 
     nmcd = &nmcdhdr.nmcd;
-    nmcd->hdr.hwndFrom = hwnd;
-    nmcd->hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    nmcd->hdr.code = NM_CUSTOMDRAW;
     nmcd->dwDrawStage = dwDrawStage;
     nmcd->hdc = hdc;
     nmcd->rc = rc;
@@ -615,11 +600,9 @@ TREEVIEW_SendCustomDrawNotify(const TREEVIEW_INFO *infoPtr, DWORD dwDrawStage,
     nmcdhdr.clrTextBk = infoPtr->clrBk;
     nmcdhdr.iLevel = 0;
 
-    return TREEVIEW_SendRealNotify(infoPtr, nmcd->hdr.idFrom, &nmcdhdr.nmcd.hdr);
+    return TREEVIEW_SendRealNotify(infoPtr, NM_CUSTOMDRAW, &nmcdhdr.nmcd.hdr);
 }
 
-
-
 /* FIXME: need to find out when the flags in uItemState need to be set */
 
 static BOOL
@@ -627,8 +610,7 @@ TREEVIEW_SendCustomDrawItemNotify(const TREEVIEW_INFO *infoPtr, HDC hdc,
                                  TREEVIEW_ITEM *item, UINT uItemDrawState,
                                  NMTVCUSTOMDRAW *nmcdhdr)
 {
-    HWND hwnd = infoPtr->hwnd;
-    LPNMCUSTOMDRAW nmcd;
+    NMCUSTOMDRAW *nmcd;
     DWORD dwDrawStage;
     DWORD_PTR dwItemSpec;
     UINT uItemState;
@@ -644,9 +626,6 @@ TREEVIEW_SendCustomDrawItemNotify(const TREEVIEW_INFO *infoPtr, HDC hdc,
        uItemState |= CDIS_HOT;
 
     nmcd = &nmcdhdr->nmcd;
-    nmcd->hdr.hwndFrom = hwnd;
-    nmcd->hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    nmcd->hdr.code = NM_CUSTOMDRAW;
     nmcd->dwDrawStage = dwDrawStage;
     nmcd->hdc = hdc;
     nmcd->rc = item->rect;
@@ -659,24 +638,19 @@ TREEVIEW_SendCustomDrawItemNotify(const TREEVIEW_INFO *infoPtr, HDC hdc,
          nmcd->dwDrawStage, nmcd->hdc, nmcd->dwItemSpec,
          nmcd->uItemState, nmcd->lItemlParam);
 
-    return TREEVIEW_SendRealNotify(infoPtr, nmcd->hdr.idFrom, &nmcdhdr->nmcd.hdr);
+    return TREEVIEW_SendRealNotify(infoPtr, NM_CUSTOMDRAW, &nmcdhdr->nmcd.hdr);
 }
 
 static BOOL
 TREEVIEW_BeginLabelEditNotify(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *editItem)
 {
-    HWND hwnd = infoPtr->hwnd;
     NMTVDISPINFOW tvdi;
     BOOL ret;
 
-    tvdi.hdr.hwndFrom = hwnd;
-    tvdi.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    tvdi.hdr.code = get_notifycode(infoPtr, TVN_BEGINLABELEDITW);
-
     TREEVIEW_TVItemFromItem(infoPtr, TVIF_HANDLE | TVIF_STATE | TVIF_PARAM | TVIF_TEXT,
                             &tvdi.item, editItem);
 
-    ret = TREEVIEW_SendRealNotify(infoPtr, tvdi.hdr.idFrom, &tvdi.hdr);
+    ret = TREEVIEW_SendRealNotify(infoPtr, TVN_BEGINLABELEDITW, &tvdi.hdr);
 
     if (!infoPtr->bNtfUnicode)
        Free(tvdi.item.pszText);
@@ -689,17 +663,12 @@ TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item,
                        UINT mask)
 {
     NMTVDISPINFOEXW callback;
-    HWND hwnd = infoPtr->hwnd;
 
     TRACE("mask=0x%x, callbackmask=0x%x\n", mask, item->callbackMask);
     mask &= item->callbackMask;
 
     if (mask == 0) return;
 
-    callback.hdr.hwndFrom         = hwnd;
-    callback.hdr.idFrom           = GetWindowLongPtrW(hwnd, GWLP_ID);
-    callback.hdr.code             = get_notifycode(infoPtr, TVN_GETDISPINFOW);
-
     /* 'state' always contains valid value, as well as 'lParam'.
      * All other parameters are uninitialized.
      */
@@ -714,7 +683,7 @@ TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item,
     if (mask & TVIF_TEXT)
        item->textWidth = 0;
 
-    TREEVIEW_SendRealNotify(infoPtr, callback.hdr.idFrom, &callback.hdr);
+    TREEVIEW_SendRealNotify(infoPtr, TVN_GETDISPINFOW, &callback.hdr);
     TRACE("resulting code 0x%08x\n", callback.hdr.code);
 
     /* It may have changed due to a call to SetItem. */
@@ -2692,17 +2661,17 @@ TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
        DeleteObject(hNewPen);
     }
 
+    /* Restore the hdc state */
+    SetTextColor(hdc, oldTextColor);
+    SetBkColor(hdc, oldTextBkColor);
+    SelectObject(hdc, hOldFont);
+
     if (cditem & CDRF_NOTIFYPOSTPAINT)
     {
        cditem = TREEVIEW_SendCustomDrawItemNotify
            (infoPtr, hdc, item, CDDS_ITEMPOSTPAINT, &nmcdhdr);
        TRACE("postpaint:cditem-app returns 0x%x\n", cditem);
     }
-
-    /* Restore the hdc state */
-    SetTextColor(hdc, oldTextColor);
-    SetBkColor(hdc, oldTextBkColor);
-    SelectObject(hdc, hOldFont);
 }
 
 /* Computes treeHeight and treeWidth and updates the scroll bars.
@@ -3973,7 +3942,6 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
 static LRESULT
 TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
 {
-    HWND hwnd = infoPtr->hwnd;
     TREEVIEW_ITEM *editedItem = infoPtr->editItem;
     NMTVDISPINFOW tvdi;
     BOOL bCommit;
@@ -3983,9 +3951,6 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
 
     if (!IsWindow(infoPtr->hwndEdit)) return FALSE;
 
-    tvdi.hdr.hwndFrom = hwnd;
-    tvdi.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);
-    tvdi.hdr.code = get_notifycode(infoPtr, TVN_ENDLABELEDITW);
     tvdi.item.mask = 0;
     tvdi.item.hItem = editedItem;
     tvdi.item.state = editedItem->state;
@@ -4013,7 +3978,7 @@ TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
        tvdi.item.cchTextMax = 0;
     }
 
-    bCommit = TREEVIEW_SendRealNotify(infoPtr, tvdi.hdr.idFrom, &tvdi.hdr);
+    bCommit = TREEVIEW_SendRealNotify(infoPtr, TVN_ENDLABELEDITW, &tvdi.hdr);
 
     if (!bCancel && bCommit)   /* Apply the changes */
     {
@@ -5219,11 +5184,15 @@ TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam)
 {
     /* If it is non-NULL and different, it will be selected and visible. */
     TREEVIEW_ITEM *newSelection = NULL;
-
     TREEVIEW_ITEM *prevItem = infoPtr->selectedItem;
+    NMTVKEYDOWN nmkeydown;
 
     TRACE("%lx\n", wParam);
 
+    nmkeydown.wVKey = wParam;
+    nmkeydown.flags = 0;
+    TREEVIEW_SendRealNotify(infoPtr, TVN_KEYDOWN, &nmkeydown.hdr);
+
     if (prevItem == NULL)
        return FALSE;
 
@@ -5244,8 +5213,8 @@ TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam)
 
     case VK_RETURN:
         TREEVIEW_SendSimpleNotify(infoPtr, NM_RETURN);
-    break;
-    
+        break;
+
     case VK_HOME:
        newSelection = infoPtr->root->firstChild;
        break;
@@ -5526,9 +5495,6 @@ TREEVIEW_SetCursor(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
     item = TREEVIEW_HitTestPoint(infoPtr, pt);
 
     memset(&nmmouse, 0, sizeof(nmmouse));
-    nmmouse.hdr.hwndFrom = infoPtr->hwnd;
-    nmmouse.hdr.idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
-    nmmouse.hdr.code = NM_SETCURSOR;
     if (item)
     {
         nmmouse.dwItemSpec = (DWORD_PTR)item;
@@ -5537,7 +5503,7 @@ TREEVIEW_SetCursor(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
     nmmouse.pt.x = 0;
     nmmouse.pt.y = 0;
     nmmouse.dwHitInfo = lParam;
-    if (TREEVIEW_SendRealNotify(infoPtr, nmmouse.hdr.idFrom, &nmmouse.hdr))
+    if (TREEVIEW_SendRealNotify(infoPtr, NM_SETCURSOR, &nmmouse.hdr))
         return 0;
 
     if (item && (infoPtr->dwStyle & TVS_TRACKSELECT))
index 1d248da..8e49275 100644 (file)
@@ -60,7 +60,7 @@ reactos/dll/win32/browseui            # Out of sync
 reactos/dll/win32/cabinet             # Synced to Wine-1.7.17
 reactos/dll/win32/clusapi             # Synced to Wine-1.7.17
 reactos/dll/win32/comcat              # Synced to Wine-1.7.17
-reactos/dll/win32/comctl32            # Synced to Wine-1.7.17
+reactos/dll/win32/comctl32            # Synced to Wine-1.7.27
 reactos/dll/win32/comdlg32            # Synced to Wine-1.7.17
 reactos/dll/win32/compstui            # Synced to Wine-1.7.17
 reactos/dll/win32/credui              # Synced to Wine-1.7.17