Listview N1

Dimitrie O. Paun dpaun at rogers.com
Thu Oct 10 00:47:39 CDT 2002


ChangeLog
  Rework the mouse click notifications
  Assorted cleanups, and simplifications.

--- dlls/comctl32/listview.c.N0	Thu Oct 10 00:36:37 2002
+++ dlls/comctl32/listview.c	Thu Oct 10 01:45:04 2002
@@ -177,8 +177,6 @@
   BOOL bIsDrawing;
 } LISTVIEW_INFO;
 
-DEFINE_COMMON_NOTIFICATIONS(LISTVIEW_INFO, hwndSelf);
-
 /*
  * constants
  */
@@ -244,6 +242,9 @@
 #define LV_FL_DT_FLAGS  (DT_TOP | DT_NOPREFIX | DT_EDITCONTROL | DT_CENTER | DT_WORDBREAK | DT_NOCLIP)
 #define LV_SL_DT_FLAGS  (DT_TOP | DT_EDITCONTROL | DT_SINGLELINE | DT_WORD_ELLIPSIS | DT_END_ELLIPSIS)
 
+/* The time in milisecods to reset the search in the list */
+#define KEY_DELAY       450
+
 /* Dump the LISTVIEW_INFO structure to the debug channel */
 #define LISTVIEW_DUMP(iP) do { \
   TRACE("hwndSelf=%08x, clrBk=0x%06lx, clrText=0x%06lx, clrTextBk=0x%06lx, ItemHeight=%d, ItemWidth=%d, Style=0x%08lx\n", \
@@ -292,7 +293,6 @@
 static LRESULT LISTVIEW_Command(LISTVIEW_INFO *, WPARAM, LPARAM);
 static LRESULT LISTVIEW_SortItems(LISTVIEW_INFO *, PFNLVCOMPARE, LPARAM);
 static LRESULT LISTVIEW_GetStringWidthT(LISTVIEW_INFO *, LPCWSTR, BOOL);
-static INT LISTVIEW_ProcessLetterKeys(LISTVIEW_INFO *, WPARAM, LPARAM);
 static BOOL LISTVIEW_KeySelection(LISTVIEW_INFO *, INT);
 static LRESULT LISTVIEW_GetItemState(LISTVIEW_INFO *, INT, UINT);
 static LRESULT LISTVIEW_SetItemState(LISTVIEW_INFO *, INT, LPLVITEMW);
@@ -303,9 +303,6 @@
 static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *, INT, BOOL);
 static HWND CreateEditLabelT(LISTVIEW_INFO *, LPCWSTR, DWORD, INT, INT, INT, INT, BOOL);
 
-/******** Defines that LISTVIEW_ProcessLetterKeys uses ****************/
-#define KEY_DELAY       450
-
 /******** Text handling functions *************************************/
 
 /* A text pointer is either NULL, LPSTR_TEXTCALLBACK, or points to a
@@ -536,7 +533,7 @@
 
 /******** Notification functions i************************************/
 
-static inline BOOL notify(LISTVIEW_INFO *infoPtr, INT code, LPNMHDR pnmh)
+static inline BOOL notify_hdr(LISTVIEW_INFO *infoPtr, INT code, LPNMHDR pnmh)
 {
     pnmh->hwndFrom = infoPtr->hwndSelf;
     pnmh->idFrom = GetWindowLongW(infoPtr->hwndSelf, GWL_ID);
@@ -545,15 +542,31 @@
 			      (WPARAM)pnmh->idFrom, (LPARAM)pnmh);
 }
 
