Listview K11
Dimitrie O. Paun
dpaun at rogers.com
Sat Oct 5 11:27:05 CDT 2002
SubItem work this time around.
ChangeLog:
Reimplement GetSubItemRect, subitem setting optimizations.
--- dlls/comctl32/listview.c.K10 Sat Oct 5 03:08:13 2002
+++ dlls/comctl32/listview.c Sat Oct 5 12:22:26 2002
@@ -270,6 +270,7 @@
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT);
static INT LISTVIEW_GetItemWidth(LISTVIEW_INFO *);
+static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *, INT, LPRECT);
static INT LISTVIEW_GetLabelWidth(LISTVIEW_INFO *, INT);
static LRESULT LISTVIEW_GetColumnWidth(LISTVIEW_INFO *, INT);
static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *, LPPOINT);
@@ -1455,7 +1456,7 @@
TRACE("hwnd=%x, item=%d, label=%s, fulltext=%s\n",
infoPtr->hwndSelf, nItem, debugrect(&Label), debugrect(lprcText));
-
+
/***********************************************************/
/* compute boundary box for the item (ala LVM_GETITEMRECT) */
/***********************************************************/
@@ -2693,6 +2694,7 @@
{
HDPA hdpaSubItems;
LISTVIEW_SUBITEM *lpSubItem;
+ BOOL bModified = FALSE;
/* set subitem only if column is present */
if (Header_GetItemCount(infoPtr->hwndHeader) <= lpLVItem->iSubItem)
@@ -2700,6 +2702,7 @@
/* First do some sanity checks */
if (lpLVItem->mask & ~(LVIF_TEXT | LVIF_IMAGE)) return FALSE;
+ if (!(lpLVItem->mask & (LVIF_TEXT | LVIF_IMAGE))) return TRUE;
/* get the subitem structure, and create it if not there */
hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem);
@@ -2725,13 +2728,34 @@
return FALSE;
}
lpSubItem->iSubItem = lpLVItem->iSubItem;
+ bModified = TRUE;
}
if (lpLVItem->mask & LVIF_IMAGE)
- lpSubItem->hdr.iImage = lpLVItem->iImage;
+ if (lpSubItem->hdr.iImage != lpLVItem->iImage)
+ {
+ lpSubItem->hdr.iImage = lpLVItem->iImage;
+ bModified = TRUE;
+ }
if (lpLVItem->mask & LVIF_TEXT)
- textsetptrT(&lpSubItem->hdr.pszText, lpLVItem->pszText, isW);
+ if (lpSubItem->hdr.pszText != lpLVItem->pszText)
+ {
+ textsetptrT(&lpSubItem->hdr.pszText, lpLVItem->pszText, isW);
+ bModified = TRUE;
+ }
+
+ if (bModified && !infoPtr->bIsDrawing)
+ {
+ RECT rect;
+
+ rect.top = lpLVItem->iSubItem;
+ rect.left = LVIR_BOUNDS;
+ /* GetSubItemRect will fail in non-report mode, so there's
+ * gonna be no invalidation then, yay! */
+ if (LISTVIEW_GetSubItemRect(infoPtr, lpLVItem->iItem, &rect))
+ LISTVIEW_InvalidateRect(infoPtr, &rect);
+ }
return TRUE;
}
@@ -2783,7 +2807,7 @@
}
/* redraw item, if necessary */
- if (bResult && !infoPtr->bIsDrawing)
+ if (bResult && !infoPtr->bIsDrawing && lpLVItem->iSubItem == 0)
{
if (oldFocus != infoPtr->nFocusedItem && infoPtr->bFocus)
{
@@ -5202,34 +5226,51 @@
return TRUE;
}
-
-static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, INT nSubItem, INT flags, LPRECT lprc)
+/***
+ * DESCRIPTION:
+ * Retrieves the spacing between listview control items.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [IO] lprc : rectangle to receive the output
+ * on input, lprc->top = nSubItem
+ * lprc->left = LVIR_ICON | LVIR_BOUNDS | LVIR_LABEL
+ *
+ * NOTE: this call is succeeds only for REPORT style listviews.
+ * Because we can calculate things much faster in report mode,
+ * we're gonna do the calculations inline here, instead of
+ * calling functions that do heavy lifting.
+ *
+ * RETURN:
+ * TRUE: success
+ * FALSE: failure
+ */
+static BOOL LISTVIEW_GetSubItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
{
- UINT uView = LISTVIEW_GetType(infoPtr);
- INT count;
-
- TRACE("(nItem=%d, nSubItem=%d lprc=%p)\n", nItem, nSubItem,
- lprc);
+ POINT ptPosition;
+
+ if (!lprc || LISTVIEW_GetType(infoPtr) != LVS_REPORT) return FALSE;
+
+ TRACE("(nItem=%d, nSubItem=%d)\n", nItem, lprc->top);
- if (!(uView & LVS_REPORT))
- return FALSE;
+ if (!Header_GetItemRect(infoPtr->hwndHeader, lprc->top, lprc)) return FALSE;
+ if (!LISTVIEW_GetItemPosition(infoPtr, nItem, &ptPosition)) return FALSE;
+ lprc->top = ptPosition.y;
+ lprc->bottom = lprc->top + infoPtr->nItemHeight;
- if (flags & LVIR_ICON)
+ switch(lprc->left)
{
+ case LVIR_ICON:
FIXME("Unimplemented LVIR_ICON\n");
return FALSE;
- }
- else
- {
- int top = min(Header_GetItemCount(infoPtr->hwndHeader), nSubItem - 1);
-
- LISTVIEW_GetItemRect(infoPtr,nItem,lprc);
- for (count = 0; count < top; count++)
- lprc->left += LISTVIEW_GetColumnWidth(infoPtr,count);
-
- lprc->right = LISTVIEW_GetColumnWidth(infoPtr,(nSubItem-1)) +
- lprc->left;
- }
+ case LVIR_LABEL:
+ case LVIR_BOUNDS:
+ /* nothing to do here, we're done */
+ break;
+ default:
+ ERR("Unknown bounds=%d\n", lprc->left);
+ return FALSE;
+ }
return TRUE;
}
@@ -8621,8 +8662,7 @@
return LISTVIEW_GetStringWidthT(infoPtr, (LPCWSTR)lParam, TRUE);
case LVM_GETSUBITEMRECT:
- return LISTVIEW_GetSubItemRect(infoPtr, (UINT)wParam, ((LPRECT)lParam)->top,
- ((LPRECT)lParam)->left, (LPRECT)lParam);
+ return LISTVIEW_GetSubItemRect(infoPtr, (UINT)wParam, (LPRECT)lParam);
case LVM_GETTEXTBKCOLOR:
return infoPtr->clrTextBk;
More information about the wine-patches
mailing list