Listview V10

Dimitrie O. Paun dpaun at rogers.com
Sun Oct 20 18:37:13 CDT 2002


ChangeLog
  Reorganize header notifications
  Support notifications that don't have embedded size info
  Invalidate columns on format change (if needed)
  Assorted cleanups.

--- dlls/comctl32/listview.c.V9	Sun Oct 20 17:38:55 2002
+++ dlls/comctl32/listview.c	Sun Oct 20 19:33:54 2002
@@ -30,7 +30,7 @@
  *   -- Support CustonDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs)
  *
  * Notifications:
- *   LISTVIEW_Notify : most notifications from children (editbox and header)
+ *   LISTVIEW_Notify : most notifications from editbox
  *
  * Data structure:
  *   LISTVIEW_SetItemCount : not completed for non OWNERDATA
@@ -1059,6 +1059,22 @@
 
 /******** Internal API functions ************************************/
 
+static inline COLUMN_INFO * LISTVIEW_GetColumnInfo(LISTVIEW_INFO *infoPtr, INT nSubItem)
+{
+    assert (nSubItem >= 0 && nSubItem < infoPtr->hdpaColumns->nItemCount);
+    return (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
+}
+	
+static inline void LISTVIEW_GetHeaderRect(LISTVIEW_INFO *infoPtr, INT nSubItem, RECT *lprc)
+{
+    *lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader;
+}
+	
+static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
+{
+    return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE);
+}
+
 /* The Invalidate* are macros, so we preserve the caller location */
 #define LISTVIEW_InvalidateRect(infoPtr, rect) while(infoPtr->bRedraw) { \
     TRACE(" invalidating rect=%s\n", debugrect(rect)); \
@@ -1088,21 +1104,15 @@
 #define LISTVIEW_InvalidateList(infoPtr)\
     LISTVIEW_InvalidateRect(infoPtr, NULL)
 
-
-static inline COLUMN_INFO * LISTVIEW_GetColumnInfo(LISTVIEW_INFO *infoPtr, INT nSubItem)
-{
-    assert (nSubItem >= 0 && nSubItem < infoPtr->hdpaColumns->nItemCount);
-    return (COLUMN_INFO *)DPA_GetPtr(infoPtr->hdpaColumns, nSubItem);
-}
-	
-static inline void LISTVIEW_GetHeaderRect(LISTVIEW_INFO *infoPtr, INT nSubItem, RECT *lprc)
-{
-    *lprc = LISTVIEW_GetColumnInfo(infoPtr, nSubItem)->rcHeader;
-}
 	
-static inline BOOL LISTVIEW_GetItemW(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem)
+static inline void LISTVIEW_InvalidateColumn(LISTVIEW_INFO *infoPtr, INT nColumn)
 {
-    return LISTVIEW_GetItemT(infoPtr, lpLVItem, TRUE);
+    RECT rcCol;
+    
+    LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol);
+    rcCol.top = infoPtr->rcList.top;
+    rcCol.bottom = infoPtr->rcList.bottom;
+    LISTVIEW_InvalidateRect(infoPtr, &rcCol);
 }
 
 /***
@@ -4602,24 +4612,15 @@
  *   SUCCESS : image list handle
  *   FAILURE : NULL
  */
-static LRESULT LISTVIEW_GetImageList(LISTVIEW_INFO *infoPtr, INT nImageList)
+static HIMAGELIST LISTVIEW_GetImageList(LISTVIEW_INFO *infoPtr, INT nImageList)
 {
-  HIMAGELIST himl = NULL;
-
-  switch (nImageList)
-  {
-  case LVSIL_NORMAL:
-    himl = infoPtr->himlNormal;
-    break;
-  case LVSIL_SMALL:
-    himl = infoPtr->himlSmall;
-    break;
-  case LVSIL_STATE:
-    himl = infoPtr->himlState;
-    break;
-  }
-
-  return (LRESULT)himl;
+    switch (nImageList)
+    {
+    case LVSIL_NORMAL: return infoPtr->himlNormal;
+    case LVSIL_SMALL: return infoPtr->himlSmall;
+    case LVSIL_STATE: return infoPtr->himlState;
+    }
+    return NULL;
 }
 
 /* LISTVIEW_GetISearchString */
@@ -6040,8 +6041,18 @@
     bResult = SendMessageW(infoPtr->hwndHeader, isW ? HDM_SETITEMW : HDM_SETITEMA, (WPARAM)nColumn, (LPARAM)&hdi);
     if (!bResult) return FALSE;
 
-    if (lpColumn->mask & LVCF_FMT) 
-	LISTVIEW_GetColumnInfo(infoPtr, nColumn)->fmt = lpColumn->fmt;
+    if (lpColumn->mask & LVCF_FMT)
+    {
+	COLUMN_INFO *lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, nColumn);
+	int oldFmt = lpColumnInfo->fmt;
+	
+	lpColumnInfo->fmt = lpColumn->fmt;
+	if ((oldFmt ^ lpColumn->fmt) & (LVCFMT_JUSTIFYMASK | LVCFMT_IMAGE))
+	{
+	    UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+	    if (uView == LVS_REPORT) LISTVIEW_InvalidateColumn(infoPtr, nColumn);
+	}
+    }
 
     return TRUE;
 }