-static inline void notify_itemactivate(LISTVIEW_INFO *infoPtr)
+static inline BOOL notify(LISTVIEW_INFO *infoPtr, INT code)
 {
     NMHDR nmh;
-    notify(infoPtr, LVN_ITEMACTIVATE, &nmh);
+    return notify_hdr(infoPtr, code, &nmh);
+}
+
+static inline void notify_itemactivate(LISTVIEW_INFO *infoPtr)
+{
+    notify(infoPtr, LVN_ITEMACTIVATE);
 }
 
 static inline BOOL notify_listview(LISTVIEW_INFO *infoPtr, INT code, LPNMLISTVIEW plvnm)
 {
-    return notify(infoPtr, code, (LPNMHDR)plvnm);
+    return notify_hdr(infoPtr, code, (LPNMHDR)plvnm);
+}
+
+static BOOL notify_click(LISTVIEW_INFO *infoPtr,  INT code, LVHITTESTINFO *lvht)
+{
+    NMLISTVIEW nmlv;
+    
+    ZeroMemory(&nmlv, sizeof(nmlv));
+    nmlv.iItem = lvht->iItem;
+    nmlv.iSubItem = lvht->iSubItem;
+    nmlv.ptAction = lvht->pt;
+    return notify_listview(infoPtr, NM_RCLICK, &nmlv);
 }
 
 static int get_ansi_notification(INT unicodeNotificationCode)
@@ -626,7 +639,7 @@
 	realNotifCode = get_ansi_notification(notificationCode);
     else
 	realNotifCode = notificationCode;
-    bResult = notify(infoPtr, realNotifCode, (LPNMHDR)pdi);
+    bResult = notify_hdr(infoPtr, realNotifCode, (LPNMHDR)pdi);
 
     if (convertToUnicode || convertToAnsi)
     {
@@ -649,7 +662,7 @@
 
     nmlv.iFrom = range.lower;
     nmlv.iTo   = range.upper;
-    notify(infoPtr, LVN_ODCACHEHINT, &nmlv.hdr);
+    notify_hdr(infoPtr, LVN_ODCACHEHINT, &nmlv.hdr);
 }
 
 static BOOL notify_customdraw (LISTVIEW_INFO *infoPtr, DWORD dwDrawStage, HDC hdc, RECT rc)
@@ -667,7 +680,7 @@
     nmlvcd.clrText          = infoPtr->clrText;
     nmlvcd.clrTextBk        = infoPtr->clrBk;
 
-    return (BOOL)notify(infoPtr, NM_CUSTOMDRAW, &nmlvcd.nmcd.hdr);
+    return (BOOL)notify_hdr(infoPtr, NM_CUSTOMDRAW, &nmlvcd.nmcd.hdr);
 }
 
 /* FIXME: we should inline this where it's called somehow
@@ -709,7 +722,7 @@
           nmlvcd.nmcd.dwDrawStage, nmlvcd.nmcd.hdc, nmlvcd.nmcd.dwItemSpec,
           nmlvcd.nmcd.uItemState, nmlvcd.nmcd.lItemlParam);
 
-    bReturn = notify(infoPtr, NM_CUSTOMDRAW, &nmlvcd.nmcd.hdr);
+    bReturn = notify_hdr(infoPtr, NM_CUSTOMDRAW, &nmlvcd.nmcd.hdr);
 
     infoPtr->clrText = nmlvcd.clrText;
     infoPtr->clrBk   = nmlvcd.clrTextBk;
@@ -978,7 +991,7 @@
     INT endidx,idx;
     LVITEMW item;
     WCHAR buffer[MAX_PATH];
-    DWORD timestamp,elapsed;
+    DWORD lastKeyPressTimestamp = infoPtr->lastKeyPressTimestamp;
 
     /* simple parameter checking */
     if (!charCode || !keyData) return 0;
@@ -999,23 +1012,13 @@
     /* if there's one item or less, there is no where to go */
     if (infoPtr->nItemCount <= 1) return 0;
 
-    /* compute how much time elapsed since last keypress */
-    timestamp=GetTickCount();
-    if (timestamp > infoPtr->lastKeyPressTimestamp) {
-        elapsed=timestamp-infoPtr->lastKeyPressTimestamp;
-    } else {
-        elapsed=infoPtr->lastKeyPressTimestamp-timestamp;
-    }
-
     /* update the search parameters */
