Commit e65eb614 authored by Dimitrie O. Paun's avatar Dimitrie O. Paun Committed by Alexandre Julliard

- Fix crashes in debug mode.

- Fix some focus rectangle problems. - Better debugging output. - More cleanups.
parent 48d8ff42
...@@ -175,6 +175,10 @@ DEFINE_COMMON_NOTIFICATIONS(LISTVIEW_INFO, hwndSelf); ...@@ -175,6 +175,10 @@ DEFINE_COMMON_NOTIFICATIONS(LISTVIEW_INFO, hwndSelf);
/* /*
* constants * constants
*/ */
/* How many we debug buffer to allocate */
#define DEBUG_BUFFERS 20
/* The size of a single debug bbuffer */
#define DEBUG_BUFFER_SIZE 256
/* Internal interface to LISTVIEW_HScroll and LISTVIEW_VScroll */ /* Internal interface to LISTVIEW_HScroll and LISTVIEW_VScroll */
#define SB_INTERNAL -1 #define SB_INTERNAL -1
...@@ -428,34 +432,87 @@ static inline LPCSTR debugtext_tn(LPCWSTR text, BOOL isW, INT n) ...@@ -428,34 +432,87 @@ static inline LPCSTR debugtext_tn(LPCWSTR text, BOOL isW, INT n)
return isW ? debugstr_wn(text, n) : debugstr_an((LPCSTR)text, n); return isW ? debugstr_wn(text, n) : debugstr_an((LPCSTR)text, n);
} }
static char* debuglvitem_t(LPLVITEMW lpLVItem, BOOL isW) static char* debug_getbuf()
{ {
static int index = 0; static int index = 0;
static char buffers[20][256]; static char buffers[DEBUG_BUFFERS][DEBUG_BUFFER_SIZE];
char* buf = buffers[index++ % 20]; return buffers[index++ % DEBUG_BUFFERS];
}
static char* debuglvitem_t(LPLVITEMW lpLVItem, BOOL isW)
{
char* buf = debug_getbuf(), *text = buf;
int len, size = DEBUG_BUFFER_SIZE;
if (lpLVItem == NULL) return "(null)"; if (lpLVItem == NULL) return "(null)";
snprintf(buf, 256, "{mask=%x, iItem=%d, iSubItem=%d, state=%x, stateMask=%x," len = snprintf(buf, size, "{iItem=%d, iSubItem=%d, ", lpLVItem->iItem, lpLVItem->iSubItem);
" pszText=%s, cchTextMax=%d, iImage=%d, lParam=%lx, iIndent=%d}", if (len == -1) goto end; buf += len; size -= len;
lpLVItem->mask, lpLVItem->iItem, lpLVItem->iSubItem, if (lpLVItem->mask & LVIF_STATE)
lpLVItem->state, lpLVItem->stateMask, len = snprintf(buf, size, "state=%x, stateMask=%x, ", lpLVItem->state, lpLVItem->stateMask);
lpLVItem->mask & LVIF_TEXT ? debugtext_tn(lpLVItem->pszText, isW, 80) : 0, else len = 0;
lpLVItem->cchTextMax, lpLVItem->iImage, lpLVItem->lParam, if (len == -1) goto end; buf += len; size -= len;
lpLVItem->iIndent); if (lpLVItem->mask & LVIF_TEXT)
return buf; len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpLVItem->pszText, isW, 80), lpLVItem->cchTextMax);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpLVItem->mask & LVIF_IMAGE)
len = snprintf(buf, size, "iImage=%d, ", lpLVItem->iImage);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpLVItem->mask & LVIF_PARAM)
len = snprintf(buf, size, "lParam=%lx, ", lpLVItem->lParam);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpLVItem->mask & LVIF_INDENT)
len = snprintf(buf, size, "iIndent=%d, ", lpLVItem->iIndent);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
goto undo;
end:
buf = text + strlen(text);
undo:
if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
return text;
} }
static char* debuglvcolumn_t(LPLVCOLUMNW lpColumn, BOOL isW) static char* debuglvcolumn_t(LPLVCOLUMNW lpColumn, BOOL isW)
{ {
static int index = 0; char* buf = debug_getbuf(), *text = buf;
static char buffers[20][256]; int len, size = DEBUG_BUFFER_SIZE;
char* buf = buffers[index++ % 20];
if (lpColumn == NULL) return "(null)"; if (lpColumn == NULL) return "(null)";
snprintf(buf, 256, "{mask=%x, fmt=%x, cx=%d," len = snprintf(buf, size, "{");
" pszText=%s, cchTextMax=%d, iSubItem=%d}", if (len == -1) goto end; buf += len; size -= len;
lpColumn->mask, lpColumn->fmt, lpColumn->cx, if (lpColumn->mask & LVCF_SUBITEM)
lpColumn->mask & LVCF_TEXT ? debugtext_tn(lpColumn->pszText, isW, 80): "", len = snprintf(buf, size, "iSubItem=%d, ", lpColumn->iSubItem);
lpColumn->mask & LVCF_TEXT ? lpColumn->cchTextMax: 0, lpColumn->iSubItem); else len = 0;
return buf; if (len == -1) goto end; buf += len; size -= len;
if (lpColumn->mask & LVCF_FMT)
len = snprintf(buf, size, "fmt=%x, ", lpColumn->fmt);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpColumn->mask & LVCF_WIDTH)
len = snprintf(buf, size, "cx=%d, ", lpColumn->cx);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpColumn->mask & LVCF_TEXT)
len = snprintf(buf, size, "pszText=%s, cchTextMax=%d, ", debugtext_tn(lpColumn->pszText, isW, 80), lpColumn->cchTextMax);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpColumn->mask & LVCF_IMAGE)
len = snprintf(buf, size, "iImage=%d, ", lpColumn->iImage);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
if (lpColumn->mask & LVCF_ORDER)
len = snprintf(buf, size, "iOrder=%d, ", lpColumn->iOrder);
else len = 0;
if (len == -1) goto end; buf += len; size -= len;
goto undo;
end:
buf = text + strlen(text);
undo:
if (buf - text > 2) buf[-2] = '}'; buf[-1] = 0;
return text;
} }
#if 0 #if 0
...@@ -1147,28 +1204,29 @@ static void LISTVIEW_UnsupportedStyles(LONG lStyle) ...@@ -1147,28 +1204,29 @@ static void LISTVIEW_UnsupportedStyles(LONG lStyle)
/*** /***
* DESCRIPTION: [INTERNAL] * DESCRIPTION: [INTERNAL]
* Compute sizes and rectangles of an item. This is to localize all * Compute sizes and rectangles of an item. This is to localize all
* the computations in one place. * the computations in one place. If you are not interested in some
* of these values, simply pass in a NULL.
* *
* supported for style: * supported for style:
* IC SI LI RP * IC SI LI RP
* PARAMETER(S): * PARAMETER(S):
* [I] HWND : window handle * [I] infoPtr : valid pointer to the listview structure
* [I] INT : item number * [I] nItem : item number
* [O] LPPOINT : ptr to Origin point or NULL x x x x * [O] lpptOrigin : ptr to Origin point x x x x
* [O] LPPOINT : ptr to Position point or NULL x x x x * [O] lpptPosition : ptr to Position point x x x x
* the Position point is relative to infoPtr->rcList * the Position point is relative to infoPtr->rcList
* (has *NOT* been adjusted by the origin) * (has *NOT* been adjusted by the origin)
* [O] LPRECT : ptr to Boundary rectangle or NULL x x x x * [O] lprcBoundary : ptr to Boundary rectangle x x x x
* the Boundary rectangle is relative to infoPtr->rcList * the Boundary rectangle is relative to infoPtr->rcList
* (has *NOT* been adjusted by the origin) * (has *NOT* been adjusted by the origin)
* [O] LPRECT : ptr to Icon rectangle or NULL x x x x * [O] lprcIcon : ptr to Icon rectangle x x x x
* the Icon rectangle is relative to infoPtr->rcView * the Icon rectangle is relative to infoPtr->rcView
* (has already been adjusted by the origin) * (has already been adjusted by the origin)
* [O] LPRECT : ptr to Label rectangle or NULL x x - - * [O] lprcLabel : ptr to Label rectangle x x - -
* - the Label rectangle is relative to infoPtr->rcView * - the Label rectangle is relative to infoPtr->rcView
* (has already been adjusted by the origin) * (has already been adjusted by the origin)
* - the Label rectangle encloses the label text only * - the Label rectangle encloses the label text only
* [O] LPRECT : ptr to FullText rectangle or NULL x x - - * [O] lprcFText : ptr to FullText rectangle x x - -
* - the FullText rectangle is relative to infoPtr->rcView * - the FullText rectangle is relative to infoPtr->rcView
* (has already been adjusted by the origin) * (has already been adjusted by the origin)
* - the FullText rectangle contains the Label rectangle * - the FullText rectangle contains the Label rectangle
...@@ -1178,58 +1236,53 @@ static void LISTVIEW_UnsupportedStyles(LONG lStyle) ...@@ -1178,58 +1236,53 @@ static void LISTVIEW_UnsupportedStyles(LONG lStyle)
* TRUE if computations OK * TRUE if computations OK
* FALSE otherwise * FALSE otherwise
*/ */
static BOOL LISTVIEW_GetAllMeasure(LISTVIEW_INFO *infoPtr, INT nItem, static BOOL LISTVIEW_GetAllMeasures(LISTVIEW_INFO *infoPtr, INT nItem,
LPPOINT lpptOrigin, LPPOINT lpptOrigin, LPPOINT lpptPosition,
LPPOINT lpptPosition, LPRECT lprcBoundary, LPRECT lprcIcon,
LPRECT lprcBoundary, LPRECT lprcLabel, LPRECT lprcFText)
LPRECT lprcIcon,
LPRECT lprcLabel,
LPRECT lprcFText)
{ {
LONG lStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE); LONG lStyle = GetWindowLongW(infoPtr->hwndSelf, GWL_STYLE);
UINT uView = lStyle & LVS_TYPEMASK; UINT uView = lStyle & LVS_TYPEMASK;
BOOL bResult = TRUE; BOOL bResult = TRUE;
HDPA hdpaSubItems; HDPA hdpaSubItems;
LISTVIEW_ITEM *lpItem; LISTVIEW_ITEM *lpItem;
POINT Origin, Position; POINT Origin, Position;
RECT Icon, Boundary, Label; RECT Icon, Boundary, Label;
INT nHorzPos = 0, nVertPos = 0; INT nHorzPos = 0, nVertPos = 0;
SCROLLINFO scrollInfo;
/************************************************************/ /************************************************************/
/* compute Origin point */ /* compute Origin point */
/* (we can always do this even with bad/invalid nItem) */ /* (we can always do this even with bad/invalid nItem) */
/************************************************************/ /************************************************************/
SCROLLINFO scrollInfo; scrollInfo.cbSize = sizeof(SCROLLINFO);
ZeroMemory(&Origin, sizeof(POINT)); scrollInfo.fMask = SIF_POS;
ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = SIF_POS;
if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) if ((lStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo))
nHorzPos = scrollInfo.nPos; nHorzPos = scrollInfo.nPos;
if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo))
nVertPos = scrollInfo.nPos; nVertPos = scrollInfo.nPos;
TRACE("nHorzPos=%d, nVertPos=%d\n", nHorzPos, nVertPos); TRACE("nHorzPos=%d, nVertPos=%d\n", nHorzPos, nVertPos);
Origin.x = infoPtr->rcList.left; Origin.x = infoPtr->rcList.left;
Origin.y = infoPtr->rcList.top; Origin.y = infoPtr->rcList.top;
if (uView == LVS_LIST) if (uView == LVS_LIST)
{ {
nHorzPos *= LISTVIEW_GetCountPerColumn(infoPtr); nHorzPos *= LISTVIEW_GetCountPerColumn(infoPtr);
nVertPos = 0; nVertPos = 0;
} }
else if (uView == LVS_REPORT) else if (uView == LVS_REPORT)
{ {
nVertPos *= infoPtr->nItemHeight; nVertPos *= infoPtr->nItemHeight;
} }
Origin.x -= nHorzPos; Origin.x -= nHorzPos;
Origin.y -= nVertPos; Origin.y -= nVertPos;
TRACE("hwnd=%x, item=%d, origin=(%ld,%ld)\n", TRACE("hwnd=%x, item=%d, origin=(%ld,%ld)\n",
infoPtr->hwndSelf, nItem, Origin.x, Origin.y); infoPtr->hwndSelf, nItem, Origin.x, Origin.y);
if (lpptOrigin) *lpptOrigin = Origin; if (lpptOrigin) *lpptOrigin = Origin;
/************************************************************/ /************************************************************/
...@@ -1284,15 +1337,7 @@ static BOOL LISTVIEW_GetAllMeasure(LISTVIEW_INFO *infoPtr, INT nItem, ...@@ -1284,15 +1337,7 @@ static BOOL LISTVIEW_GetAllMeasure(LISTVIEW_INFO *infoPtr, INT nItem,
infoPtr->nItemHeight) + infoPtr->rcList.top; infoPtr->nItemHeight) + infoPtr->rcList.top;
if (!(lStyle & LVS_NOSCROLL)) if (!(lStyle & LVS_NOSCROLL))
{ Boundary.left -= nHorzPos;
SCROLLINFO scrollInfo;
/* Adjust position by scrollbar offset */
ZeroMemory(&scrollInfo, sizeof(SCROLLINFO));
scrollInfo.cbSize = sizeof(SCROLLINFO);
scrollInfo.fMask = SIF_POS;
GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo);
Boundary.left -= scrollInfo.nPos;
}
} }
Boundary.right = Boundary.left + infoPtr->nItemWidth; Boundary.right = Boundary.left + infoPtr->nItemWidth;
Boundary.bottom = Boundary.top + infoPtr->nItemHeight; Boundary.bottom = Boundary.top + infoPtr->nItemHeight;
...@@ -2258,7 +2303,6 @@ static void LISTVIEW_SetSelection(LISTVIEW_INFO *infoPtr, INT nItem) ...@@ -2258,7 +2303,6 @@ static void LISTVIEW_SetSelection(LISTVIEW_INFO *infoPtr, INT nItem)
LISTVIEW_RemoveAllSelections(infoPtr); LISTVIEW_RemoveAllSelections(infoPtr);
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.state = LVIS_FOCUSED | LVIS_SELECTED; lvItem.state = LVIS_FOCUSED | LVIS_SELECTED;
lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED;
LISTVIEW_SetItemState(infoPtr, nItem, &lvItem); LISTVIEW_SetItemState(infoPtr, nItem, &lvItem);
...@@ -2598,9 +2642,6 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW) ...@@ -2598,9 +2642,6 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
NMLISTVIEW nmlv; NMLISTVIEW nmlv;
UINT uChanged = 0; UINT uChanged = 0;
TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
if (lStyle & LVS_OWNERDATA) if (lStyle & LVS_OWNERDATA)
{ {
INT oldState; INT oldState;
...@@ -2764,8 +2805,6 @@ static BOOL set_sub_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW) ...@@ -2764,8 +2805,6 @@ static BOOL set_sub_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
HDPA hdpaSubItems; HDPA hdpaSubItems;
LISTVIEW_SUBITEM *lpSubItem; LISTVIEW_SUBITEM *lpSubItem;
TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
if (lStyle & LVS_OWNERDATA) return FALSE; if (lStyle & LVS_OWNERDATA) return FALSE;
/* set subitem only if column is present */ /* set subitem only if column is present */
...@@ -2832,6 +2871,8 @@ static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i ...@@ -2832,6 +2871,8 @@ static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i
LPWSTR pszText = NULL; LPWSTR pszText = NULL;
BOOL bResult; BOOL bResult;
TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW);
if (!lpLVItem || lpLVItem->iItem < 0 || if (!lpLVItem || lpLVItem->iItem < 0 ||
lpLVItem->iItem>=GETITEMCOUNT(infoPtr)) lpLVItem->iItem>=GETITEMCOUNT(infoPtr))
return FALSE; return FALSE;
...@@ -2869,7 +2910,7 @@ static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i ...@@ -2869,7 +2910,7 @@ static BOOL LISTVIEW_SetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i
InvalidateRect(infoPtr->hwndSelf, &rcOldItem, TRUE); InvalidateRect(infoPtr->hwndSelf, &rcOldItem, TRUE);
} }
LISTVIEW_GetAllMeasure(infoPtr, lpLVItem->iItem, NULL, NULL, LISTVIEW_GetAllMeasures(infoPtr, lpLVItem->iItem, NULL, NULL,
NULL, &rcIcon, NULL, &rcFullText); NULL, &rcIcon, NULL, &rcFullText);
UnionRect(&rcNewItem, &rcIcon, &rcFullText); UnionRect(&rcNewItem, &rcIcon, &rcFullText);
if(!IsRectEmpty(&rcNewItem)) if(!IsRectEmpty(&rcNewItem))
...@@ -2993,7 +3034,6 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT ...@@ -2993,7 +3034,6 @@ static void LISTVIEW_DrawSubItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT
LISTVIEW_GetItemW(infoPtr, &lvItem, TRUE); LISTVIEW_GetItemW(infoPtr, &lvItem, TRUE);
TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE)); TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
ZeroMemory(&lvColumn, sizeof(lvColumn));
lvColumn.mask = LVCF_FMT; lvColumn.mask = LVCF_FMT;
LISTVIEW_GetColumnT(infoPtr, nSubItem, &lvColumn, TRUE); LISTVIEW_GetColumnT(infoPtr, nSubItem, &lvColumn, TRUE);
textLeft = rcItem.left; textLeft = rcItem.left;
...@@ -3299,7 +3339,7 @@ static void LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, R ...@@ -3299,7 +3339,7 @@ static void LISTVIEW_DrawLargeItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, R
LISTVIEW_GetItemW(infoPtr, &lvItem, FALSE); LISTVIEW_GetItemW(infoPtr, &lvItem, FALSE);
TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE)); TRACE(" lvItem=%s\n", debuglvitem_t(&lvItem, TRUE));
LISTVIEW_GetAllMeasure(infoPtr, nItem, &ptOrg, NULL, LISTVIEW_GetAllMeasures(infoPtr, nItem, &ptOrg, NULL,
&rcFill, &rcIcon, &rcLabel, &rcFullText); &rcFill, &rcIcon, &rcLabel, &rcFullText);
rcFill.left += ptOrg.x; rcFill.left += ptOrg.x;
rcFill.top += ptOrg.y; rcFill.top += ptOrg.y;
...@@ -3564,7 +3604,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode ...@@ -3564,7 +3604,6 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight; dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight;
OffsetRect(&dis.rcItem, ptOrig.x, 0); OffsetRect(&dis.rcItem, ptOrig.x, 0);
ZeroMemory(&item, sizeof(item));
item.iItem = nItem; item.iItem = nItem;
item.iSubItem = 0; item.iSubItem = 0;
item.mask = LVIF_PARAM; item.mask = LVIF_PARAM;
...@@ -4668,41 +4707,35 @@ static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPart ...@@ -4668,41 +4707,35 @@ static BOOL LISTVIEW_EnsureVisible(LISTVIEW_INFO *infoPtr, INT nItem, BOOL bPart
*/ */
static INT LISTVIEW_GetNearestItem(LISTVIEW_INFO *infoPtr, POINT pt, UINT vkDirection) static INT LISTVIEW_GetNearestItem(LISTVIEW_INFO *infoPtr, POINT pt, UINT vkDirection)
{ {
LV_INTHIT lvIntHit; LV_INTHIT lvIntHit;
INT nItem = -1; INT nItem;
RECT rcView; RECT rcView;
TRACE("point %ld,%ld, direction %s\n", pt.x, pt.y, TRACE("point %ld,%ld, direction %s\n", pt.x, pt.y,
(vkDirection == VK_DOWN) ? "VK_DOWN" : (vkDirection == VK_DOWN) ? "VK_DOWN" :
((vkDirection == VK_UP) ? "VK_UP" : ((vkDirection == VK_UP) ? "VK_UP" :
((vkDirection == VK_LEFT) ? "VK_LEFT" : "VK_RIGHT"))); ((vkDirection == VK_LEFT) ? "VK_LEFT" : "VK_RIGHT")));
if (LISTVIEW_GetViewRect(infoPtr, &rcView)) if (!LISTVIEW_GetViewRect(infoPtr, &rcView)) return -1;
{
ZeroMemory(&lvIntHit, sizeof(lvIntHit)); if (!LISTVIEW_GetOrigin(infoPtr, &lvIntHit.ht.pt)) return -1;
LISTVIEW_GetOrigin(infoPtr, &lvIntHit.ht.pt);
lvIntHit.ht.pt.x += pt.x; lvIntHit.ht.pt.x += pt.x;
lvIntHit.ht.pt.y += pt.y; lvIntHit.ht.pt.y += pt.y;
if (vkDirection == VK_DOWN) if (vkDirection == VK_DOWN)
lvIntHit.ht.pt.y += infoPtr->nItemHeight; lvIntHit.ht.pt.y += infoPtr->nItemHeight;
else if (vkDirection == VK_UP) else if (vkDirection == VK_UP)
lvIntHit.ht.pt.y -= infoPtr->nItemHeight; lvIntHit.ht.pt.y -= infoPtr->nItemHeight;
else if (vkDirection == VK_LEFT) else if (vkDirection == VK_LEFT)
lvIntHit.ht.pt.x -= infoPtr->nItemWidth; lvIntHit.ht.pt.x -= infoPtr->nItemWidth;
else if (vkDirection == VK_RIGHT) else if (vkDirection == VK_RIGHT)
lvIntHit.ht.pt.x += infoPtr->nItemWidth; lvIntHit.ht.pt.x += infoPtr->nItemWidth;
if (!PtInRect(&rcView, lvIntHit.ht.pt))
return -1;
else
{
nItem = LISTVIEW_SuperHitTestItem(infoPtr, &lvIntHit, TRUE);
return nItem == -1 ? lvIntHit.iDistItem : nItem;
}
}
return nItem; if (!PtInRect(&rcView, lvIntHit.ht.pt)) return -1;
nItem = LISTVIEW_SuperHitTestItem(infoPtr, &lvIntHit, TRUE);
return nItem == -1 ? lvIntHit.iDistItem : nItem;
} }
/*** /***
...@@ -5120,8 +5153,7 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i ...@@ -5120,8 +5153,7 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i
* information from the application * information from the application
*/ */
TRACE("(lpLVItem=%s, internal=%d, isW=%d)\n", TRACE("(lpLVItem=%s, internal=%d, isW=%d)\n", debuglvitem_t(lpLVItem, isW), internal, isW);
debuglvitem_t(lpLVItem, isW), internal, isW);
if (!lpLVItem || (lpLVItem->iItem < 0) || if (!lpLVItem || (lpLVItem->iItem < 0) ||
(lpLVItem->iItem >= GETITEMCOUNT(infoPtr))) (lpLVItem->iItem >= GETITEMCOUNT(infoPtr)))
...@@ -5313,19 +5345,17 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i ...@@ -5313,19 +5345,17 @@ static BOOL LISTVIEW_GetItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL i
*/ */
static BOOL LISTVIEW_GetItemBoundBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lpRect) static BOOL LISTVIEW_GetItemBoundBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lpRect)
{ {
BOOL bResult = FALSE; BOOL bResult;
TRACE("(nItem=%d,lpRect=%p)\n", nItem, lpRect); TRACE("(nItem=%d,lpRect=%p)\n", nItem, lpRect);
if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && if (!lpRect) return FALSE;
(lpRect != NULL))
{ bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, lpRect, 0, 0, 0);
bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL,
lpRect, NULL, NULL, NULL); TRACE("result %s: (%d,%d)-(%d,%d)\n", bResult ? "TRUE" : "FALSE",
} lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
TRACE("result %s: (%d,%d)-(%d,%d)\n", bResult ? "TRUE" : "FALSE", return bResult;
lpRect->left, lpRect->top, lpRect->right, lpRect->bottom);
return bResult;
} }
/*** /***
...@@ -5345,19 +5375,18 @@ static BOOL LISTVIEW_GetItemBoundBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT l ...@@ -5345,19 +5375,18 @@ static BOOL LISTVIEW_GetItemBoundBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT l
*/ */
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition) static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition)
{ {
BOOL bResult = FALSE; BOOL bResult;
TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition); TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition);
if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr)) && if(!lpptPosition) return FALSE;
(lpptPosition != NULL))
{ bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, lpptPosition,
bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, lpptPosition,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
TRACE("result %s (%ld,%ld)\n", bResult ? "TRUE" : "FALSE", TRACE("result %s (%ld,%ld)\n", bResult ? "TRUE" : "FALSE",
lpptPosition->x, lpptPosition->y); lpptPosition->x, lpptPosition->y);
} return bResult;
return bResult;
} }
/*** /***
...@@ -5555,7 +5584,6 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) ...@@ -5555,7 +5584,6 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
{ {
LVITEMW lvItem; LVITEMW lvItem;
ZeroMemory(&lvItem, sizeof(lvItem));
lvItem.mask = LVIF_INDENT; lvItem.mask = LVIF_INDENT;
lvItem.iItem = nItem; lvItem.iItem = nItem;
lvItem.iSubItem = 0; lvItem.iSubItem = 0;
...@@ -5575,8 +5603,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) ...@@ -5575,8 +5603,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
switch(lprc->left) switch(lprc->left)
{ {
case LVIR_ICON: case LVIR_ICON:
bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL, bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, 0, lprc, 0, 0);
NULL, lprc, NULL, NULL);
if (uView & LVS_REPORT) if (uView & LVS_REPORT)
{ {
lprc->left += nIndent; lprc->left += nIndent;
...@@ -5587,8 +5614,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) ...@@ -5587,8 +5614,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
case LVIR_LABEL: case LVIR_LABEL:
if ((uView == LVS_ICON) || (uView == LVS_SMALLICON)) if ((uView == LVS_ICON) || (uView == LVS_SMALLICON))
{ {
bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL, bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, 0, 0, 0, 0, lprc, 0);
NULL, NULL, lprc, NULL);
} }
else else
{ {
...@@ -5628,13 +5654,13 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc) ...@@ -5628,13 +5654,13 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
{ {
RECT label_rect, icon_rect; RECT label_rect, icon_rect;
bResult = LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL, bResult = LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, NULL,
NULL, &icon_rect, &label_rect, NULL); NULL, &icon_rect, &label_rect, NULL);
UnionRect (lprc, &icon_rect, &label_rect); UnionRect (lprc, &icon_rect, &label_rect);
} }
else else
{ {
if (!LISTVIEW_GetAllMeasure(infoPtr, nItem, NULL, NULL, if (!LISTVIEW_GetAllMeasures(infoPtr, nItem, NULL, NULL,
lprc, NULL, NULL, NULL)) break; lprc, NULL, NULL, NULL)) break;
bResult = TRUE; bResult = TRUE;
if (!(infoPtr->dwExStyle&LVS_EX_FULLROWSELECT) && uView&LVS_REPORT) if (!(infoPtr->dwExStyle&LVS_EX_FULLROWSELECT) && uView&LVS_REPORT)
...@@ -5895,20 +5921,13 @@ static LRESULT LISTVIEW_GetItemState(LISTVIEW_INFO *infoPtr, INT nItem, UINT uMa ...@@ -5895,20 +5921,13 @@ static LRESULT LISTVIEW_GetItemState(LISTVIEW_INFO *infoPtr, INT nItem, UINT uMa
*/ */
static LRESULT LISTVIEW_GetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem, BOOL isW) static LRESULT LISTVIEW_GetItemTextT(LISTVIEW_INFO *infoPtr, INT nItem, LPLVITEMW lpLVItem, BOOL isW)
{ {
INT nLength = 0; if (!lpLVItem || (nItem < 0) || (nItem >= GETITEMCOUNT(infoPtr))) return 0;
if (lpLVItem != NULL) lpLVItem->mask = LVIF_TEXT;
{ lpLVItem->iItem = nItem;
if ((nItem >= 0) && (nItem < GETITEMCOUNT(infoPtr))) if (!LISTVIEW_GetItemT(infoPtr, lpLVItem, FALSE, isW)) return 0;
{
lpLVItem->mask = LVIF_TEXT;
lpLVItem->iItem = nItem;
if (LISTVIEW_GetItemT(infoPtr, lpLVItem, FALSE, isW))
nLength = textlenT(lpLVItem->pszText, isW);
}
}
return nLength; return textlenT(lpLVItem->pszText, isW);
} }
/*** /***
...@@ -6076,8 +6095,7 @@ static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *infoPtr, LPPOINT lpptOrigin) ...@@ -6076,8 +6095,7 @@ static BOOL LISTVIEW_GetOrigin(LISTVIEW_INFO *infoPtr, LPPOINT lpptOrigin)
{ {
if (!lpptOrigin) return FALSE; if (!lpptOrigin) return FALSE;
LISTVIEW_GetAllMeasure(infoPtr, -1, lpptOrigin, NULL, LISTVIEW_GetAllMeasures(infoPtr, -1, lpptOrigin, 0, 0, 0, 0, 0);
NULL, NULL, NULL, NULL);
TRACE("(pt=(%ld,%ld))\n", lpptOrigin->x, lpptOrigin->y); TRACE("(pt=(%ld,%ld))\n", lpptOrigin->x, lpptOrigin->y);
...@@ -6196,6 +6214,7 @@ static INT LISTVIEW_SuperHitTestItem(LISTVIEW_INFO *infoPtr, LPLV_INTHIT lpInt, ...@@ -6196,6 +6214,7 @@ static INT LISTVIEW_SuperHitTestItem(LISTVIEW_INFO *infoPtr, LPLV_INTHIT lpInt,
TRACE("(x=%ld, y=%ld)\n", lpInt->ht.pt.x, lpInt->ht.pt.y); TRACE("(x=%ld, y=%ld)\n", lpInt->ht.pt.x, lpInt->ht.pt.y);
/* FIXME: get the visible range */
topindex = LISTVIEW_GetTopIndex(infoPtr); topindex = LISTVIEW_GetTopIndex(infoPtr);
if (uView == LVS_REPORT) if (uView == LVS_REPORT)
{ {
...@@ -6327,29 +6346,25 @@ static INT LISTVIEW_HitTestItem(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpHitTes ...@@ -6327,29 +6346,25 @@ static INT LISTVIEW_HitTestItem(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpHitTes
*/ */
static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpHitTestInfo) static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpHitTestInfo)
{ {
INT nItem = -1; lpHitTestInfo->flags = 0;
lpHitTestInfo->flags = 0; if (infoPtr->rcList.left > lpHitTestInfo->pt.x)
lpHitTestInfo->flags = LVHT_TOLEFT;
if (infoPtr->rcList.left > lpHitTestInfo->pt.x) else if (infoPtr->rcList.right < lpHitTestInfo->pt.x)
lpHitTestInfo->flags = LVHT_TOLEFT; lpHitTestInfo->flags = LVHT_TORIGHT;
else if (infoPtr->rcList.right < lpHitTestInfo->pt.x)
lpHitTestInfo->flags = LVHT_TORIGHT; if (infoPtr->rcList.top > lpHitTestInfo->pt.y)
if (infoPtr->rcList.top > lpHitTestInfo->pt.y) lpHitTestInfo->flags |= LVHT_ABOVE;
lpHitTestInfo->flags |= LVHT_ABOVE; else if (infoPtr->rcList.bottom < lpHitTestInfo->pt.y)
else if (infoPtr->rcList.bottom < lpHitTestInfo->pt.y) lpHitTestInfo->flags |= LVHT_BELOW;
lpHitTestInfo->flags |= LVHT_BELOW;
if (lpHitTestInfo->flags == 0) if (lpHitTestInfo->flags) return -1;
{
/* NOTE (mm 20001022): We must not allow iSubItem to be touched, for /* NOTE (mm 20001022): We must not allow iSubItem to be touched, for
* an app might pass only a structure with space up to iItem! * an app might pass only a structure with space up to iItem!
* (MS Office 97 does that for instance in the file open dialog) * (MS Office 97 does that for instance in the file open dialog)
*/ */
nItem = LISTVIEW_HitTestItem(infoPtr, lpHitTestInfo, FALSE); return LISTVIEW_HitTestItem(infoPtr, lpHitTestInfo, FALSE);
}
return nItem;
} }
/*** /***
...@@ -6404,7 +6419,7 @@ static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn, ...@@ -6404,7 +6419,7 @@ static LRESULT LISTVIEW_InsertColumnT(LISTVIEW_INFO *infoPtr, INT nColumn,
INT nNewColumn = -1; INT nNewColumn = -1;
HDITEMW hdi; HDITEMW hdi;
TRACE("(nColumn=%d, lpColumn=%p)\n", nColumn, lpColumn); TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW);
if (lpColumn != NULL) if (lpColumn != NULL)
{ {
...@@ -6557,7 +6572,7 @@ static INT WINAPI LISTVIEW_InsertCompare( LPVOID first, LPVOID second, LPARAM ...@@ -6557,7 +6572,7 @@ static INT WINAPI LISTVIEW_InsertCompare( LPVOID first, LPVOID second, LPARAM
* *
* PARAMETER(S): * PARAMETER(S):
* [I] infoPtr : valid pointer to the listview structure * [I] infoPtr : valid pointer to the listview structure
* [I] LPLVITEMW : item information * [I] lpLVItem : item information
* [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI * [I] isW : TRUE if lpLVItem is Unicode, FALSE if it's ANSI
* *
* RETURN: * RETURN:
...@@ -6599,6 +6614,11 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, ...@@ -6599,6 +6614,11 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
is_sorted = (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) && is_sorted = (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) &&
!(lStyle & LVS_OWNERDRAWFIXED) && (LPSTR_TEXTCALLBACKW != lpLVItem->pszText); !(lStyle & LVS_OWNERDRAWFIXED) && (LPSTR_TEXTCALLBACKW != lpLVItem->pszText);
nItem = DPA_InsertPtr( infoPtr->hdpaItems,
is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem,
hdpaSubItems );
if (nItem == -1) goto fail;
if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW)) goto fail; if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW)) goto fail;
/* if we're sorted, sort the list, and update the index */ /* if we're sorted, sort the list, and update the index */
...@@ -6606,17 +6626,17 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, ...@@ -6606,17 +6626,17 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
{ {
DPA_Sort( infoPtr->hdpaItems, LISTVIEW_InsertCompare, (LPARAM)infoPtr->hwndSelf ); DPA_Sort( infoPtr->hdpaItems, LISTVIEW_InsertCompare, (LPARAM)infoPtr->hwndSelf );
nItem = DPA_GetPtrIndex( infoPtr->hdpaItems, hdpaSubItems ); nItem = DPA_GetPtrIndex( infoPtr->hdpaItems, hdpaSubItems );
if (nItem == -1) goto fail; if (nItem == -1)
{
ERR("We can't find the item we just inserted, possible memory corruption.");
/* we can't remove it from the list if we can't find it, so just fail */
goto fail;
}
} }
/* Add the subitem list to the items array. Do this last in case we go to /* Add the subitem list to the items array. Do this last in case we go to
* fail during the above. * fail during the above.
*/ */
nItem = DPA_InsertPtr( infoPtr->hdpaItems,
is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem,
hdpaSubItems );
if (nItem == -1) goto fail;
LISTVIEW_ShiftIndices(infoPtr, nItem, 1); LISTVIEW_ShiftIndices(infoPtr, nItem, 1);
lpItem->valid = TRUE; lpItem->valid = TRUE;
...@@ -6639,9 +6659,11 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, ...@@ -6639,9 +6659,11 @@ static LRESULT LISTVIEW_InsertItemT(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem,
/* FIXME: refresh client area */ /* FIXME: refresh client area */
LISTVIEW_Invalidate(infoPtr); LISTVIEW_Invalidate(infoPtr);
TRACE(" <- %d\n", nItem);
return nItem; return nItem;
fail: fail:
DPA_DeletePtr(hdpaSubItems, 0);
DPA_Destroy (hdpaSubItems); DPA_Destroy (hdpaSubItems);
COMCTL32_Free (lpItem); COMCTL32_Free (lpItem);
return -1; return -1;
...@@ -7853,6 +7875,9 @@ static void scroll_list(LISTVIEW_INFO *infoPtr, INT dx, INT dy) ...@@ -7853,6 +7875,9 @@ static void scroll_list(LISTVIEW_INFO *infoPtr, INT dx, INT dy)
/* now we can scroll the list */ /* now we can scroll the list */
ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList, ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList,
&infoPtr->rcList, 0, 0, SW_INVALIDATE); &infoPtr->rcList, 0, 0, SW_INVALIDATE);
/* if we have focus, adjust rect */
if (infoPtr->bFocus && !IsRectEmpty(&infoPtr->rcFocus))
OffsetRect(&infoPtr->rcFocus, dx, dy);
UpdateWindow(infoPtr->hwndSelf); UpdateWindow(infoPtr->hwndSelf);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment