diff --git a/dll/win32/comctl32/listview.c b/dll/win32/comctl32/listview.c index fcd3dbefcf2..47d9d753ebd 100644 --- a/dll/win32/comctl32/listview.c +++ b/dll/win32/comctl32/listview.c @@ -555,8 +555,8 @@ static inline int textcmpWT(LPCWSTR aw, LPCWSTR bt, BOOL isW) int r = bw ? lstrcmpW(aw, bw) : 1; textfreeT(bw, isW); return r; - } - + } + return 1; } @@ -2467,7 +2467,6 @@ static void LISTVIEW_GetItemMetrics(const LISTVIEW_INFO *infoPtr, const LVITEMW RECT Box, SelectBox, Icon, Label; COLUMN_INFO *lpColumnInfo = NULL; SIZE labelSize = { 0, 0 }; - INT subItemOffset; TRACE("(lpLVItem=%s)\n", debuglvitem_t(lpLVItem, TRUE)); @@ -2661,24 +2660,12 @@ calc_label: Label.right = Label.left + labelSize.cx; Label.bottom = Label.top + labelSize.cy;; } - else if (infoPtr->tileLines && lpLVItem->cColumns && lpLVItem->puColumns) { - /* Calculate the offset for each sub item in tiles view. - * Fixme: Doing scan over the row even though we should just process them in order. */ - subItemOffset = 0; - for (INT subItemSearch = 0; subItemSearch < lpLVItem->cColumns; subItemSearch++) { - if (lpLVItem->iSubItem == lpLVItem->puColumns[subItemSearch]) { - subItemOffset = subItemSearch + 1; - break; - } - } - if (subItemOffset) { - Label.top = Box.top + subItemOffset * (infoPtr->ntmHeight + infoPtr->ntmExternalLeading); - Label.right = Label.left + labelSize.cx; - Label.bottom = Label.top + labelSize.cy;; - } else { - Label.top = Label.bottom = Box.top; - Label.right = Label.left; - } + else if (infoPtr->tileLines && lpLVItem->cColumns) { + /* Side channel. Subitems can't have cColumns; and the fetch won't overwrite it, so put + * the index of the sub-item into the cColumns field. */ + Label.top = Box.top + lpLVItem->cColumns * (infoPtr->ntmHeight + infoPtr->ntmExternalLeading); + Label.right = Label.left + labelSize.cx; + Label.bottom = Label.top + labelSize.cy;; } else { Label.top = Label.bottom = Box.top; Label.right = Label.left; @@ -5065,6 +5052,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT RECT *focus, rcBox; NMLVCUSTOMDRAW nmlvcd; LVITEMW lvItem = {0}; + UINT puColumns[20] = {0}; INT j; TRACE("(hdc=%p, nItem=%d, subitems=%p, pos=%s)\n", hdc, nItem, subitems, wine_dbgstr_point(&pos)); @@ -5072,7 +5060,11 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT /* get information needed for drawing the item */ lvItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM | LVIF_STATE; if (infoPtr->uView == LV_VIEW_DETAILS) lvItem.mask |= LVIF_INDENT; - if (infoPtr->uView == LV_VIEW_TILE) lvItem.mask |= LVIF_COLUMNS; + if (infoPtr->uView == LV_VIEW_TILE) { + lvItem.mask |= LVIF_COLUMNS; + lvItem.cColumns = 20; + lvItem.puColumns = puColumns; + } lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED | LVIS_STATEIMAGEMASK | LVIS_CUT | LVIS_OVERLAYMASK; lvItem.iItem = nItem; lvItem.cchTextMax = DISP_TEXT_SIZE; @@ -5169,18 +5161,25 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT * * Reports mode is a bit different here, there can be many columns, so it has to be careful to * only pull the few required, as many could be off screen. + * + * NOTE: TileView Positions + * Because these are laid out in order, and their displacement depends on those preceding them, + * we pack some side channel information into lvItem.cColumns. */ if (infoPtr->uView == LV_VIEW_TILE && infoPtr->tileLines) { + lvItem.mask = LVIF_TEXT; + lvItem.puColumns = NULL; + j = min(infoPtr->tileLines, lvItem.cColumns); - for (UINT subIx; subIx < j; subIx++) + for (UINT subIx = 0; subIx < j; subIx++) { - lvItem.iSubItem = lvItem.puColumns[subIx]; + lvItem.cColumns = subIx + 1; + lvItem.iSubItem = puColumns[subIx]; lvItem.cchTextMax = DISP_TEXT_SIZE; lvItem.pszText = szDispText; szDispText[0] = 0; - lvItem.mask = LVIF_TEXT; if (LISTVIEW_GetItemW(infoPtr, &lvItem)) LISTVIEW_DrawItemPart(infoPtr, &lvItem, &nmlvcd, &pos); diff --git a/modules/rostests/winetests/comctl32/listview.c b/modules/rostests/winetests/comctl32/listview.c index 75004b4f65b..26846b812b3 100644 --- a/modules/rostests/winetests/comctl32/listview.c +++ b/modules/rostests/winetests/comctl32/listview.c @@ -5617,6 +5617,7 @@ static void test_hover(void) } /* test WM_MOUSEHOVER forwarding */ + g_block_hover = FALSE; flush_sequences(sequences, NUM_MSG_SEQUENCES); r = SendMessageA(hwnd, WM_MOUSEHOVER, 0, 0); expect(0, r);