-    infoPtr->lastKeyPressTimestamp=timestamp;
-    if (elapsed < KEY_DELAY) {
-        if (infoPtr->nSearchParamLength < MAX_PATH) {
+    infoPtr->lastKeyPressTimestamp = GetTickCount();
+    if (infoPtr->lastKeyPressTimestamp - lastKeyPressTimestamp < KEY_DELAY) {
+        if (infoPtr->nSearchParamLength < MAX_PATH)
             infoPtr->szSearchParam[infoPtr->nSearchParamLength++]=charCode;
-        }
-        if (infoPtr->charCode != charCode) {
-            infoPtr->charCode=charCode=0;
-        }
+        if (infoPtr->charCode != charCode)
+            infoPtr->charCode = charCode = 0;
     } else {
         infoPtr->charCode=charCode;
         infoPtr->szSearchParam[0]=charCode;
@@ -7457,15 +7460,15 @@
   /* send LVN_KEYDOWN notification */
   nmKeyDown.wVKey = nVirtualKey;
   nmKeyDown.flags = 0;
-  notify(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr);
+  notify_hdr(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr);
 
   switch (nVirtualKey)
   {
   case VK_RETURN:
     if ((infoPtr->nItemCount > 0) && (infoPtr->nFocusedItem != -1))
     {
-      notify_return(infoPtr);
-      notify_itemactivate(infoPtr);
+      notify(infoPtr, NM_RETURN);
+      notify(infoPtr, LVN_ITEMACTIVATE);
     }
     break;
 
@@ -7538,7 +7541,7 @@
     if (!infoPtr->bFocus) return 0;
    
     /* send NM_KILLFOCUS notification */
-    notify_killfocus(infoPtr);
+    notify(infoPtr, NM_KILLFOCUS);
 
     /* if we have a focus rectagle, get rid of it */
     LISTVIEW_ShowFocusRect(infoPtr, FALSE);
@@ -7567,24 +7570,21 @@
 static LRESULT LISTVIEW_LButtonDblClk(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
 {
     LVHITTESTINFO htInfo;
-    NMLISTVIEW nmlv;
 
     TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);
 
+    /* send NM_RELEASEDCAPTURE notification */
+    notify(infoPtr, NM_RELEASEDCAPTURE);
+
     htInfo.pt.x = pts.x;
     htInfo.pt.y = pts.y;
 
     /* send NM_DBLCLK notification */
-    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
     LISTVIEW_HitTest(infoPtr, &htInfo, TRUE, FALSE);
-    nmlv.iItem = htInfo.iItem;
-    nmlv.iSubItem = htInfo.iSubItem;
-    nmlv.ptAction = htInfo.pt;
-    notify_listview(infoPtr, NM_DBLCLK, &nmlv);
+    notify_click(infoPtr, NM_DBLCLK, &htInfo);
 
     /* To send the LVN_ITEMACTIVATE, it must be on an Item */
-    if(nmlv.iItem != -1)
-        notify_itemactivate(infoPtr);
+    if(htInfo.iItem != -1) notify(infoPtr, LVN_ITEMACTIVATE);
 
     return 0;
 }
@@ -7611,10 +7611,8 @@
 
   TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);
 
-  /* FIXME: NM_CLICK */
-  
   /* send NM_RELEASEDCAPTURE notification */
-  notify_releasedcapture(infoPtr);
+  notify(infoPtr, NM_RELEASEDCAPTURE);
 
   if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);
 
@@ -7704,7 +7702,6 @@
 static LRESULT LISTVIEW_LButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
 {
     LVHITTESTINFO lvHitTestInfo;
-    NMLISTVIEW nmlv;
     
     TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y);
 
@@ -7714,12 +7711,8 @@
     lvHitTestInfo.pt.y = pts.y;
 
     /* send NM_CLICK notification */
-    ZeroMemory(&nmlv, sizeof(NMLISTVIEW));
     LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
-    nmlv.iItem = lvHitTestInfo.iItem;
-    nmlv.iSubItem = lvHitTestInfo.iSubItem;
-    nmlv.ptAction = lvHitTestInfo.pt;
-    notify_listview(infoPtr, NM_CLICK, &nmlv);
+    notify_click(infoPtr, NM_CLICK, &lvHitTestInfo);
 
     /* set left button flag */
     infoPtr->bLButtonDown = FALSE;
@@ -7908,13 +7901,18 @@
  */
 static LRESULT LISTVIEW_RButtonDblClk(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
 {
+    LVHITTESTINFO lvHitTestInfo;
+    
     TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);
 
     /* send NM_RELEASEDCAPTURE notification */
-    notify_releasedcapture(infoPtr);
+    notify(infoPtr, NM_RELEASEDCAPTURE);
 
     /* send NM_RDBLCLK notification */
-    notify_rdblclk(infoPtr);
+    lvHitTestInfo.pt.x = pts.x;
+    lvHitTestInfo.pt.y = pts.y;
+    LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
+    notify_click(infoPtr, NM_RDBLCLK, &lvHitTestInfo);
 
     return 0;
 }
@@ -7934,15 +7932,12 @@
 static LRESULT LISTVIEW_RButtonDown(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
 {
     LVHITTESTINFO lvHitTestInfo;
-    NMLISTVIEW nmlv;
     INT nItem;
 
     TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);
 
-    /* FIXME: NM_CLICK */
-  
     /* send NM_RELEASEDCAPTURE notification */
-    notify_releasedcapture(infoPtr);
+    notify(infoPtr, NM_RELEASEDCAPTURE);
 
     /* make sure the listview control window has the focus */
     if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);
@@ -7967,14 +7962,6 @@
 	LISTVIEW_RemoveAllSelections(infoPtr);
     }
 
