Listview K3
Dimitrie O. Paun
dpaun at rogers.com
Thu Oct 3 23:41:41 CDT 2002
ChangeLog
Fix large item focus handling for virtual listviews.
Since at most _one_ item can have the focus at any time,
we can maintain one such rectangle per list, rather than
per item. This is both more efficient, and works for
LVS_OWNERDATA listviews as well.
--- dlls/comctl32/listview.c.K2 Thu Oct 3 23:51:46 2002
+++ dlls/comctl32/listview.c Fri Oct 4 00:22:58 2002
@@ -102,7 +102,6 @@
INT iIndent;
POINT ptPosition;
BOOL valid;
- RECT rcLastDraw;
} LISTVIEW_ITEM;
typedef struct tagRANGE
@@ -151,6 +150,7 @@
BOOL bFocus;
INT nFocusedItem;
RECT rcFocus;
+ RECT rcLargeFocus; /* non-empty when a large item in ICON mode has focus */
DWORD dwStyle; /* the cached window GWL_STYLE */
DWORD dwLvExStyle; /* extended listview style */
HDPA hdpaItems;
@@ -2454,80 +2454,6 @@
}
- /***
- * DESCRIPTION: [INTERNAL]
- * Sets rectangle that the item was last drawn at.
- *
- * PARAMETER(S):
- * [I] HWND : window handle
- * [I] INT : item index
- * [I] LPRECT : coordinate information
- *
- * RETURN:
- * SUCCESS : TRUE
- * FAILURE : FALSE
- */
-static BOOL LISTVIEW_SetItemDrawRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lpRect)
-{
- BOOL bResult = FALSE;
- HDPA hdpaSubItems;
- LISTVIEW_ITEM *lpItem;
-
- TRACE("(hwnd=%x,nItem=%d,rect=(%d,%d)-(%d,%d))\n",
- infoPtr->hwndSelf, nItem,
- lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
-
- if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && (lpRect != NULL))
- {
- if ((hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)))
- {
- if ((lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)))
- {
- bResult = TRUE;
- lpItem->rcLastDraw = *lpRect;
- }
- }
- }
- return bResult;
-}
-
- /***
- * DESCRIPTION: [INTERNAL]
- * Gets rectangle that the item was last drawn at.
- *
- * PARAMETER(S):
- * [I] HWND : window handle
- * [I] INT : item index
- * [O] LPRECT : coordinate information
- *
- * RETURN:
- * SUCCESS : TRUE
- * FAILURE : FALSE
- */
-static BOOL LISTVIEW_GetItemDrawRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lpRect)
-{
- BOOL bResult = FALSE;
- HDPA hdpaSubItems;
- LISTVIEW_ITEM *lpItem;
-
- if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && (lpRect != NULL))
- {
- if ((hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, nItem)))
- {
- if ((lpItem = (LISTVIEW_ITEM *)DPA_GetPtr(hdpaSubItems, 0)))
- {
- bResult = TRUE;
- if (lpRect) *lpRect = lpItem->rcLastDraw;
- TRACE("(hwnd=%x,nItem=%d,rect=(%d,%d)-(%d,%d))\n",
- infoPtr->hwndSelf, nItem,
- lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
- }
- }
- }
- return bResult;
-}
-
-
/***
* Tests wheather the item is assignable to a list with style lStyle
*/
@@ -2827,30 +2753,18 @@
/* redraw item, if necessary */
if (bResult && !infoPtr->bIsDrawing)
{
- RECT rcOldItem={0,0,0,0};
-
if (oldFocus != infoPtr->nFocusedItem && infoPtr->bFocus)
- LISTVIEW_ToggleFocusRect(infoPtr);
-
- /* Note that ->rcLastDraw is normally all zero, so
- * no second InvalidateRect is issued.
- *
- * However, when a large icon style is drawn (LVS_ICON),
- * the rectangle drawn is saved in rcLastDraw. That way
- * the InvalidateRect will invalidate the entire area drawn
- *
- * FIXME: this is not right. We have already a ton of rects,
- * we have two functions to get to them (GetItemRect,
- * and GetItemMeasurements), and we introduce yet
- * another rectangle with setter/getter functions!!!
- * This is too much. Besides, this does not work
- * correctly for owner drawn control...
- */
- if ((oldFocus >= 0) && (oldFocus < GETITEMCOUNT(infoPtr)))
{
- LISTVIEW_GetItemDrawRect(infoPtr, oldFocus, &rcOldItem);
- if(!IsRectEmpty(&rcOldItem))
- LISTVIEW_InvalidateRect(infoPtr, &rcOldItem);
+ LISTVIEW_ToggleFocusRect(infoPtr);
+ /* Note that ->rcLargeFocus is normally all zero, so
+ * no second InvalidateRect is issued.
+ *
+ * However, when a large icon style is drawn (LVS_ICON),
+ * the rectangle drawn is saved in rcLastDraw. That way
+ * the InvalidateRect will invalidate the entire area drawn
+ */
+ if (!IsRectEmpty(&infoPtr->rcLargeFocus))
+ LISTVIEW_InvalidateRect(infoPtr, &infoPtr->rcLargeFocus);
}
LISTVIEW_InvalidateItem(infoPtr, lpLVItem->iItem);
}
@@ -3266,6 +3180,7 @@
* that the background is complete
*/
rcFocus = rcLabel; /* save for focus */
+ SetRectEmpty(&infoPtr->rcLargeFocus);
if ((uFormat & DT_NOCLIP) || (lvItem.state & LVIS_SELECTED))
{
/* FIXME: why do we need this??? */
@@ -3276,7 +3191,7 @@
DeleteObject(hBrush);
/* Save size of item drawing for next InvalidateRect */
- LISTVIEW_SetItemDrawRect(infoPtr, nItem, &rcFullText);
+ infoPtr->rcLargeFocus = rcFullText;
TRACE("focused/selected, rcFocus=%s\n", debugrect(&rcFocus));
}
/* else ? What if we are losing the focus? will we not get a complete
More information about the wine-patches
mailing list