Listview L7
Dimitrie O. Paun
dpaun at rogers.com
Mon Oct 7 01:12:32 CDT 2002
This one should make ICON and SMALLICON work in OWNERDATA case.
ChangeLog
Maintain the item position in {,SMALL}ICON mode separataly
from the item, so that we have it even in LVS_OWNERDATA.
--- dlls/comctl32/listview.c.L6 Mon Oct 7 01:02:40 2002
+++ dlls/comctl32/listview.c Mon Oct 7 02:07:24 2002
@@ -100,7 +100,6 @@
UINT state;
LPARAM lParam;
INT iIndent;
- POINT ptPosition;
BOOL valid;
} LISTVIEW_ITEM;
@@ -153,8 +152,10 @@
RECT rcFocus;
DWORD dwStyle; /* the cached window GWL_STYLE */
DWORD dwLvExStyle; /* extended listview style */
- HDPA hdpaItems;
UINT nItemCount;
+ HDPA hdpaItems;
+ HDPA hdpaPosX; /* maintains the (X, Y) coordinates of the */
+ HDPA hdpaPosY; /* items in LVS_ICON, and LVS_SMALLICON modes */
PFNLVCOMPARE pfnCompare;
LPARAM lParamSort;
HWND hwndEdit;
@@ -1297,11 +1298,8 @@
/************************************************************/
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
{
- /* FIXME: what about virtual listview? */
- HDPA hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem);
- LISTVIEW_ITEM * lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0);
- if (!lpItem) return FALSE;
- TopLeft = lpItem->ptPosition;
+ TopLeft.x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem);
+ TopLeft.y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem);
}
else if (uView == LVS_LIST)
{
@@ -1347,6 +1345,7 @@
TopLeft.x -= scrollInfo.nPos;
}
}
+ TRACE("TopLeft=%s\n", debugpoint(&TopLeft));
/************************************************************/
/* compute position point (ala LVM_GETITEMPOSITION) */
@@ -3901,6 +3900,8 @@
/* reinitialize listview memory */
bResult = DPA_DeleteAllPtrs(infoPtr->hdpaItems);
infoPtr->nItemCount = 0;
+ DPA_DeleteAllPtrs(infoPtr->hdpaPosX);
+ DPA_DeleteAllPtrs(infoPtr->hdpaPosY);
/* align items (set position of each item) */
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
@@ -4105,6 +4106,8 @@
}
bResult = DPA_Destroy(hdpaSubItems);
+ DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
+ DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
}
LISTVIEW_ShiftIndices(infoPtr,nItem,-1);
@@ -6052,11 +6055,7 @@
infoPtr->nItemCount++;
if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW))
- {
- DPA_DeletePtr(infoPtr->hdpaItems, nItem);
- infoPtr->nItemCount--;
- goto fail;
- }
+ goto undo;
/* if we're sorted, sort the list, and update the index */
if (is_sorted)
@@ -6072,6 +6071,18 @@
}
}
+ /* make room for the position, if we are in the right mode */
+ if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
+ {
+ if (DPA_InsertPtr(infoPtr->hdpaPosX, nItem, 0) == -1)
+ goto undo;
+ if (DPA_InsertPtr(infoPtr->hdpaPosY, nItem, 0) == -1)
+ {
+ DPA_DeletePtr(infoPtr->hdpaPosX, nItem);
+ goto undo;
+ }
+ }
+
/* Add the subitem list to the items array. Do this last in case we go to
* fail during the above.
*/
@@ -6099,6 +6110,9 @@
TRACE(" <- %d\n", nItem);
return nItem;
+undo:
+ DPA_DeletePtr(infoPtr->hdpaItems, nItem);
+ infoPtr->nItemCount--;
fail:
DPA_DeletePtr(hdpaSubItems, 0);
DPA_Destroy (hdpaSubItems);
@@ -6785,68 +6799,33 @@
*/
static BOOL LISTVIEW_SetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, POINT pt)
{
- UINT lStyle = infoPtr->dwStyle;
- UINT uView = lStyle & LVS_TYPEMASK;
- LISTVIEW_ITEM *lpItem;
- HDPA hdpaSubItems;
- BOOL bResult = FALSE;
-
- TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));
-
- if (lStyle & LVS_OWNERDATA)
- return FALSE;
+ UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
- if ((nItem >= 0) || (nItem < infoPtr->nItemCount))
- {
- if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
- {
- if ( (hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)) )
- {
- if ( (lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)) )
- {
- POINT orig = lpItem->ptPosition;
- bResult = TRUE;
- if ((pt.x == -1) && (pt.y == -1))
- {
- /* This point value seems to be an undocumented feature. The
- * best guess is that it means either at the origin, or at
- * the true beginning of the list. I will assume the origin.
- */
- if (!LISTVIEW_GetOrigin(infoPtr, &pt))
- pt.x = pt.y = 0;
- if (uView == LVS_ICON)
- {
- pt.x += (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
- pt.y += ICON_TOP_PADDING;
- }
- TRACE("requested special (-1,-1), set to origin %s\n", debugpoint(&pt));
- }
+ TRACE("(nItem=%d, &pt=%s\n", nItem, debugpoint(&pt));
- lpItem->ptPosition = *&pt;
- if (uView == LVS_ICON)
- {
- lpItem->ptPosition.y -= ICON_TOP_PADDING;
- lpItem->ptPosition.x -= (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
- if ((lpItem->ptPosition.y < 0) || (lpItem->ptPosition.x < 0))
- {
- FIXME("failed orig=%s, intent=%s, is %s, setting neg to 0\n",
- debugpoint(&orig), debugpoint(&pt), debugpoint(&lpItem->ptPosition));
- /*
- if (lpItem->ptPosition.x < 0) lpItem->ptPosition.x = 0;
- if (lpItem->ptPosition.y < 0) lpItem->ptPosition.y = 0;
- */
- }
- else
- {
- TRACE("orig=%s, intent=%s, is %s\n", debugpoint(&orig), debugpoint(&pt), debugpoint(&lpItem->ptPosition));
- }
- }
- }
- }
- }
- }
+ if (nItem < 0 || nItem >= infoPtr->nItemCount ||
+ !(uView == LVS_ICON || uView == LVS_SMALLICON)) return FALSE;
- return bResult;
+ /* This point value seems to be an undocumented feature.
+ * The best guess is that it means either at the origin,
+ * or at true beginning of the list. I will assume the origin. */
+ if ((pt.x == -1) && (pt.y == -1))
+ LISTVIEW_GetOrigin(infoPtr, &pt);
+ else if (uView == LVS_ICON)
+ {
+ pt.x -= (infoPtr->iconSpacing.cx - infoPtr->iconSize.cx) / 2;
+ pt.y -= ICON_TOP_PADDING;
+ }
+
+ /* Allocating a POINTER for every item is too resource intensive,
+ * so we'll keep the (x,y) in different arrays */
+ if (DPA_InsertPtr(infoPtr->hdpaPosX, nItem, (void *)pt.x) == nItem &&
+ DPA_InsertPtr(infoPtr->hdpaPosY, nItem, (void *)pt.y) == nItem )
+ return TRUE;
+
+ ERR("We should never fail here (nItem=%d, pt=%s), please report.\n",
+ nItem, debugpoint(&pt));
+ return FALSE;
}
/***
@@ -7224,6 +7203,8 @@
/* allocate memory for the data structure */
infoPtr->hdpaItems = DPA_Create(10);
+ infoPtr->hdpaPosX = DPA_Create(10);
+ infoPtr->hdpaPosY = DPA_Create(10);
/* allocate memory for the selection ranges */
infoPtr->hdpaSelectionRanges = DPA_Create(10);
More information about the wine-patches
mailing list