--- trunk/reactos/lib/comctl32/listview.c 2005-10-27 18:56:27 UTC (rev 18792)
+++ trunk/reactos/lib/comctl32/listview.c 2005-10-27 19:01:29 UTC (rev 18793)
@@ -769,10 +769,12 @@
return result;
}
-static inline LRESULT notify(LISTVIEW_INFO *infoPtr, INT code)
+static inline BOOL notify(LISTVIEW_INFO *infoPtr, INT code)
{
NMHDR nmh;
- return notify_hdr(infoPtr, code, &nmh);
+ HWND hwnd = infoPtr->hwndSelf;
+ notify_hdr(infoPtr, code, &nmh);
+ return IsWindow(hwnd);
}
static inline void notify_itemactivate(LISTVIEW_INFO *infoPtr, LVHITTESTINFO *htInfo)
@@ -813,11 +815,12 @@
return notify_hdr(infoPtr, code, (LPNMHDR)plvnm);
}
-static LRESULT notify_click(LISTVIEW_INFO *infoPtr, INT code, LVHITTESTINFO *lvht)
+static BOOL notify_click(LISTVIEW_INFO *infoPtr, INT code, LVHITTESTINFO *lvht)
{
NMLISTVIEW nmlv;
LVITEMW item;
-
+ HWND hwnd = infoPtr->hwndSelf;
+
TRACE("code=%d, lvht=%s\n", code, debuglvhittestinfo(lvht));
ZeroMemory(&nmlv, sizeof(nmlv));
nmlv.iItem = lvht->iItem;
@@ -827,14 +830,16 @@
item.iItem = lvht->iItem;
item.iSubItem = 0;
if (LISTVIEW_GetItemT(infoPtr, &item, TRUE)) nmlv.lParam = item.lParam;
- return notify_listview(infoPtr, code, &nmlv);
+ notify_listview(infoPtr, code, &nmlv);
+ return IsWindow(hwnd);
}
-static void notify_deleteitem(LISTVIEW_INFO *infoPtr, INT nItem)
+static BOOL notify_deleteitem(LISTVIEW_INFO *infoPtr, INT nItem)
{
NMLISTVIEW nmlv;
LVITEMW item;
-
+ HWND hwnd = infoPtr->hwndSelf;
+
ZeroMemory(&nmlv, sizeof (NMLISTVIEW));
nmlv.iItem = nItem;
item.mask = LVIF_PARAM;
@@ -842,6 +847,7 @@
item.iSubItem = 0;
if (LISTVIEW_GetItemT(infoPtr, &item, TRUE)) nmlv.lParam = item.lParam;
notify_listview(infoPtr, LVN_DELETEITEM, &nmlv);
+ return IsWindow(hwnd);
}
static int get_ansi_notification(INT unicodeNotificationCode)
@@ -3014,12 +3020,13 @@
* [I] nItem : item index
*
* RETURN:
- * None
+ * Whether the window is still valid.
*/
-static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
+static BOOL LISTVIEW_AddGroupSelection(LISTVIEW_INFO *infoPtr, INT nItem)
{
INT nFirst = min(infoPtr->nSelectionMark, nItem);
INT nLast = max(infoPtr->nSelectionMark, nItem);
+ HWND hwndSelf = infoPtr->hwndSelf;
NMLVODSTATECHANGE nmlv;
LVITEMW item;
BOOL bOldChange;
@@ -3048,7 +3055,10 @@
nmlv.uOldState = item.state;
notify_hdr(infoPtr, LVN_ODSTATECHANGED, (LPNMHDR)&nmlv);
+ if (!IsWindow(hwndSelf))
+ return FALSE;
infoPtr->bDoChangeNotify = bOldChange;
+ return TRUE;
}
@@ -3279,7 +3289,9 @@
notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv);
return 0;
- }
+ }
+ else
+ infoPtr->bLButtonDown = FALSE;
/* see if we are supposed to be tracking mouse hovering */
if(infoPtr->dwLvExStyle & LVS_EX_TRACKSELECT) {
@@ -3400,9 +3412,15 @@
/* send LVN_ITEMCHANGING notification, if the item is not being inserted */
/* and we are _NOT_ virtual (LVS_OWERNDATA), and change notifications */
/* are enabled */
- if(lpItem && !isNew && infoPtr->bDoChangeNotify &&
- notify_listview(infoPtr, LVN_ITEMCHANGING, &nmlv))
+ if(lpItem && !isNew && infoPtr->bDoChangeNotify)
+ {
+ HWND hwndSelf = infoPtr->hwndSelf;
+
+ if (notify_listview(infoPtr, LVN_ITEMCHANGING, &nmlv))
return FALSE;
+ if (!IsWindow(hwndSelf))
+ return FALSE;
+ }
/* copy information */
if (lpLVItem->mask & LVIF_TEXT)
@@ -3546,6 +3564,7 @@
static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, BOOL isW)
{
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+ HWND hwndSelf = infoPtr->hwndSelf;
LPWSTR pszText = NULL;
BOOL bResult, bChanged = FALSE;
@@ -3568,6 +3587,8 @@
bResult = set_sub_item(infoPtr, lpLVItem, TRUE, &bChanged);
else
bResult = set_main_item(infoPtr, lpLVItem, FALSE, TRUE, &bChanged);
+ if (!IsWindow(hwndSelf))
+ return FALSE;
/* redraw item, if necessary */
if (bChanged && !infoPtr->bIsDrawing)
@@ -4516,7 +4537,7 @@
LISTVIEW_SetItemState(infoPtr, nItem, &item);
/* send LVN_DELETEITEM notification. */
- notify_deleteitem(infoPtr, nItem);
+ if (!notify_deleteitem(infoPtr, nItem)) return FALSE;
/* we need to do this here, because we'll be deleting stuff */
if (uView == LVS_SMALLICON || uView == LVS_ICON)
@@ -4568,6 +4589,7 @@
*/
static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, LPWSTR pszText, BOOL isW)
{
+ HWND hwndSelf = infoPtr->hwndSelf;
NMLVDISPINFOW dispInfo;
TRACE("(pszText=%s, isW=%d)\n", debugtext_t(pszText, isW), isW);
@@ -4585,6 +4607,8 @@
/* Do we need to update the Item Text */
if (!notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW)) return FALSE;
+ if (!IsWindow(hwndSelf))
+ return FALSE;
if (!pszText) return TRUE;
if (!(infoPtr->dwStyle & LVS_OWNERDATA))
@@ -4625,6 +4649,7 @@
WCHAR szDispText[DISP_TEXT_SIZE] = { 0 };
NMLVDISPINFOW dispInfo;
RECT rect;
+ HWND hwndSelf = infoPtr->hwndSelf;
TRACE("(nItem=%d, isW=%d)\n", nItem, isW);
@@ -4662,6 +4687,8 @@
if (notify_dispinfoT(infoPtr, LVN_BEGINLABELEDITW, &dispInfo, isW))
{
+ if (!IsWindow(hwndSelf))
+ return 0;
SendMessageW(infoPtr->hwndEdit, WM_CLOSE, 0, 0);
infoPtr->hwndEdit = 0;
return 0;
@@ -6191,6 +6218,7 @@
ITEM_INFO *lpItem;
BOOL is_sorted, has_changed;
LVITEMW item;
+ HWND hwndSelf = infoPtr->hwndSelf;
TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
@@ -6264,6 +6292,8 @@
nmlv.iItem = nItem;
nmlv.lParam = lpItem->lParam;
notify_listview(infoPtr, LVN_INSERTITEM, &nmlv);
+ if (!IsWindow(hwndSelf))
+ return -1;
/* align items (set position of each item) */
if ((uView == LVS_SMALLICON || uView == LVS_ICON))
@@ -7969,6 +7999,7 @@
static LRESULT LISTVIEW_KeyDown(LISTVIEW_INFO *infoPtr, INT nVirtualKey, LONG lKeyData)
{
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+ HWND hwndSelf = infoPtr->hwndSelf;
INT nItem = -1;
NMLVKEYDOWN nmKeyDown;
@@ -7978,14 +8009,16 @@
nmKeyDown.wVKey = nVirtualKey;
nmKeyDown.flags = 0;
notify_hdr(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr);
+ if (!IsWindow(hwndSelf))
+ return 0;
switch (nVirtualKey)
{
case VK_RETURN:
if ((infoPtr->nItemCount > 0) && (infoPtr->nFocusedItem != -1))
{
- notify(infoPtr, NM_RETURN);
- notify(infoPtr, LVN_ITEMACTIVATE);
+ if (!notify(infoPtr, NM_RETURN)) return 0;
+ if (!notify(infoPtr, LVN_ITEMACTIVATE)) return 0;
}
break;
@@ -8017,7 +8050,13 @@
case VK_PRIOR:
if (uView == LVS_REPORT)
- nItem = infoPtr->nFocusedItem - LISTVIEW_GetCountPerColumn(infoPtr);
+ {
+ INT topidx = LISTVIEW_GetTopIndex(infoPtr);
+ if (infoPtr->nFocusedItem == topidx)
+ nItem = topidx - LISTVIEW_GetCountPerColumn(infoPtr) + 1;
+ else
+ nItem = topidx;
+ }
else
nItem = infoPtr->nFocusedItem - LISTVIEW_GetCountPerColumn(infoPtr)
* LISTVIEW_GetCountPerRow(infoPtr);
@@ -8026,7 +8065,14 @@
case VK_NEXT:
if (uView == LVS_REPORT)
- nItem = infoPtr->nFocusedItem + LISTVIEW_GetCountPerColumn(infoPtr);
+ {
+ INT topidx = LISTVIEW_GetTopIndex(infoPtr);
+ INT cnt = LISTVIEW_GetCountPerColumn(infoPtr);
+ if (infoPtr->nFocusedItem == topidx + cnt - 1)
+ nItem = infoPtr->nFocusedItem + cnt - 1;
+ else
+ nItem = topidx + cnt - 1;
+ }
else
nItem = infoPtr->nFocusedItem + LISTVIEW_GetCountPerColumn(infoPtr)
* LISTVIEW_GetCountPerRow(infoPtr);
@@ -8058,7 +8104,7 @@
if (!infoPtr->bFocus) return 0;
/* send NM_KILLFOCUS notification */
- notify(infoPtr, NM_KILLFOCUS);
+ if (!notify(infoPtr, NM_KILLFOCUS)) return 0;
/* if we have a focus rectagle, get rid of it */
LISTVIEW_ShowFocusRect(infoPtr, FALSE);
@@ -8091,14 +8137,14 @@
TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, x, y);
/* send NM_RELEASEDCAPTURE notification */
- notify(infoPtr, NM_RELEASEDCAPTURE);
+ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0;
htInfo.pt.x = x;
htInfo.pt.y = y;
/* send NM_DBLCLK notification */
LISTVIEW_HitTest(infoPtr, &htInfo, TRUE, FALSE);
- notify_click(infoPtr, NM_DBLCLK, &htInfo);
+ if (!notify_click(infoPtr, NM_DBLCLK, &htInfo)) return 0;
/* To send the LVN_ITEMACTIVATE, it must be on an Item */
if(htInfo.iItem != -1) notify_itemactivate(infoPtr,&htInfo);
@@ -8128,7 +8174,7 @@
TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, x, y);
/* send NM_RELEASEDCAPTURE notification */
- notify(infoPtr, NM_RELEASEDCAPTURE);
+ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0;
if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);
@@ -8171,7 +8217,7 @@
{
if (bGroupSelect)
{
- LISTVIEW_AddGroupSelection(infoPtr, nItem);
+ if (!LISTVIEW_AddGroupSelection(infoPtr, nItem)) return 0;
LISTVIEW_SetItemFocus(infoPtr, nItem);
infoPtr->nSelectionMark = nItem;
}
@@ -8246,7 +8292,7 @@
/* send NM_CLICK notification */
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
- notify_click(infoPtr, NM_CLICK, &lvHitTestInfo);
+ if (!notify_click(infoPtr, NM_CLICK, &lvHitTestInfo)) return 0;
/* set left button flag */
infoPtr->bLButtonDown = FALSE;
@@ -8321,6 +8367,7 @@
static LRESULT LISTVIEW_HeaderNotification(LISTVIEW_INFO *infoPtr, const NMHEADERW *lpnmh)
{
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
+ HWND hwndSelf = infoPtr->hwndSelf;
TRACE("(lpnmh=%p)\n", lpnmh);
@@ -8334,6 +8381,8 @@
case HDN_ITEMCHANGEDW:
case HDN_ITEMCHANGEDA:
notify_forward_header(infoPtr, lpnmh);
+ if (!IsWindow(hwndSelf))
+ break;
/* Fall through */
case HDN_TRACKW:
case HDN_TRACKA:
@@ -8564,7 +8613,7 @@
TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, x, y);
/* send NM_RELEASEDCAPTURE notification */
- notify(infoPtr, NM_RELEASEDCAPTURE);
+ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0;
/* send NM_RDBLCLK notification */
lvHitTestInfo.pt.x = x;
@@ -8595,7 +8644,7 @@
TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, x, y);
/* send NM_RELEASEDCAPTURE notification */
- notify(infoPtr, NM_RELEASEDCAPTURE);
+ if (!notify(infoPtr, NM_RELEASEDCAPTURE)) return 0;
/* make sure the listview control window has the focus */
if (!infoPtr->bFocus) SetFocus(infoPtr->hwndSelf);
@@ -8651,7 +8700,7 @@
lvHitTestInfo.pt.x = x;
lvHitTestInfo.pt.y = y;
LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, FALSE);
- notify_click(infoPtr, NM_RCLICK, &lvHitTestInfo);
+ if (!notify_click(infoPtr, NM_RCLICK, &lvHitTestInfo)) return 0;
/* Change to screen coordinate for WM_CONTEXTMENU */
pt = lvHitTestInfo.pt;
@@ -8714,7 +8763,7 @@
if (infoPtr->bFocus) return 0;
/* send NM_SETFOCUS notification */
- notify(infoPtr, NM_SETFOCUS);
+ if (!notify(infoPtr, NM_SETFOCUS)) return 0;
/* set window focus flag */
infoPtr->bFocus = TRUE;