Listview M4

Dimitrie O. Paun dpaun at rogers.com
Tue Oct 8 09:13:10 CDT 2002


Heh, the last patch (M3) was nick named 'For the love of cool cars' :)

ChangeLog
  Factor out owner draw code, so that it works for all modes
  Documentation updates.

--- dlls/comctl32/listview.c.M3	Tue Oct  8 09:35:19 2002
+++ dlls/comctl32/listview.c	Tue Oct  8 10:09:59 2002
@@ -3249,11 +3249,89 @@
 
 /***
  * DESCRIPTION:
+ * Draws listview items when in owner draw mode.
+ *
+ * PARAMETER(S):
+ * [I] infoPtr : valid pointer to the listview structure
+ * [I] hdc : device context handle
+ *
+ * RETURN:
+ * None
+ */
+static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, HDC hdc)
+{
+    INT nTop, nItem, nLast, nUpdateHeight, nUpdateWidth, rgntype;
+    UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
+    HWND hwndParent = GetParent(infoPtr->hwndSelf);
+    POINT Origin, Position;
+    DRAWITEMSTRUCT dis;
+    LVITEMW item;
+    RECT rcClip;
+    
+    TRACE("()\n");
+
+    /* figure out what to draw */
+    /* FIXME: this works for REPORT only */
+    rgntype = GetClipBox(hdc, &rcClip);
+    if (rgntype == NULLREGION) return;
+    nUpdateHeight = rcClip.bottom - rcClip.top + 1;
+    nUpdateWidth = rcClip.right - rcClip.left;
+    nTop = LISTVIEW_GetTopIndex(infoPtr);
+    nItem = nTop + (rcClip.top - infoPtr->rcList.top) / infoPtr->nItemHeight;
+    if (nItem < nTop)
+        nItem = nTop;
+    nLast = nItem + nUpdateHeight / infoPtr->nItemHeight;
+    if (nUpdateHeight % infoPtr->nItemHeight) nLast++;
+    if (nLast > infoPtr->nItemCount)
+        nLast = infoPtr->nItemCount;
+    ZeroMemory(&dis, sizeof(dis));
+    
+    /* Get scroll info once before loop */
+    if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return;
+    
+
+    /* send cache hint notification */
+    if (infoPtr->dwStyle & LVS_OWNERDATA) 
+	notify_odcachehint(infoPtr, nItem, nLast);
+
+    /* iterate through the invalidated rows */ 
+    for (; nItem < nLast; nItem++)
+    {
+	item.iItem = nItem;
+	item.iSubItem = 0;
+	item.mask = LVIF_PARAM | LVIF_STATE;
+	item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
+	if (!LISTVIEW_GetItemW(infoPtr, &item)) continue;
+	   
+	dis.CtlType = ODT_LISTVIEW;
+	dis.CtlID = uID;
+	dis.itemID = nItem;
+	dis.itemAction = ODA_DRAWENTIRE;
+	dis.itemState = 0;
+	if (item.state & LVIS_SELECTED) dis.itemState |= ODS_SELECTED;
+	if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
+	dis.hwndItem = infoPtr->hwndSelf;
+	dis.hDC = hdc;
+	if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position)) continue;
+	dis.rcItem.left = Position.x + Origin.x;
+	dis.rcItem.right = dis.rcItem.left + infoPtr->nItemWidth;
+	dis.rcItem.top = Position.y + Origin.y;
+	dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
+	dis.itemData = item.lParam;
+
+	TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
+	SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
+    }
+}
+
+/***
+ * DESCRIPTION:
  * Draws listview items when in report display mode.
  *
  * PARAMETER(S):
  * [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
  *
  * RETURN:
  * None
@@ -3266,8 +3344,6 @@
     RECT rcItem, rcClip, rcFullSelect;
     BOOL bFullSelected, isFocused;
     DWORD cditemmode = CDRF_DODEFAULT;
-    LONG lStyle = infoPtr->dwStyle;
-    UINT uID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
     TEXTATTR tmpTa, oldTa;
     COLUMNCACHE *lpCols;
     LVCOLUMNW lvColumn;
@@ -3291,7 +3367,7 @@
         nLast = infoPtr->nItemCount;
 
     /* send cache hint notification */
-    if (lStyle & LVS_OWNERDATA) 
+    if (infoPtr->dwStyle & LVS_OWNERDATA) 
 	notify_odcachehint(infoPtr, nItem, nLast);
 
     /* cache column info */
@@ -3341,45 +3417,6 @@
     /* iterate through the invalidated rows */ 
     for (; nItem < nLast; nItem++, nDrawPosY += infoPtr->nItemHeight)
     {
-	/* if owner wants to take a first stab at it, have it his way... */
-	if (lStyle & LVS_OWNERDRAWFIXED)
-	{
-            DRAWITEMSTRUCT dis;
-
-            TRACE("Owner Drawn\n");
-
-            item.iItem = nItem;
-	    item.iSubItem = 0;
-            item.mask = LVIF_PARAM | LVIF_STATE;
-	    item.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
-	    if (!LISTVIEW_GetItemW(infoPtr, &item)) continue;
-	   
-	    ZeroMemory(&dis, sizeof(dis)); 
-            dis.CtlType = ODT_LISTVIEW;
-            dis.CtlID = uID;
-            dis.itemID = nItem;
-            dis.itemAction = ODA_DRAWENTIRE;
-            if (item.state & LVIS_SELECTED) dis.itemState |= ODS_SELECTED;
-            if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
-            dis.hwndItem = infoPtr->hwndSelf;
-            dis.hDC = hdc;
-            dis.rcItem.left = lpCols[0].rc.left;
-            dis.rcItem.right = lpCols[nColumnCount - 1].rc.right;
-            dis.rcItem.top = nDrawPosY;
-            dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
-            OffsetRect(&dis.rcItem, ptOrig.x, 0);
-            dis.itemData = item.lParam;
-
-	    TRACE("item=%s, rcItem=%s\n", debuglvitem_t(&item, TRUE), debugrect(&dis.rcItem));
-            SendMessageW(GetParent(infoPtr->hwndSelf), WM_DRAWITEM, dis.CtlID, (LPARAM)&dis);
-	    /* In theory we should do the default drawing if WM_DRAWITEM 
-	     * returns FALSE but, in the words of Larry McVoy, in practice
-	     * theory is different than practice, and hence there are 
-	     * important apps out there that depend on no default drawing
-	     * in LVS_OWNERDRAWFIXED. So we always skip to the next item. */
-	    continue;
-        }
-	
 	/* compute the full select rectangle, if needed */
 	if (bFullSelected)
 	{
@@ -3444,7 +3481,8 @@
  *
  * PARAMETER(S):
  * [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
  *
  * RETURN:
  * None
@@ -3501,7 +3539,8 @@
  *
  * PARAMETER(S):
  * [I] infoPtr : valid pointer to the listview structure
- * [I] HDC : device context handle
+ * [I] hdc : device context handle
+ * [I] cdmode : custom draw mode
  *
  * RETURN:
  * None
@@ -3637,7 +3676,9 @@
     /* select font */
     hOldFont = SelectObject(hdc, infoPtr->hFont);
 
-    if (uView == LVS_LIST)
+    if (infoPtr->dwStyle & LVS_OWNERDRAWFIXED)
+	LISTVIEW_RefreshOwnerDraw(infoPtr, hdc);
+    else if (uView == LVS_LIST)
 	LISTVIEW_RefreshList(infoPtr, hdc, cdmode);
     else if (uView == LVS_REPORT)
 	LISTVIEW_RefreshReport(infoPtr, hdc, cdmode);




More information about the wine-patches mailing list