listview advice needed.

Rein Klazes rklazes at xs4all.nl
Sat Nov 15 08:43:53 CST 2003


On Sat, 15 Nov 2003 01:50:34 -0500, you wrote:

> On November 12, 2003 08:30 am, Rei
> 
> OK, I've looked at the code, and it may be the fix. The problem with 
> it is that we modify the app's structure, which may be a problem. 
> Can you please check with the native comctl32 if it modifies iSubItem 
> to 0 after the call?

OK, here is a patch that doesn't modify the structure.

Changelog:
	dlls/comctl32	: listview.c
	Ignore invalid iSubItem in LISTVIEW_GetItemT()

Rein.
-- 
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/dlls/comctl32/listview.c	2003-11-14 11:56:56.000000000 +0100
+++ mywine/dlls/comctl32/listview.c	2003-11-15 15:14:14.000000000 +0100
@@ -4982,6 +4982,7 @@
     ITEM_INFO *lpItem;
     ITEMHDR* pItemHdr;
     HDPA hdpaSubItems;
+    INT isubitem;
 
     TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
 
@@ -4990,6 +4991,9 @@
 
     if (lpLVItem->mask == 0) return TRUE;
 
+    /* make a local copy */
+    isubitem = lpLVItem->iSubItem;
+
     /* a quick optimization if all we're asked is the focus state
      * these queries are worth optimising since they are common,
      * and can be answered in constant time, without the heavy accesses */
@@ -5016,7 +5020,7 @@
 	     *       depend on the uninitialized fields being 0 */
 	    dispInfo.item.mask = lpLVItem->mask & ~LVIF_PARAM;
 	    dispInfo.item.iItem = lpLVItem->iItem;
-	    dispInfo.item.iSubItem = lpLVItem->iSubItem;
+	    dispInfo.item.iSubItem = isubitem;
 	    if (lpLVItem->mask & LVIF_TEXT)
 	    {
 		dispInfo.item.pszText = lpLVItem->pszText;
@@ -5048,7 +5052,7 @@
 	if (lpLVItem->mask & LVIF_PARAM) lpLVItem->lParam = 0;
 	
 	/* we store only a little state, so if we're not asked, we're done */
-	if (!(lpLVItem->mask & LVIF_STATE) || lpLVItem->iSubItem) return TRUE;
+	if (!(lpLVItem->mask & LVIF_STATE) || isubitem) return TRUE;
 
 	/* if focus is handled by us, report it */
 	if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 
@@ -5074,16 +5078,20 @@
     lpItem = (ITEM_INFO *)DPA_GetPtr(hdpaSubItems, 0);
     assert (lpItem);
 
-    if (lpLVItem->iSubItem)
+    if (isubitem)
     {
-	SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem);
+	SUBITEM_INFO *lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, isubitem);
         pItemHdr = lpSubItem ? &lpSubItem->hdr : &callbackHdr;
+        if( !lpSubItem) {
+            WARN(" iSubItem invalid (%08x), ignored.\n", isubitem);
+            isubitem = 0;
+        }
     }
     else
 	pItemHdr = &lpItem->hdr;
 
     /* Do we need to query the state from the app? */
-    if ((lpLVItem->mask & LVIF_STATE) && infoPtr->uCallbackMask && lpLVItem->iSubItem == 0)
+    if ((lpLVItem->mask & LVIF_STATE) && infoPtr->uCallbackMask && isubitem == 0)
     {
 	dispInfo.item.mask |= LVIF_STATE;
 	dispInfo.item.stateMask = infoPtr->uCallbackMask;
@@ -5091,7 +5099,7 @@
   
     /* Do we need to enquire about the image? */
     if ((lpLVItem->mask & LVIF_IMAGE) && pItemHdr->iImage == I_IMAGECALLBACK &&
-        (lpLVItem->iSubItem == 0 || (infoPtr->dwLvExStyle & LVS_EX_SUBITEMIMAGES)))
+        (isubitem == 0 || (infoPtr->dwLvExStyle & LVS_EX_SUBITEMIMAGES)))
     {
 	dispInfo.item.mask |= LVIF_IMAGE;
         dispInfo.item.iImage = I_IMAGECALLBACK;
@@ -5111,14 +5119,14 @@
     if (dispInfo.item.mask != 0)
     {
 	dispInfo.item.iItem = lpLVItem->iItem;
-	dispInfo.item.iSubItem = lpLVItem->iSubItem;
+	dispInfo.item.iSubItem = isubitem;
 	dispInfo.item.lParam = lpItem->lParam;
 	notify_dispinfoT(infoPtr, LVN_GETDISPINFOW, &dispInfo, isW);
 	TRACE("   getdispinfo(2):item=%s\n", debuglvitem_t(&dispInfo.item, isW));
     }
 
     /* we should not store values for subitems */
-    if (lpLVItem->iSubItem) dispInfo.item.mask &= ~LVIF_DI_SETITEM;
+    if (isubitem) dispInfo.item.mask &= ~LVIF_DI_SETITEM;
 
     /* Now, handle the iImage field */
     if (dispInfo.item.mask & LVIF_IMAGE)
@@ -5129,7 +5137,7 @@
     }
     else if (lpLVItem->mask & LVIF_IMAGE)
     {
-        if(lpLVItem->iSubItem == 0 || (infoPtr->dwLvExStyle & LVS_EX_SUBITEMIMAGES))
+        if(isubitem == 0 || (infoPtr->dwLvExStyle & LVS_EX_SUBITEMIMAGES))
             lpLVItem->iImage = pItemHdr->iImage;
         else
             lpLVItem->iImage = 0;
@@ -5150,7 +5158,7 @@
     }
 
     /* if this is a subitem, we're done */
-    if (lpLVItem->iSubItem) return TRUE;
+    if (isubitem) return TRUE;
   
     /* Next is the lParam field */
     if (dispInfo.item.mask & LVIF_PARAM)


More information about the wine-devel mailing list