This patch handles the LVM_SUBITEMHITTEST message for Listviews and fixes an infinite loop in Xnews' group window. Changelog: dlls/comctl32/listview.c Paul Rupe <prupe@myrealbox.com> Support for LVM_SUBITEMHITTEST; check for out-of-bounds subitem index in LISTVIEW_GetSubItemRect -- Paul Rupe "She smiled, in the end." p r u p e @ m y r e a l b o x . c o m | Oppose government police-ware on your PC! | Stop the Consumer Broadband and Digital Television Promotion Act! | <http://www.eff.org/alerts/20020322_eff_cbdtpa_alert.html>
Index: dlls/comctl32/listview.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/listview.c,v retrieving revision 1.129 diff -u -r1.129 listview.c --- dlls/comctl32/listview.c 31 May 2002 23:25:44 -0000 1.129 +++ dlls/comctl32/listview.c 9 Jun 2002 22:03:02 -0000 @@ -6081,17 +6081,15 @@ } else { + int top = min(((LISTVIEW_INFO *)GetWindowLongW(hwnd, 0))->nColumnCount, + nSubItem - 1); + LISTVIEW_GetItemRect(hwnd,nItem,lprc); - count = 0; - while (count<(nSubItem-1)) - { + for (count = 0; count < top; count++) lprc->left += LISTVIEW_GetColumnWidth(hwnd,count); - count ++; - } lprc->right = LISTVIEW_GetColumnWidth(hwnd,(nSubItem-1)) + lprc->left; - } return TRUE; } @@ -6549,8 +6547,8 @@ LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0); LONG lStyle = GetWindowLongW(hwnd, GWL_STYLE); UINT uView = lStyle & LVS_TYPEMASK; - INT i,topindex,bottomindex; - RECT rcItem; + INT i,j,topindex,bottomindex; + RECT rcItem,rcSubItem; DWORD xterm, yterm, dist; TRACE("(hwnd=%x, x=%ld, y=%ld)\n", hwnd, lpInt->ht.pt.x, lpInt->ht.pt.y); @@ -6576,6 +6574,7 @@ { if (PtInRect(&rcItem, lpInt->ht.pt)) { + rcSubItem = rcItem; rcItem.left = LVIR_ICON; if (LISTVIEW_GetItemRect(hwnd, i, &rcItem)) { @@ -6583,8 +6582,7 @@ { lpInt->ht.flags = LVHT_ONITEMICON; lpInt->ht.iItem = i; - if (subitem) lpInt->ht.iSubItem = 0; - return i; + goto set_subitem; } } @@ -6595,14 +6593,28 @@ { lpInt->ht.flags = LVHT_ONITEMLABEL; lpInt->ht.iItem = i; - if (subitem) lpInt->ht.iSubItem = 0; - return i; + goto set_subitem; } } lpInt->ht.flags = LVHT_ONITEMSTATEICON; lpInt->ht.iItem = i; - if (subitem) lpInt->ht.iSubItem = 0; + set_subitem: + if (subitem) + { + lpInt->ht.iSubItem = 0; + rcSubItem.right = rcSubItem.left; + for (j = 0; j < infoPtr->nColumnCount; j++) + { + rcSubItem.left = rcSubItem.right; + rcSubItem.right += LISTVIEW_GetColumnWidth(hwnd, j); + if (PtInRect(&rcSubItem, lpInt->ht.pt)) + { + lpInt->ht.iSubItem = j; + break; + } + } + } return i; } else @@ -6699,6 +6711,40 @@ /*** * DESCRIPTION: + * Determines which listview subitem is located at the specified position. + * + * PARAMETER(S): + * [I] HWND : window handle + * [IO} LPLVHITTESTINFO : hit test information + * + * RETURN: + * SUCCESS : item index + * FAILURE : -1 + */ +static LRESULT LISTVIEW_SubItemHitTest(HWND hwnd, LPLVHITTESTINFO lpHitTestInfo) +{ + LISTVIEW_INFO *infoPtr = (LISTVIEW_INFO *)GetWindowLongW(hwnd, 0); + INT nItem = -1; + + lpHitTestInfo->flags = 0; + + if (infoPtr->rcList.left > lpHitTestInfo->pt.x) + lpHitTestInfo->flags = LVHT_TOLEFT; + else if (infoPtr->rcList.right < lpHitTestInfo->pt.x) + lpHitTestInfo->flags = LVHT_TORIGHT; + if (infoPtr->rcList.top > lpHitTestInfo->pt.y) + lpHitTestInfo->flags |= LVHT_ABOVE; + else if (infoPtr->rcList.bottom < lpHitTestInfo->pt.y) + lpHitTestInfo->flags |= LVHT_BELOW; + + if (lpHitTestInfo->flags == 0) + nItem = LISTVIEW_HitTestItem(hwnd, lpHitTestInfo, TRUE); + + return nItem; +} + +/*** + * DESCRIPTION: * Inserts a new column. * * PARAMETER(S): @@ -9644,7 +9690,8 @@ case LVM_SORTITEMS: return LISTVIEW_SortItems(hwnd, (PFNLVCOMPARE)lParam, (LPARAM)wParam); -/* case LVM_SUBITEMHITTEST: */ + case LVM_SUBITEMHITTEST: + return LISTVIEW_SubItemHitTest(hwnd, (LPLVHITTESTINFO)lParam); case LVM_UPDATE: return LISTVIEW_Update(hwnd, (INT)wParam);