Fix iterator creation for LVS_LIST mode.

Do not update the infoPtr->nItemWidth in set_main_item.
Better handling of text bk colour in custom draw.
Rename GetItemListOrigin to GetItemOrigin.
A bunch of code cleanups, simplifications, etc.
This commit is contained in:
Dimitrie O. Paun 2002-10-15 21:08:09 +00:00 committed by Alexandre Julliard
parent 17dce17a58
commit db14dbf12b
1 changed files with 59 additions and 85 deletions

View File

@ -123,6 +123,7 @@ typedef struct tagLISTVIEW_INFO
COLORREF clrBk; COLORREF clrBk;
COLORREF clrText; COLORREF clrText;
COLORREF clrTextBk; COLORREF clrTextBk;
COLORREF clrTextBkDefault;
HIMAGELIST himlNormal; HIMAGELIST himlNormal;
HIMAGELIST himlSmall; HIMAGELIST himlSmall;
HIMAGELIST himlState; HIMAGELIST himlState;
@ -153,7 +154,6 @@ typedef struct tagLISTVIEW_INFO
HCURSOR hHotCursor; HCURSOR hHotCursor;
HFONT hFont; HFONT hFont;
INT ntmHeight; /* from GetTextMetrics from above font */ INT ntmHeight; /* from GetTextMetrics from above font */
INT ntmAveCharWidth; /* from GetTextMetrics from above font */
BOOL bRedraw; BOOL bRedraw;
BOOL bFocus; BOOL bFocus;
INT nFocusedItem; INT nFocusedItem;
@ -275,7 +275,7 @@ static void LISTVIEW_AlignLeft(LISTVIEW_INFO *);
static void LISTVIEW_AlignTop(LISTVIEW_INFO *); static void LISTVIEW_AlignTop(LISTVIEW_INFO *);
static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT); static void LISTVIEW_AddGroupSelection(LISTVIEW_INFO *, INT);
static INT LISTVIEW_CalculateMaxHeight(LISTVIEW_INFO *); static INT LISTVIEW_CalculateMaxHeight(LISTVIEW_INFO *);
static BOOL LISTVIEW_GetItemListOrigin(LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemOrigin(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT); static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *, INT, LPPOINT);
static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT); static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *, INT, LPRECT);
static INT LISTVIEW_CalculateMaxWidth(LISTVIEW_INFO *); static INT LISTVIEW_CalculateMaxWidth(LISTVIEW_INFO *);
@ -947,7 +947,7 @@ static BOOL iterator_frameditems(ITERATOR* i, LISTVIEW_INFO* infoPtr, const RECT
if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE; if (nLastCol < nFirstCol || nLastRow < nFirstRow) return TRUE;
if (!(i->ranges = DPA_Create(nLastCol - nFirstCol + 1))) return FALSE; if (!(i->ranges = DPA_Create(nLastCol - nFirstCol + 1))) return FALSE;
for (nCol = nFirstCol; nCol < nLastCol; nCol++) for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
{ {
item_range.lower = nCol * nPerCol + nFirstRow; item_range.lower = nCol * nPerCol + nFirstRow;
if(item_range.lower >= infoPtr->nItemCount) break; if(item_range.lower >= infoPtr->nItemCount) break;
@ -994,7 +994,7 @@ static BOOL iterator_visibleitems(ITERATOR* i, LISTVIEW_INFO *infoPtr, HDC hdc)
/* now delete the invisible items from the list */ /* now delete the invisible items from the list */
while(iterator_next(i)) while(iterator_next(i))
{ {
if (!LISTVIEW_GetItemListOrigin(infoPtr, i->nItem, &Position)) continue; if (!LISTVIEW_GetItemOrigin(infoPtr, i->nItem, &Position)) continue;
rcItem.left = Position.x + Origin.x; rcItem.left = Position.x + Origin.x;
rcItem.top = Position.y + Origin.y; rcItem.top = Position.y + Origin.y;
rcItem.right = rcItem.left + infoPtr->nItemWidth; rcItem.right = rcItem.left + infoPtr->nItemWidth;
@ -1038,7 +1038,7 @@ static inline LRESULT CallWindowProcT(WNDPROC proc, HWND hwnd, UINT uMsg,
POINT Origin, Position; \ POINT Origin, Position; \
RECT rcBox; \ RECT rcBox; \
if (LISTVIEW_GetOrigin(infoPtr, &Origin) && \ if (LISTVIEW_GetOrigin(infoPtr, &Origin) && \
LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position) && \ LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position) && \
Header_GetItemRect(infoPtr->hwndHeader, nSubItem, &rcBox)) { \ Header_GetItemRect(infoPtr->hwndHeader, nSubItem, &rcBox)) { \
OffsetRect(&rcBox, Origin.x + Position.x, Origin.y + Position.y); \ OffsetRect(&rcBox, Origin.x + Position.x, Origin.y + Position.y); \
LISTVIEW_InvalidateRect(infoPtr, &rcBox); \ LISTVIEW_InvalidateRect(infoPtr, &rcBox); \
@ -1510,7 +1510,7 @@ static void LISTVIEW_UnsupportedStyles(LONG lStyle)
* TRUE if computations OK * TRUE if computations OK
* FALSE otherwise * FALSE otherwise
*/ */
static BOOL LISTVIEW_GetItemListOrigin(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition) static BOOL LISTVIEW_GetItemOrigin(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT lpptPosition)
{ {
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
@ -1787,7 +1787,6 @@ calc_label:
* [I] infoPtr : valid pointer to the listview structure * [I] infoPtr : valid pointer to the listview structure
* [I] nItem : item number * [I] nItem : item number
* [O] lprcBox : ptr to Box rectangle * [O] lprcBox : ptr to Box rectangle
* The internal LVIR_BOX rectangle
* *
* RETURN: * RETURN:
* TRUE if computations OK * TRUE if computations OK
@ -1800,7 +1799,7 @@ static BOOL LISTVIEW_GetItemBox(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprcBo
POINT Position, Origin; POINT Position, Origin;
LVITEMW lvItem; LVITEMW lvItem;
if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position)) return FALSE; if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) return FALSE;
if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE; if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
/* Be smart and try to figure out the minimum we have to do */ /* Be smart and try to figure out the minimum we have to do */
@ -2001,8 +2000,7 @@ static BOOL LISTVIEW_GetViewRect(LISTVIEW_INFO *infoPtr, LPRECT lprcView)
* SUCCESS : subitem pointer * SUCCESS : subitem pointer
* FAILURE : NULL * FAILURE : NULL
*/ */
static LISTVIEW_SUBITEM* LISTVIEW_GetSubItemPtr(HDPA hdpaSubItems, static LISTVIEW_SUBITEM* LISTVIEW_GetSubItemPtr(HDPA hdpaSubItems, INT nSubItem)
INT nSubItem)
{ {
LISTVIEW_SUBITEM *lpSubItem; LISTVIEW_SUBITEM *lpSubItem;
INT i; INT i;
@ -2102,22 +2100,17 @@ static inline INT LISTVIEW_CalculateMaxWidth(LISTVIEW_INFO *infoPtr)
*/ */
static void LISTVIEW_SaveTextMetrics(LISTVIEW_INFO *infoPtr) static void LISTVIEW_SaveTextMetrics(LISTVIEW_INFO *infoPtr)
{ {
TEXTMETRICW tm; HDC hdc = GetDC(infoPtr->hwndSelf);
HDC hdc = GetDC(infoPtr->hwndSelf); HFONT hFont = infoPtr->hFont ? infoPtr->hFont : infoPtr->hDefaultFont;
HFONT hOldFont = SelectObject(hdc, infoPtr->hFont); HFONT hOldFont = SelectObject(hdc, hFont);
INT oldHeight, oldACW; TEXTMETRICW tm;
GetTextMetricsW(hdc, &tm); if (GetTextMetricsW(hdc, &tm))
infoPtr->ntmHeight = tm.tmHeight;
oldHeight = infoPtr->ntmHeight; SelectObject(hdc, hOldFont);
oldACW = infoPtr->ntmAveCharWidth; ReleaseDC(infoPtr->hwndSelf, hdc);
infoPtr->ntmHeight = tm.tmHeight;
infoPtr->ntmAveCharWidth = tm.tmAveCharWidth; TRACE("tmHeight=%d\n", infoPtr->ntmHeight);
SelectObject(hdc, hOldFont);
ReleaseDC(infoPtr->hwndSelf, hdc);
TRACE("tmHeight old=%d,new=%d; tmAveCharWidth old=%d,new=%d\n",
oldHeight, infoPtr->ntmHeight, oldACW, infoPtr->ntmAveCharWidth);
} }
@ -2531,6 +2524,18 @@ static inline BOOL LISTVIEW_SetItemFocus(LISTVIEW_INFO *infoPtr, INT nItem)
return oldFocus != infoPtr->nFocusedItem; return oldFocus != infoPtr->nFocusedItem;
} }
/* Helper function for LISTVIEW_ShiftIndices *only* */
static INT shift_item(LISTVIEW_INFO *infoPtr, INT nShiftItem, INT nItem, INT direction)
{
if (nShiftItem < nItem) return nShiftItem;
if (nShiftItem > nItem) return nShiftItem + direction;
if (direction > 0) return nShiftItem + direction;
return min(nShiftItem, infoPtr->nItemCount - 1);
}
/** /**
* DESCRIPTION: * DESCRIPTION:
* Updates the various indices after an item has been inserted or deleted. * Updates the various indices after an item has been inserted or deleted.
@ -2545,36 +2550,21 @@ static inline BOOL LISTVIEW_SetItemFocus(LISTVIEW_INFO *infoPtr, INT nItem)
*/ */
static void LISTVIEW_ShiftIndices(LISTVIEW_INFO *infoPtr, INT nItem, INT direction) static void LISTVIEW_ShiftIndices(LISTVIEW_INFO *infoPtr, INT nItem, INT direction)
{ {
TRACE("Shifting %iu, %i steps\n", nItem, direction); INT nNewFocus;
TRACE("Shifting %iu, %i steps\n", nItem, direction);
ranges_shift(infoPtr->hdpaSelectionRanges, nItem, direction); ranges_shift(infoPtr->hdpaSelectionRanges, nItem, direction);
/* Note that the following will fail if direction != +1 and -1 */ assert(abs(direction) == 1);
if (infoPtr->nSelectionMark > nItem)
infoPtr->nSelectionMark += direction;
else if (infoPtr->nSelectionMark == nItem)
{
if (direction > 0)
infoPtr->nSelectionMark += direction;
else if (infoPtr->nSelectionMark >= infoPtr->nItemCount)
infoPtr->nSelectionMark = infoPtr->nItemCount - 1;
}
if (infoPtr->nFocusedItem > nItem) infoPtr->nSelectionMark = shift_item(infoPtr, infoPtr->nSelectionMark, nItem, direction);
infoPtr->nFocusedItem += direction;
else if (infoPtr->nFocusedItem == nItem) nNewFocus = shift_item(infoPtr, infoPtr->nFocusedItem, nItem, direction);
{ if (nNewFocus != infoPtr->nFocusedItem)
if (direction > 0) LISTVIEW_SetItemFocus(infoPtr, nNewFocus);
infoPtr->nFocusedItem += direction;
else /* But we are not supposed to modify nHotItem! */
{
if (infoPtr->nFocusedItem >= infoPtr->nItemCount)
infoPtr->nFocusedItem = infoPtr->nItemCount - 1;
if (infoPtr->nFocusedItem >= 0)
LISTVIEW_SetItemFocus(infoPtr, infoPtr->nFocusedItem);
}
}
/* But we are not supposed to modify nHotItem! */
} }
@ -2914,7 +2904,6 @@ static BOOL set_owner_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW) static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
{ {
LONG lStyle = infoPtr->dwStyle; LONG lStyle = infoPtr->dwStyle;
UINT uView = lStyle & LVS_TYPEMASK;
HDPA hdpaSubItems; HDPA hdpaSubItems;
LISTVIEW_ITEM *lpItem; LISTVIEW_ITEM *lpItem;
NMLISTVIEW nmlv; NMLISTVIEW nmlv;
@ -2994,13 +2983,6 @@ static BOOL set_main_item(LISTVIEW_INFO *infoPtr, LPLVITEMW lpLVItem, BOOL isW)
} }
} }
/* if LVS_LIST or LVS_SMALLICON, update the width of the items */
if((uChanged & LVIF_TEXT) && ((uView == LVS_LIST) || (uView == LVS_SMALLICON)))
{
int item_width = LISTVIEW_CalculateItemWidth(infoPtr, lpLVItem->iItem);
if(item_width > infoPtr->nItemWidth) infoPtr->nItemWidth = item_width;
}
/* if we're inserting the item, we're done */ /* if we're inserting the item, we're done */
if (!lpItem->valid) return TRUE; if (!lpItem->valid) return TRUE;
@ -3196,19 +3178,6 @@ static INT LISTVIEW_GetTopIndex(LISTVIEW_INFO *infoPtr)
return nItem; return nItem;
} }
/* helper function for the drawing code */
static void select_text_attr(LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRAW *lpnmlvcd)
{
if ( (lpnmlvcd->clrTextBk != CLR_DEFAULT) && (lpnmlvcd->clrTextBk != CLR_NONE) )
{
SetBkMode(hdc, OPAQUE);
SetBkColor(hdc, lpnmlvcd->clrTextBk);
}
else
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, lpnmlvcd->clrText);
}
/*** /***
* DESCRIPTION: * DESCRIPTION:
@ -3306,7 +3275,11 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, INT nS
/* Don't bother painting item being edited */ /* Don't bother painting item being edited */
if (infoPtr->bEditing && lprcFocus && nSubItem == 0) goto postpaint; if (infoPtr->bEditing && lprcFocus && nSubItem == 0) goto postpaint;
select_text_attr(infoPtr, hdc, &nmlvcd); /* Set the text attributes */
SetBkMode(hdc, nmlvcd.clrTextBk == CLR_NONE ? TRANSPARENT : OPAQUE);
if (nmlvcd.clrTextBk != CLR_NONE)
SetBkColor(hdc, nmlvcd.clrTextBk == CLR_DEFAULT ? infoPtr->clrTextBkDefault : nmlvcd.clrTextBk);
SetTextColor(hdc, nmlvcd.clrText);
/* draw the selection background, if we're drawing the main item */ /* draw the selection background, if we're drawing the main item */
if (nSubItem == 0) if (nSubItem == 0)
@ -3407,7 +3380,7 @@ static void LISTVIEW_RefreshOwnerDraw(LISTVIEW_INFO *infoPtr, HDC hdc)
if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS; if (infoPtr->bFocus && (item.state & LVIS_FOCUSED)) dis.itemState |= ODS_FOCUS;
dis.hwndItem = infoPtr->hwndSelf; dis.hwndItem = infoPtr->hwndSelf;
dis.hDC = hdc; dis.hDC = hdc;
if (!LISTVIEW_GetItemListOrigin(infoPtr, dis.itemID, &Position)) continue; if (!LISTVIEW_GetItemOrigin(infoPtr, dis.itemID, &Position)) continue;
dis.rcItem.left = Position.x + Origin.x; dis.rcItem.left = Position.x + Origin.x;
dis.rcItem.right = dis.rcItem.left + infoPtr->nItemWidth; dis.rcItem.right = dis.rcItem.left + infoPtr->nItemWidth;
dis.rcItem.top = Position.y + Origin.y; dis.rcItem.top = Position.y + Origin.y;
@ -3478,7 +3451,7 @@ static void LISTVIEW_RefreshReport(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode
/* iterate through the invalidated columns */ /* iterate through the invalidated columns */
for (nCol = nFirstCol; nCol <= nLastCol; nCol++) for (nCol = nFirstCol; nCol <= nLastCol; nCol++)
{ {
if (!LISTVIEW_GetItemListOrigin(infoPtr, i.nItem, &Position)) continue; if (!LISTVIEW_GetItemOrigin(infoPtr, i.nItem, &Position)) continue;
Position.x += Origin.x; Position.x += Origin.x;
Position.y += Origin.y; Position.y += Origin.y;
@ -3526,7 +3499,7 @@ static void LISTVIEW_RefreshList(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
while(iterator_prev(&i)) while(iterator_prev(&i))
{ {
if (!LISTVIEW_GetItemListOrigin(infoPtr, i.nItem, &Position)) continue; if (!LISTVIEW_GetItemOrigin(infoPtr, i.nItem, &Position)) continue;
Position.x += Origin.x; Position.x += Origin.x;
Position.y += Origin.y; Position.y += Origin.y;
@ -3550,7 +3523,7 @@ static void LISTVIEW_RefreshList(LISTVIEW_INFO *infoPtr, HDC hdc, DWORD cdmode)
static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc) static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
{ {
UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; UINT uView = infoPtr->dwStyle & LVS_TYPEMASK;
COLORREF oldBkColor, oldTextColor; COLORREF oldTextColor;
NMLVCUSTOMDRAW nmlvcd; NMLVCUSTOMDRAW nmlvcd;
HFONT hOldFont; HFONT hOldFont;
DWORD cdmode; DWORD cdmode;
@ -3564,7 +3537,7 @@ static void LISTVIEW_Refresh(LISTVIEW_INFO *infoPtr, HDC hdc)
/* save dc values we're gonna trash while drawing */ /* save dc values we're gonna trash while drawing */
hOldFont = SelectObject(hdc, infoPtr->hFont); hOldFont = SelectObject(hdc, infoPtr->hFont);
oldBkMode = GetBkMode(hdc); oldBkMode = GetBkMode(hdc);
oldBkColor = GetBkColor(hdc); infoPtr->clrTextBkDefault = GetBkColor(hdc);
oldTextColor = GetTextColor(hdc); oldTextColor = GetTextColor(hdc);
GetClientRect(infoPtr->hwndSelf, &rcClient); GetClientRect(infoPtr->hwndSelf, &rcClient);
@ -3596,7 +3569,7 @@ enddraw:
/* unselect objects */ /* unselect objects */
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
SetBkMode(hdc, oldBkMode); SetBkMode(hdc, oldBkMode);
SetBkColor(hdc, oldBkColor); SetBkColor(hdc, infoPtr->clrTextBkDefault);
SetTextColor(hdc, oldTextColor); SetTextColor(hdc, oldTextColor);
infoPtr->bIsDrawing = FALSE; infoPtr->bIsDrawing = FALSE;
} }
@ -4018,7 +3991,7 @@ static LRESULT LISTVIEW_DeleteItem(LISTVIEW_INFO *infoPtr, INT nItem)
DPA_DeletePtr(infoPtr->hdpaPosY, nItem); DPA_DeletePtr(infoPtr->hdpaPosY, nItem);
} }
LISTVIEW_ShiftIndices(infoPtr,nItem,-1); LISTVIEW_ShiftIndices(infoPtr, nItem, -1);
/* align items (set position of each item) */ /* align items (set position of each item) */
if ((uView == LVS_SMALLICON) || (uView == LVS_ICON)) if ((uView == LVS_SMALLICON) || (uView == LVS_ICON))
@ -4330,7 +4303,7 @@ again:
/* This is very inefficient. To do a good job here, /* This is very inefficient. To do a good job here,
* we need a sorted array of (x,y) item positions */ * we need a sorted array of (x,y) item positions */
if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position)) continue; if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) continue;
/* compute the distance^2 to the destination */ /* compute the distance^2 to the destination */
xdist = Destination.x - Position.x; xdist = Destination.x - Position.x;
@ -4894,7 +4867,7 @@ static BOOL LISTVIEW_GetItemPosition(LISTVIEW_INFO *infoPtr, INT nItem, LPPOINT
TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition); TRACE("(nItem=%d, lpptPosition=%p)\n", nItem, lpptPosition);
if (!lpptPosition || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE; if (!lpptPosition || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, lpptPosition)) return FALSE; if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, lpptPosition)) return FALSE;
if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE; if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
if (uView == LVS_ICON) if (uView == LVS_ICON)
@ -4984,7 +4957,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
if (!lprc || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE; if (!lprc || nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE;
if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE; if (!LISTVIEW_GetOrigin(infoPtr, &Origin)) return FALSE;
if (!LISTVIEW_GetItemListOrigin(infoPtr, nItem, &Position)) return FALSE; if (!LISTVIEW_GetItemOrigin(infoPtr, nItem, &Position)) return FALSE;
/* Be smart and try to figure out the minimum we have to do */ /* Be smart and try to figure out the minimum we have to do */
if (lprc->left == LVIR_ICON) doLabel = FALSE; if (lprc->left == LVIR_ICON) doLabel = FALSE;
@ -5057,6 +5030,7 @@ static BOOL LISTVIEW_GetItemRect(LISTVIEW_INFO *infoPtr, INT nItem, LPRECT lprc)
* *
* NOTE: for subItem = 0, we should return the bounds of the _entire_ item, * NOTE: for subItem = 0, we should return the bounds of the _entire_ item,
* not only those of the first column. * not only those of the first column.
* Fortunately, LISTVIEW_GetItemMetrics does the right thing.
* *
* RETURN: * RETURN:
* TRUE: success * TRUE: success
@ -5523,7 +5497,7 @@ static LRESULT LISTVIEW_HitTest(LISTVIEW_INFO *infoPtr, LPLVHITTESTINFO lpht, BO
if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return -1; if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return -1;
if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel)) return -1; if (!LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel)) return -1;
if (!LISTVIEW_GetItemListOrigin(infoPtr, lpht->iItem, &Position)) return -1; if (!LISTVIEW_GetItemOrigin(infoPtr, lpht->iItem, &Position)) return -1;
opt.x = lpht->pt.x - Position.x - Origin.x; opt.x = lpht->pt.x - Position.x - Origin.x;
opt.y = lpht->pt.y - Position.y - Origin.y; opt.y = lpht->pt.y - Position.y - Origin.y;