@@ -7540,7 +7551,7 @@
 
 /***
  * DESCRIPTION:
- * Handles notifications from children.
+ * Handles notifications from header.
  *
  * PARAMETER(S):
  * [I] infoPtr : valid pointer to the listview structure
@@ -7550,54 +7561,59 @@
  * RETURN:
  * Zero
  */
-static LRESULT LISTVIEW_Notify(LISTVIEW_INFO *infoPtr, INT nCtrlId, LPNMHDR lpnmh)
+static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, LPNMHEADERW lpnmh)
 {
     UINT uView =  infoPtr->dwStyle & LVS_TYPEMASK;
     
-    TRACE("(nCtrlId=%d, lpnmh=%p)\n", nCtrlId, lpnmh);
+    TRACE("(lpnmh=%p)\n", lpnmh);
 
-    /* handle notification from header control */
-    if (lpnmh->hwndFrom == infoPtr->hwndHeader)
-    {
-	LPNMHEADERW lphnm = (LPNMHEADERW)lpnmh;
-	
-	if (lpnmh->code == HDN_TRACKW       || lpnmh->code == HDN_TRACKA ||
-	    lpnmh->code == HDN_ITEMCHANGEDW || lpnmh->code == HDN_ITEMCHANGEDA)
+    if (!lpnmh || lpnmh->iItem < 0 || lpnmh->iItem >= infoPtr->hdpaColumns->nItemCount) return 0;
+    
+    switch (lpnmh->hdr.code)
+    {    
+	case HDN_TRACKW:
+	case HDN_TRACKA:
+	case HDN_ITEMCHANGEDW:
+	case HDN_ITEMCHANGEDA:
 	{
 	    COLUMN_INFO *lpColumnInfo;
-	    RECT rcCol;
-	    INT dx;
-
-	    if (lphnm->iItem < 0 || lphnm->iItem >= infoPtr->hdpaColumns->nItemCount) return 0;
-	    if (!lphnm->pitem || !(lphnm->pitem->mask & HDI_WIDTH)) return 0;
+	    INT dx, cxy;
 
-	    lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lphnm->iItem);
+	    if (!lpnmh->pitem || !(lpnmh->pitem->mask & HDI_WIDTH))
+	    {
+    		HDITEMW hdi;
+    
+		hdi.mask = HDI_WIDTH;
+    		if (!Header_GetItemW(infoPtr->hwndHeader, lpnmh->iItem, (LPARAM)&hdi)) return 0;
+		cxy = hdi.cxy;
+	    }
+	    else
+		cxy = lpnmh->pitem->cxy;
 	    
 	    /* determine how much we change since the last know position */
-	    dx = lphnm->pitem->cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
-	    
-	    /* ajust the column being tracked */
-	    lpColumnInfo->rcHeader.right += dx;
-	    
-	    /* compute the rectangle for the tracked column */
-	    rcCol.left = lpColumnInfo->rcHeader.left;
-	    rcCol.top = infoPtr->rcList.top;
-	    rcCol.right = lpColumnInfo->rcHeader.right;
-	    rcCol.bottom = infoPtr->rcList.bottom;
-	   
-	    LISTVIEW_ScrollColumns(infoPtr, lphnm->iItem + 1, dx);
-	    if (uView == LVS_REPORT) LISTVIEW_InvalidateRect(infoPtr, &rcCol);
+	    lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lpnmh->iItem);
+	    dx = cxy - (lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left);
+	    if (dx != 0)
+	    {
+		lpColumnInfo->rcHeader.right += dx;
+		LISTVIEW_ScrollColumns(infoPtr, lpnmh->iItem + 1, dx);
+		if (uView == LVS_REPORT) LISTVIEW_InvalidateColumn(infoPtr, lpnmh->iItem);
+	    }
 	}
-	else if(lpnmh->code ==  HDN_ITEMCLICKW || lpnmh->code ==  HDN_ITEMCLICKA)
+	break;
+
+	case HDN_ITEMCLICKW:
+	case HDN_ITEMCLICKA:
 	{
             /* Handle sorting by Header Column */
             NMLISTVIEW nmlv;
 
             ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
             nmlv.iItem = -1;
-            nmlv.iSubItem = lphnm->iItem;
+            nmlv.iSubItem = lpnmh->iItem;
             notify_listview(infoPtr, LVN_COLUMNCLICK, &nmlv);
         }
+	break;
     }
 
     return 0;
@@ -8195,7 +8211,7 @@
     return infoPtr->dwHoverTime;
 
   case LVM_GETIMAGELIST:
-    return LISTVIEW_GetImageList(infoPtr, (INT)wParam);
+    return (LRESULT)LISTVIEW_GetImageList(infoPtr, (INT)wParam);
 
   /* case LVN_GETINSERTMARK: */
 
@@ -8498,7 +8514,9 @@
     return LISTVIEW_NCDestroy(infoPtr);
 
   case WM_NOTIFY:
-    return LISTVIEW_Notify(infoPtr, (INT)wParam, (LPNMHDR)lParam);
+    if (lParam && ((LPNMHDR)lParam)->hwndFrom == infoPtr->hwndHeader)
+        return LISTVIEW_HeaderNotification(infoPtr, (LPNMHEADERW)lParam);
+    else return 0;
 
   case WM_NOTIFYFORMAT:
     return LISTVIEW_NotifyFormat(infoPtr, (HWND)wParam, (INT)lParam);




More information about the wine-patches mailing list