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;