-
-    /* Send NM_RClICK notification */
-    ZeroMemory(&nmlv, sizeof(nmlv));
-    nmlv.iItem = lvHitTestInfo.iItem;
-    nmlv.iSubItem = lvHitTestInfo.iSubItem;
-    nmlv.ptAction = lvHitTestInfo.pt;
-    notify_listview(infoPtr, NM_RCLICK, &nmlv);
-
     return 0;
 }
 
@@ -7992,7 +7979,8 @@
  */
 static LRESULT LISTVIEW_RButtonUp(LISTVIEW_INFO *infoPtr, WORD wKey, POINTS pts)
 {
-    POINT pt = { pts.x, pts.y };
+    LVHITTESTINFO lvHitTestInfo;
+    POINT pt;
 
     TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y);
 
@@ -8001,14 +7989,21 @@
     /* set button flag */
     infoPtr->bRButtonDown = FALSE;
 
+    /* Send NM_RClICK notification */
+    lvHitTestInfo.pt.x = pts.x;
+    lvHitTestInfo.pt.y = pts.y;
+    LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
+    notify_click(infoPtr, NM_RCLICK, &lvHitTestInfo);
+
     /* Change to screen coordinate for WM_CONTEXTMENU */
+    pt = lvHitTestInfo.pt;
     ClientToScreen(infoPtr->hwndSelf, &pt);
 
     /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
     SendMessageW(infoPtr->hwndSelf, WM_CONTEXTMENU,
 		 (WPARAM)infoPtr->hwndSelf, MAKELPARAM(pt.x, pt.y));
 
-  return 0;
+    return 0;
 }
 
 
@@ -8061,7 +8056,7 @@
     if (infoPtr->bFocus) return 0;
    
     /* send NM_SETFOCUS notification */
-    notify_setfocus(infoPtr);
+    notify(infoPtr, NM_SETFOCUS);
 
     /* set window focus flag */
     infoPtr->bFocus = TRUE;




More information about the wine-patches mailing list