- Timestamp:
- Feb 10, 2004, 4:47:01 PM (22 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/comctl32/listview.c
r10127 r10448 5 5 * Copyright 1999 Luc Tourangeau 6 6 * Copyright 2000 Jason Mawdsley 7 * Copyright 2001 Code weavers Inc.7 * Copyright 2001 CodeWeavers Inc. 8 8 * Copyright 2002 Dimitrie O. Paun 9 9 * … … 26 26 * This code was audited for completeness against the documented features 27 27 * of Comctl32.dll version 6.0 on Oct. 21, 2002, by Dimitrie O. Paun. 28 * 28 * 29 29 * Unless otherwise noted, we belive this code to be complete, as per 30 30 * the specification mentioned above. 31 31 * If you discover missing features, or bugs, please note them below. 32 * 32 * 33 33 * TODO: 34 34 * … … 42 42 * -- Expand large item in ICON mode when the cursor is flying over the icon or text. 43 43 * -- Support CustonDraw options for _WIN32_IE >= 0x560 (see NMLVCUSTOMDRAW docs. 44 * -- in LISTVIEW_AddGroupSelection, se whould send LVN_ODSTATECHANGED 44 * -- in LISTVIEW_AddGroupSelection, se whould send LVN_ODSTATECHANGED 45 45 * -- LVA_SNAPTOGRID not implemented 46 46 * -- LISTVIEW_ApproximateViewRect partially implemented … … 94 94 * -- LVS_EX_UNDERLINECOLD 95 95 * -- LVS_EX_UNDERLINEHOT 96 * 96 * 97 97 * Notifications: 98 * -- LVN_BEGIN DRAG, LVN_BEGINRDRAG98 * -- LVN_BEGINRDRAG 99 99 * -- LVN_BEGINSCROLL, LVN_ENDSCROLL 100 100 * -- LVN_GETINFOTIP … … 235 235 SHORT notifyFormat; 236 236 RECT rcList; /* This rectangle is really the window 237 * client rectangle possibly reduced by the 238 * horizontal scroll bar and/or header - see 237 * client rectangle possibly reduced by the 238 * horizontal scroll bar and/or header - see 239 239 * LISTVIEW_UpdateSize. This rectangle offset 240 240 * by the LISTVIEW_GetOrigin value is in … … 273 273 HWND hwndToolTip; 274 274 275 /* __WIN32OS2__: this might be sligtly fishy as the merge with wine is only partially done ... */ 276 DWORD cditemmode; /* Keep the custom draw flags for an item/row */ 277 275 278 DWORD lastKeyPressTimestamp; 276 279 WPARAM charCode; … … 278 281 WCHAR szSearchParam[ MAX_PATH ]; 279 282 BOOL bIsDrawing; 280 #ifdef __WIN32OS2__281 BOOL bDragInProcess;282 #endif283 283 } LISTVIEW_INFO; 284 284 … … 460 460 { 461 461 BOOL bResult = TRUE; 462 462 463 463 if (src == LPSTR_TEXTCALLBACKW) 464 464 { … … 491 491 textfreeT(bw, isW); 492 492 return r; 493 } 494 493 } 494 495 495 return 1; 496 496 } 497 497 498 498 static inline int lstrncmpiW(LPCWSTR s1, LPCWSTR s2, int n) 499 499 { … … 535 535 } 536 536 537 #ifdef __WIN32OS2__ 538 static char* debug_getbuf(void) 539 #else 537 540 static char* debug_getbuf() 541 #endif 538 542 { 539 543 static int index = 0; … … 544 548 static inline char* debugrange(const RANGE *lprng) 545 549 { 546 if (lprng) 550 if (lprng) 547 551 { 548 552 char* buf = debug_getbuf(); … … 554 558 static inline char* debugpoint(const POINT *lppt) 555 559 { 556 if (lppt) 560 if (lppt) 557 561 { 558 562 char* buf = debug_getbuf(); … … 564 568 static inline char* debugrect(const RECT *rect) 565 569 { 566 if (rect) 570 if (rect) 567 571 { 568 572 char* buf = debug_getbuf(); … … 577 581 char* buf = debug_getbuf(), *text = buf; 578 582 int len, size = DEBUG_BUFFER_SIZE; 579 583 580 584 if (pScrollInfo == NULL) return "(null)"; 581 585 len = snprintf(buf, size, "{cbSize=%d, ", pScrollInfo->cbSize); … … 603 607 if (buf - text > 2) { buf[-2] = '}'; buf[-1] = 0; } 604 608 return text; 605 } 609 } 606 610 607 611 static char* debugnmlistview(const NMLISTVIEW *plvnm) … … 622 626 char* buf = debug_getbuf(), *text = buf; 623 627 int len, size = DEBUG_BUFFER_SIZE; 624 628 625 629 if (lpLVItem == NULL) return "(null)"; 626 630 len = snprintf(buf, size, "{iItem=%d, iSubItem=%d, ", lpLVItem->iItem, lpLVItem->iSubItem); … … 658 662 char* buf = debug_getbuf(), *text = buf; 659 663 int len, size = DEBUG_BUFFER_SIZE; 660 664 661 665 if (lpColumn == NULL) return "(null)"; 662 666 len = snprintf(buf, size, "{"); … … 696 700 static char* debuglvhittestinfo(const LVHITTESTINFO *lpht) 697 701 { 698 if (lpht) 702 if (lpht) 699 703 { 700 704 char* buf = debug_getbuf(); … … 728 732 { 729 733 LRESULT result; 730 734 731 735 TRACE("(code=%d)\n", code); 732 736 … … 763 767 NMLISTVIEW nmlv; 764 768 LVITEMW item; 765 766 TRACE("code=%d, lvht=%s\n", code, debuglvhittestinfo(lvht)); 769 770 TRACE("code=%d, lvht=%s\n", code, debuglvhittestinfo(lvht)); 767 771 ZeroMemory(&nmlv, sizeof(nmlv)); 768 772 nmlv.iItem = lvht->iItem; … … 780 784 NMLISTVIEW nmlv; 781 785 LVITEMW item; 782 786 783 787 ZeroMemory(&nmlv, sizeof (NMLISTVIEW)); 784 788 nmlv.iItem = nItem; … … 869 873 } 870 874 871 static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, 875 static void customdraw_fill(NMLVCUSTOMDRAW *lpnmlvcd, LISTVIEW_INFO *infoPtr, HDC hdc, 872 876 const RECT *rcBounds, const LVITEMW *lplvItem) 873 877 { … … 892 896 893 897 lpnmlvcd->nmcd.dwDrawStage = dwDrawStage; 894 if (isForItem) lpnmlvcd->nmcd.dwDrawStage |= CDDS_ITEM; 898 if (isForItem) lpnmlvcd->nmcd.dwDrawStage |= CDDS_ITEM; 895 899 if (lpnmlvcd->iSubItem) lpnmlvcd->nmcd.dwDrawStage |= CDDS_SUBITEM; 896 900 if (isForItem) lpnmlvcd->nmcd.dwItemSpec--; … … 984 988 * after it's done with it, as the creation of the iterator may 985 989 * allocate memory, which thus needs to be freed. 986 * 990 * 987 991 * You can iterate both forwards, and backwards through the list, 988 992 * by using iterator_next or iterator_prev respectively. 989 * 993 * 990 994 * Lower numbered items are draw on top of higher number items in 991 995 * LVS_ICON, and LVS_SMALLICON (which are the only modes where … … 1011 1015 * LVS_ICON, and LVS_SMALLICON mode to handle the focused item, 1012 1016 * which needs to be first, as it may overlap other items. 1013 * 1017 * 1014 1018 * The code is a bit messy because we have: 1015 1019 * - a special item to deal with … … 1161 1165 RECT frame = *lprc, rcItem, rcTemp; 1162 1166 POINT Origin; 1163 1167 1164 1168 /* in case we fail, we want to return an empty iterator */ 1165 1169 if (!iterator_empty(i)) return FALSE; … … 1246 1250 RECT rcItem, rcClip; 1247 1251 INT rgntype; 1248 1252 1249 1253 rgntype = GetClipBox(hdc, &rcClip); 1250 1254 if (rgntype == NULLREGION) return iterator_empty(i); … … 1258 1262 if (!RectVisible(hdc, &rcItem)) i->nSpecial = -1; 1259 1263 } 1260 1264 1261 1265 /* if we can't deal with the region, we'll just go with the simple range */ 1262 1266 LISTVIEW_GetOrigin(infoPtr, &Origin); … … 1286 1290 /* the iterator should restart on the next iterator_next */ 1287 1291 TRACE("done\n"); 1288 1292 1289 1293 return TRUE; 1290 1294 } … … 1302 1306 { 1303 1307 UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; 1304 1308 1305 1309 return ((infoPtr->dwStyle & LVS_AUTOARRANGE) || infoPtr->bAutoarrange) && 1306 1310 (uView == LVS_ICON || uView == LVS_SMALLICON); … … 1337 1341 static inline void LISTVIEW_InvalidateRect(LISTVIEW_INFO *infoPtr, const RECT* rect) 1338 1342 { 1339 if(!is_redrawing(infoPtr)) return; 1343 if(!is_redrawing(infoPtr)) return; 1340 1344 TRACE(" invalidating rect=%s\n", debugrect(rect)); 1341 1345 InvalidateRect(infoPtr->hwndSelf, rect, TRUE); … … 1346 1350 RECT rcBox; 1347 1351 1348 if(!is_redrawing(infoPtr)) return; 1352 if(!is_redrawing(infoPtr)) return; 1349 1353 LISTVIEW_GetItemBox(infoPtr, nItem, &rcBox); 1350 1354 LISTVIEW_InvalidateRect(infoPtr, &rcBox); … … 1355 1359 POINT Origin, Position; 1356 1360 RECT rcBox; 1357 1358 if(!is_redrawing(infoPtr)) return; 1361 1362 if(!is_redrawing(infoPtr)) return; 1359 1363 assert ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_REPORT); 1360 1364 LISTVIEW_GetOrigin(infoPtr, &Origin); … … 1375 1379 { 1376 1380 RECT rcCol; 1377 1378 if(!is_redrawing(infoPtr)) return; 1381 1382 if(!is_redrawing(infoPtr)) return; 1379 1383 LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol); 1380 1384 rcCol.top = infoPtr->rcList.top; … … 1627 1631 if (LISTVIEW_GetViewRect(infoPtr, &rcView)) horzInfo.nMax = rcView.right - rcView.left; 1628 1632 } 1629 1633 1630 1634 horzInfo.fMask = SIF_RANGE | SIF_PAGE; 1631 1635 horzInfo.nMax = max(horzInfo.nMax - 1, 0); … … 1676 1680 /*** 1677 1681 * DESCRIPTION: 1678 * Shows/hides the focus rectangle. 1682 * Shows/hides the focus rectangle. 1679 1683 * 1680 1684 * PARAMETER(S): … … 1699 1703 RECT rcBox; 1700 1704 1701 LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcBox); 1705 LISTVIEW_GetItemBox(infoPtr, infoPtr->nFocusedItem, &rcBox); 1702 1706 if ((rcBox.bottom - rcBox.top) > infoPtr->nItemHeight) 1703 1707 { … … 1719 1723 item.mask = LVIF_PARAM; 1720 1724 if (!LISTVIEW_GetItemW(infoPtr, &item)) goto done; 1721 1722 ZeroMemory(&dis, sizeof(dis)); 1725 1726 ZeroMemory(&dis, sizeof(dis)); 1723 1727 dis.CtlType = ODT_LISTVIEW; 1724 1728 dis.CtlID = GetWindowLongW(infoPtr->hwndSelf, GWL_ID); … … 1746 1750 static void LISTVIEW_InvalidateSelectedItems(LISTVIEW_INFO *infoPtr) 1747 1751 { 1748 ITERATOR i; 1749 1750 iterator_frameditems(&i, infoPtr, &infoPtr->rcList); 1752 ITERATOR i; 1753 1754 iterator_frameditems(&i, infoPtr, &infoPtr->rcList); 1751 1755 while(iterator_next(&i)) 1752 1756 { … … 1757 1761 } 1758 1762 1759 1763 1760 1764 /*** 1761 1765 * DESCRIPTION: [INTERNAL] … … 1766 1770 * one ca factor the computation of the Origin before the loop, 1767 1771 * and offset the value retured by this function, on every iteration. 1768 * 1772 * 1769 1773 * PARAMETER(S): 1770 1774 * [I] infoPtr : valid pointer to the listview structure … … 1798 1802 } 1799 1803 } 1800 1804 1801 1805 /*** 1802 1806 * DESCRIPTION: [INTERNAL] … … 1841 1845 */ 1842 1846 static void LISTVIEW_GetItemMetrics(LISTVIEW_INFO *infoPtr, const LVITEMW *lpLVItem, 1843 LPRECT lprcBox, LPRECT lprcState, 1847 LPRECT lprcBox, LPRECT lprcState, 1844 1848 LPRECT lprcIcon, LPRECT lprcLabel) 1845 1849 { … … 1861 1865 if (doLabel || lprcIcon) doIcon = TRUE; 1862 1866 if (doIcon || lprcState) doState = TRUE; 1863 1867 1864 1868 /************************************************************/ 1865 1869 /* compute the box rectangle (it should be cheap to do) */ … … 1868 1872 lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lpLVItem->iSubItem); 1869 1873 1870 if (lpLVItem->iSubItem) 1874 if (lpLVItem->iSubItem) 1871 1875 { 1872 1876 Box = lpColumnInfo->rcHeader; … … 1888 1892 { 1889 1893 State.left = Box.left - infoPtr->iconStateSize.cx - 2; 1890 if (infoPtr->himlNormal) 1894 if (infoPtr->himlNormal) 1891 1895 State.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; 1892 1896 State.top = Box.top + infoPtr->iconSize.cy - infoPtr->iconStateSize.cy + 4; … … 1896 1900 /* we need the ident in report mode, if we don't have it, we fail */ 1897 1901 State.left = Box.left; 1898 if (uView == LVS_REPORT) 1902 if (uView == LVS_REPORT) 1899 1903 { 1900 1904 if (lpLVItem->iSubItem == 0) … … 1926 1930 { 1927 1931 Icon.left = Box.left; 1928 if (infoPtr->himlNormal) 1932 if (infoPtr->himlNormal) 1929 1933 Icon.left += (infoPtr->nItemWidth - infoPtr->iconSize.cx) / 2; 1930 1934 Icon.top = Box.top + ICON_TOP_PADDING; … … 1985 1989 rcText.right = infoPtr->nItemWidth - TRAILING_LABEL_PADDING; 1986 1990 rcText.bottom = infoPtr->nItemHeight; 1987 if (uView == LVS_ICON) 1991 if (uView == LVS_ICON) 1988 1992 rcText.bottom -= ICON_TOP_PADDING + infoPtr->iconSize.cy + ICON_BOTTOM_PADDING; 1989 1993 … … 1993 1997 else 1994 1998 uFormat = LV_SL_DT_FLAGS; 1995 1999 1996 2000 DrawTextW (hdc, lpLVItem->pszText, -1, &rcText, uFormat | DT_CALCRECT); 1997 2001 … … 2027 2031 Label.bottom = Label.top + infoPtr->nItemHeight; 2028 2032 } 2029 2033 2030 2034 if (lprcLabel) *lprcLabel = Label; 2031 2035 TRACE(" - label=%s\n", debugrect(&Label)); … … 2098 2102 { 2099 2103 INT nListWidth = infoPtr->rcList.right - infoPtr->rcList.left; 2100 2104 2101 2105 *lpPos = infoPtr->currIconPos; 2102 2106 2103 2107 infoPtr->currIconPos.x += infoPtr->nItemWidth; 2104 2108 if (infoPtr->currIconPos.x + infoPtr->nItemWidth <= nListWidth) return; … … 2108 2112 } 2109 2113 2110 2114 2111 2115 /*** 2112 2116 * DESCRIPTION: … … 2124 2128 { 2125 2129 INT nListHeight = infoPtr->rcList.bottom - infoPtr->rcList.top; 2126 2130 2127 2131 *lpPos = infoPtr->currIconPos; 2128 2132 2129 2133 infoPtr->currIconPos.y += infoPtr->nItemHeight; 2130 2134 if (infoPtr->currIconPos.y + infoPtr->nItemHeight <= nListHeight) return; … … 2134 2138 } 2135 2139 2136 2140 2137 2141 /*** 2138 2142 * DESCRIPTION: … … 2153 2157 { 2154 2158 POINT old; 2155 2159 2156 2160 if (!isNew) 2157 { 2161 { 2158 2162 old.x = (LONG)DPA_GetPtr(infoPtr->hdpaPosX, nItem); 2159 2163 old.y = (LONG)DPA_GetPtr(infoPtr->hdpaPosY, nItem); 2160 2164 2161 2165 if (lppt->x == old.x && lppt->y == old.y) return TRUE; 2162 2166 LISTVIEW_InvalidateItem(infoPtr, nItem); … … 2193 2197 2194 2198 if (uView != LVS_ICON && uView != LVS_SMALLICON) return FALSE; 2195 2199 2196 2200 TRACE("nAlignCode=%d\n", nAlignCode); 2197 2201 … … 2201 2205 else nAlignCode = LVA_ALIGNTOP; 2202 2206 } 2203 2207 2204 2208 switch (nAlignCode) 2205 2209 { … … 2209 2213 default: return FALSE; 2210 2214 } 2211 2215 2212 2216 infoPtr->bAutoarrange = TRUE; 2213 2217 infoPtr->currIconPos.x = infoPtr->currIconPos.y = 0; … … 2220 2224 return TRUE; 2221 2225 } 2222 2226 2223 2227 /*** 2224 2228 * DESCRIPTION: … … 2265 2269 break; 2266 2270 2267 case LVS_REPORT: 2271 case LVS_REPORT: 2268 2272 lprcView->right = infoPtr->nItemWidth; 2269 2273 lprcView->bottom = infoPtr->nItemCount * infoPtr->nItemHeight; … … 2291 2295 2292 2296 if (!lprcView) return FALSE; 2293 2297 2294 2298 LISTVIEW_GetOrigin(infoPtr, &ptOrigin); 2295 LISTVIEW_GetAreaRect(infoPtr, lprcView); 2296 OffsetRect(lprcView, ptOrigin.x, ptOrigin.y); 2299 LISTVIEW_GetAreaRect(infoPtr, lprcView); 2300 OffsetRect(lprcView, ptOrigin.x, ptOrigin.y); 2297 2301 2298 2302 TRACE("lprcView=%s\n", debugrect(lprcView)); … … 2366 2370 nItemWidth = max(LISTVIEW_GetLabelWidth(infoPtr, i), nItemWidth); 2367 2371 2368 if (infoPtr->himlSmall) nItemWidth += infoPtr->iconSize.cx; 2372 if (infoPtr->himlSmall) nItemWidth += infoPtr->iconSize.cx; 2369 2373 if (infoPtr->himlState) nItemWidth += infoPtr->iconStateSize.cx; 2370 2374 … … 2396 2400 else 2397 2401 { 2398 nItemHeight = infoPtr->ntmHeight; 2402 nItemHeight = infoPtr->ntmHeight; 2399 2403 if (infoPtr->himlState) 2400 2404 nItemHeight = max(nItemHeight, infoPtr->iconStateSize.cy); … … 2465 2469 SelectObject(hdc, hOldFont); 2466 2470 ReleaseDC(infoPtr->hwndSelf, hdc); 2467 2471 2468 2472 TRACE("tmHeight=%d\n", infoPtr->ntmHeight); 2469 2473 } … … 2486 2490 { 2487 2491 INT cmp; 2488 2489 if (((RANGE*)range1)->upper <= ((RANGE*)range2)->lower) 2492 2493 if (((RANGE*)range1)->upper <= ((RANGE*)range2)->lower) 2490 2494 cmp = -1; 2491 else if (((RANGE*)range2)->upper <= ((RANGE*)range1)->lower) 2495 else if (((RANGE*)range2)->upper <= ((RANGE*)range1)->lower) 2492 2496 cmp = 1; 2493 else 2497 else 2494 2498 cmp = 0; 2495 2499 2496 2500 TRACE("range1=%s, range2=%s, cmp=%d\n", debugrange((RANGE*)range1), debugrange((RANGE*)range2), cmp); 2497 2501 … … 2509 2513 INT i; 2510 2514 RANGE *prev, *curr; 2511 2515 2512 2516 TRACE("*** Checking %s:%d:%s ***\n", func, line, desc); 2513 2517 assert (ranges); … … 2559 2563 RANGES clone; 2560 2564 INT i; 2561 2565 2562 2566 if (!(clone = ranges_create(ranges->hdpa->nItemCount))) goto fail; 2563 2567 … … 2570 2574 } 2571 2575 return clone; 2572 2576 2573 2577 fail: 2574 2578 TRACE ("clone failed\n"); … … 2607 2611 { 2608 2612 INT i, count = 0; 2609 2613 2610 2614 for (i = 0; i < ranges->hdpa->nItemCount; i++) 2611 2615 { … … 2648 2652 srchrgn.upper = range.upper + 1; 2649 2653 index = DPA_Search(ranges->hdpa, &srchrgn, 0, ranges_cmp, 0, DPAS_SORTED); 2650 2654 2651 2655 if (index == -1) 2652 2656 { … … 2689 2693 srchrgn.lower = chkrgn->lower - 1; 2690 2694 srchrgn.upper = chkrgn->upper + 1; 2691 2695 2692 2696 do 2693 2697 { 2694 2698 mergeindex = DPA_Search(ranges->hdpa, &srchrgn, fromindex, ranges_cmp, 0, 0); 2695 2699 if (mergeindex == -1) break; 2696 if (mergeindex == index) 2700 if (mergeindex == index) 2697 2701 { 2698 2702 fromindex = index + 1; 2699 2703 continue; 2700 2704 } 2701 2705 2702 2706 TRACE("Merge with index %i\n", mergeindex); 2703 2707 2704 2708 mrgrgn = DPA_GetPtr(ranges->hdpa, mergeindex); 2705 2709 chkrgn->lower = min(chkrgn->lower, mrgrgn->lower); … … 2713 2717 ranges_check(ranges, "after add"); 2714 2718 return TRUE; 2715 2719 2716 2720 fail: 2717 2721 ranges_check(ranges, "failed add"); … … 2726 2730 TRACE("(%s)\n", debugrange(&range)); 2727 2731 ranges_check(ranges, "before del"); 2728 2732 2729 2733 /* we don't use DPAS_SORTED here, since we need * 2730 2734 * to find the first overlapping range */ 2731 2735 index = DPA_Search(ranges->hdpa, &range, 0, ranges_cmp, 0, 0); 2732 while(index != -1) 2736 while(index != -1) 2733 2737 { 2734 2738 chkrgn = DPA_GetPtr(ranges->hdpa, index); 2735 2739 2736 TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); 2740 TRACE("Matches range %s @%d\n", debugrange(chkrgn), index); 2737 2741 2738 2742 /* case 1: Same range */ … … 2745 2749 /* case 2: engulf */ 2746 2750 else if ( (chkrgn->upper <= range.upper) && 2747 (chkrgn->lower >= range.lower) ) 2751 (chkrgn->lower >= range.lower) ) 2748 2752 { 2749 2753 DPA_DeletePtr(ranges->hdpa, index); … … 2813 2817 lvItem.state = 0; 2814 2818 lvItem.stateMask = LVIS_SELECTED; 2815 2819 2816 2820 /* need to clone the DPA because callbacks can change it */ 2817 2821 if (!(clone = ranges_clone(infoPtr->selectionRanges))) return FALSE; … … 2828 2832 { 2829 2833 RANGES toSkip; 2830 2834 2831 2835 if (!(toSkip = ranges_create(1))) return FALSE; 2832 2836 if (nItem != -1) ranges_additem(toSkip, nItem); … … 2889 2893 2890 2894 if (nItem == infoPtr->nFocusedItem) return FALSE; 2891 2895 2892 2896 lvItem.state = nItem == -1 ? 0 : LVIS_FOCUSED; 2893 2897 lvItem.stateMask = LVIS_FOCUSED; … … 2941 2945 if (nNewFocus != infoPtr->nFocusedItem) 2942 2946 LISTVIEW_SetItemFocus(infoPtr, nNewFocus); 2943 2947 2944 2948 /* But we are not supposed to modify nHotItem! */ 2945 2949 … … 3002 3006 if (!(selection = ranges_create(100))) return; 3003 3007 3004 item.state = LVIS_SELECTED; 3008 item.state = LVIS_SELECTED; 3005 3009 item.stateMask = LVIS_SELECTED; 3006 3010 … … 3015 3019 { 3016 3020 RANGE sel; 3017 3021 3018 3022 sel.lower = min(infoPtr->nSelectionMark, nItem); 3019 3023 sel.upper = max(infoPtr->nSelectionMark, nItem) + 1; … … 3046 3050 /* this will also destroy the selection */ 3047 3051 iterator_destroy(&i); 3048 3052 3049 3053 LISTVIEW_SetItemFocus(infoPtr, nItem); 3050 3054 } … … 3066 3070 3067 3071 TRACE("nItem=%d\n", nItem); 3068 3072 3069 3073 LISTVIEW_DeselectAllSkipItem(infoPtr, nItem); 3070 3074 … … 3188 3192 } 3189 3193 } 3190 #ifdef __WIN32OS2__3191 else3192 if(!infoPtr->bDragInProcess && (infoPtr->bLButtonDown || infoPtr->bRButtonDown) && infoPtr->nSelectionMark != -1) {3193 NMLISTVIEW nml = {0};3194 nml.iItem = infoPtr->nSelectionMark;3195 notify_listview(infoPtr, (infoPtr->bLButtonDown) ? LVN_BEGINDRAG : LVN_BEGINRDRAG, &nml);3196 infoPtr->bDragInProcess = TRUE;3197 }3198 #endif3199 3194 return 0; 3200 3195 } … … 3202 3197 3203 3198 /*** 3204 * Tests wheather the item is assignable to a list with style lStyle 3199 * Tests wheather the item is assignable to a list with style lStyle 3205 3200 */ 3206 3201 static inline BOOL is_assignable_item(const LVITEMW *lpLVItem, LONG lStyle) 3207 3202 { 3208 if ( (lpLVItem->mask & LVIF_TEXT) && 3203 if ( (lpLVItem->mask & LVIF_TEXT) && 3209 3204 (lpLVItem->pszText == LPSTR_TEXTCALLBACKW) && 3210 3205 (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) ) return FALSE; 3211 3206 3212 3207 return TRUE; 3213 3208 } … … 3240 3235 3241 3236 assert(lpLVItem->iItem >= 0 && lpLVItem->iItem < infoPtr->nItemCount); 3242 3243 if (lpLVItem->mask == 0) return TRUE; 3237 3238 if (lpLVItem->mask == 0) return TRUE; 3244 3239 3245 3240 if (infoPtr->dwStyle & LVS_OWNERDATA) … … 3267 3262 3268 3263 TRACE("oldState=%x, newState=%x\n", item.state, lpLVItem->state); 3269 /* determine what fields will change */ 3264 /* determine what fields will change */ 3270 3265 if ((lpLVItem->mask & LVIF_STATE) && ((item.state ^ lpLVItem->state) & lpLVItem->stateMask & ~infoPtr->uCallbackMask)) 3271 3266 uChanged |= LVIF_STATE; … … 3282 3277 if ((lpLVItem->mask & LVIF_TEXT) && textcmpWT(lpItem->hdr.pszText, lpLVItem->pszText, isW)) 3283 3278 uChanged |= LVIF_TEXT; 3284 3285 TRACE("uChanged=0x%x\n", uChanged); 3279 3280 TRACE("uChanged=0x%x\n", uChanged); 3286 3281 if (!uChanged) return TRUE; 3287 3282 *bChanged = TRUE; 3288 3283 3289 3284 ZeroMemory(&nmlv, sizeof(NMLISTVIEW)); 3290 3285 nmlv.iItem = lpLVItem->iItem; … … 3293 3288 nmlv.uChanged = uChanged; 3294 3289 nmlv.lParam = item.lParam; 3295 3290 3296 3291 /* send LVN_ITEMCHANGING notification, if the item is not being inserted */ 3297 3292 /* and we are _NOT_ virtual (LVS_OWERNDATA), and change notifications */ … … 3345 3340 /* if we're inserting the item, we're done */ 3346 3341 if (isNew) return TRUE; 3347 3342 3348 3343 /* send LVN_ITEMCHANGED notification */ 3349 3344 if (lpLVItem->mask & LVIF_PARAM) nmlv.lParam = lpLVItem->lParam; … … 3374 3369 /* we do not support subitems for virtual listviews */ 3375 3370 if (infoPtr->dwStyle & LVS_OWNERDATA) return FALSE; 3376 3371 3377 3372 /* set subitem only if column is present */ 3378 3373 if (lpLVItem->iSubItem >= infoPtr->hdpaColumns->nItemCount) return FALSE; 3379 3374 3380 3375 /* First do some sanity checks */ 3381 3376 if (lpLVItem->mask & ~(LVIF_TEXT | LVIF_IMAGE)) return FALSE; 3382 3377 if (!(lpLVItem->mask & (LVIF_TEXT | LVIF_IMAGE))) return TRUE; 3383 3378 3384 3379 /* get the subitem structure, and create it if not there */ 3385 3380 hdpaSubItems = (HDPA)DPA_GetPtr(infoPtr->hdpaItems, lpLVItem->iItem); 3386 3381 assert (hdpaSubItems); 3387 3382 3388 3383 lpSubItem = LISTVIEW_GetSubItemPtr(hdpaSubItems, lpLVItem->iSubItem); 3389 3384 if (!lpSubItem) … … 3408 3403 *bChanged = TRUE; 3409 3404 } 3410 3405 3411 3406 if (lpLVItem->mask & LVIF_IMAGE) 3412 3407 if (lpSubItem->hdr.iImage != lpLVItem->iImage) … … 3444 3439 LPWSTR pszText = NULL; 3445 3440 BOOL bResult, bChanged = FALSE; 3446 3441 3447 3442 TRACE("(lpLVItem=%s, isW=%d)\n", debuglvitem_t(lpLVItem, isW), isW); 3448 3443 … … 3456 3451 ((LVITEMW *)lpLVItem)->pszText = textdupTtoW(lpLVItem->pszText, isW); 3457 3452 } 3458 3453 3459 3454 /* actually set the fields */ 3460 3455 if (!is_assignable_item(lpLVItem, infoPtr->dwStyle)) return FALSE; 3461 3456 3462 3457 if (lpLVItem->iSubItem) 3463 3458 bResult = set_sub_item(infoPtr, lpLVItem, TRUE, &bChanged); … … 3514 3509 if ((lStyle & WS_VSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo)) 3515 3510 nItem = scrollInfo.nPos; 3516 } 3511 } 3517 3512 else 3518 3513 { … … 3522 3517 3523 3518 TRACE("nItem=%d\n", nItem); 3524 3519 3525 3520 return nItem; 3526 3521 } … … 3598 3593 lvItem.pszText = szDispText; 3599 3594 if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE; 3600 if (nSubItem > 0 && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 3595 if (nSubItem > 0 && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 3601 3596 lvItem.state = LISTVIEW_GetItemState(infoPtr, nItem, LVIS_SELECTED); 3602 3597 if (lvItem.pszText == LPSTR_TEXTCALLBACKW) lvItem.pszText = szCallback; … … 3605 3600 /* now check if we need to update the focus rectangle */ 3606 3601 lprcFocus = infoPtr->bFocus && (lvItem.state & LVIS_FOCUSED) ? &infoPtr->rcFocus : 0; 3607 3602 3608 3603 if (!lprcFocus) lvItem.state &= ~LVIS_FOCUSED; 3609 3604 LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel); … … 3612 3607 OffsetRect(&rcIcon, pos.x, pos.y); 3613 3608 OffsetRect(&rcLabel, pos.x, pos.y); 3614 TRACE(" rcBox=%s, rcState=%s, rcIcon=%s. rcLabel=%s\n", 3609 TRACE(" rcBox=%s, rcState=%s, rcIcon=%s. rcLabel=%s\n", 3615 3610 debugrect(&rcBox), debugrect(&rcState), debugrect(&rcIcon), debugrect(&rcLabel)); 3616 3611 … … 3620 3615 if (cdmode & CDRF_NOTIFYITEMDRAW) 3621 3616 cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd); 3617 if (nSubItem == 0) infoPtr->cditemmode = cditemmode; 3622 3618 if (cditemmode & CDRF_SKIPDEFAULT) goto postpaint; 3623 3619 … … 3625 3621 if (nSubItem && uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 3626 3622 nmlvcd.clrTextBk = CLR_NONE; 3627 3623 3628 3624 /* state icons */ 3629 3625 if (infoPtr->himlState && !IsRectEmpty(&rcState)) … … 3653 3649 if ((lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus != FALSE)) 3654 3650 { 3655 /* set item colors */ 3651 /* set item colors */ 3656 3652 dwBkColor = SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT)); 3657 3653 dwTextColor = SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT)); … … 3659 3655 nMixMode = SetROP2(hdc, R2_XORPEN); 3660 3656 } 3661 else if ((infoPtr->dwStyle & LVS_SHOWSELALWAYS) && 3657 else if ((infoPtr->dwStyle & LVS_SHOWSELALWAYS) && 3662 3658 (lvItem.state & LVIS_SELECTED) && (infoPtr->bFocus == FALSE)) 3663 3659 { … … 3694 3690 if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 3695 3691 rcSelect.right = rcBox.right; 3696 3697 if (nmlvcd.clrTextBk != CLR_NONE) 3692 3693 if (nmlvcd.clrTextBk != CLR_NONE) 3698 3694 #ifdef __WIN32OS2__ 3699 3695 ExtTextOutW(hdc, rcSelect.left, rcSelect.top, textoutOptions, &rcSelect, 0, 0, 0); … … 3703 3699 if(lprcFocus) *lprcFocus = rcSelect; 3704 3700 } 3705 3701 3706 3702 /* figure out the text drawing flags */ 3707 3703 uFormat = (uView == LVS_ICON ? (lprcFocus ? LV_FL_DT_FLAGS : LV_ML_DT_FLAGS) : LV_SL_DT_FLAGS); … … 3763 3759 DRAWITEMSTRUCT dis; 3764 3760 LVITEMW item; 3765 3761 3766 3762 TRACE("()\n"); 3767 3763 3768 3764 ZeroMemory(&dis, sizeof(dis)); 3769 3765 3770 3766 /* Get scroll info once before loop */ 3771 3767 LISTVIEW_GetOrigin(infoPtr, &Origin); 3772 3768 3773 3769 /* iterate through the invalidated rows */ 3774 3770 while(iterator_next(i)) … … 3779 3775 item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; 3780 3776 if (!LISTVIEW_GetItemW(infoPtr, &item)) continue; 3781 3777 3782 3778 dis.CtlType = ODT_LISTVIEW; 3783 3779 dis.CtlID = uID; … … 3803 3799 cditemmode = notify_prepaint (infoPtr, hdc, &nmlvcd); 3804 3800 } 3805 3801 3806 3802 if (!(cditemmode & CDRF_SKIPDEFAULT)) 3807 3803 SendMessageW(hwndParent, WM_DRAWITEM, dis.CtlID, (LPARAM)&dis); … … 3837 3833 rgntype = GetClipBox(hdc, &rcClip); 3838 3834 if (rgntype == NULLREGION) return; 3839 3835 3840 3836 /* Get scroll info once before loop */ 3841 3837 LISTVIEW_GetOrigin(infoPtr, &Origin); 3842 3838 3843 3839 /* narrow down the columns we need to paint */ 3844 3840 for(colRange.lower = 0; colRange.lower < infoPtr->hdpaColumns->nItemCount; colRange.lower++) … … 3901 3897 /* Get scroll info once before loop */ 3902 3898 LISTVIEW_GetOrigin(infoPtr, &Origin); 3903 3899 3904 3900 while(iterator_prev(i)) 3905 3901 { … … 3936 3932 3937 3933 LISTVIEW_DUMP(infoPtr); 3938 3934 3939 3935 infoPtr->bIsDrawing = TRUE; 3940 3936 … … 3947 3943 oldClrTextBk = infoPtr->clrTextBk; 3948 3944 oldClrText = infoPtr->clrText; 3949 3945 3946 infoPtr->cditemmode = CDRF_DODEFAULT; 3947 3950 3948 GetClientRect(infoPtr->hwndSelf, &rcClient); 3951 3949 customdraw_fill(&nmlvcd, infoPtr, hdc, &rcClient, 0); … … 3962 3960 /* figure out what we need to draw */ 3963 3961 iterator_visibleitems(&i, infoPtr, hdc); 3964 3962 3965 3963 /* send cache hint notification */ 3966 3964 if (infoPtr->dwStyle & LVS_OWNERDATA) … … 3989 3987 } 3990 3988 iterator_destroy(&i); 3991 3989 3992 3990 enddraw: 3993 3991 if (cdmode & CDRF_NOTIFYPOSTPAINT) … … 4098 4096 wWidth = nColumnCount * infoPtr->nItemWidth + 2; 4099 4097 4100 dwViewRect = MAKELONG(wWidth, wHeight); 4098 dwViewRect = MAKELONG(wWidth, wHeight); 4101 4099 } 4102 4100 #else … … 4111 4109 } 4112 4110 4113 /* << LISTVIEW_CreateDragImage >> */ 4111 4112 /*** 4113 * DESCRIPTION: 4114 * Create a drag image list for the specified item. 4115 * 4116 * PARAMETER(S): 4117 * [I] infoPtr : valid pointer to the listview structure 4118 * [I] iItem : index of item 4119 * [O] lppt : Upperr-left corner of the image 4120 * 4121 * RETURN: 4122 * Returns a handle to the image list if successful, NULL otherwise. 4123 */ 4124 static HIMAGELIST LISTVIEW_CreateDragImage(LISTVIEW_INFO *infoPtr, INT iItem, LPPOINT lppt) 4125 { 4126 RECT rcItem; 4127 SIZE size; 4128 POINT pos; 4129 HDC hdc, hdcOrig; 4130 HBITMAP hbmp, hOldbmp; 4131 HIMAGELIST dragList = 0; 4132 TRACE("iItem=%d Count=%d \n", iItem, infoPtr->nItemCount); 4133 4134 if (iItem < 0 || iItem >= infoPtr->nItemCount) 4135 return 0; 4136 4137 rcItem.left = LVIR_BOUNDS; 4138 if (!LISTVIEW_GetItemRect(infoPtr, iItem, &rcItem)) 4139 return 0; 4140 4141 lppt->x = rcItem.left; 4142 lppt->y = rcItem.top; 4143 4144 size.cx = rcItem.right - rcItem.left; 4145 size.cy = rcItem.bottom - rcItem.top; 4146 4147 hdcOrig = GetDC(infoPtr->hwndSelf); 4148 hdc = CreateCompatibleDC(hdcOrig); 4149 hbmp = CreateCompatibleBitmap(hdcOrig, size.cx, size.cy); 4150 hOldbmp = SelectObject(hdc, hbmp); 4151 4152 rcItem.left = rcItem.top = 0; 4153 rcItem.right = size.cx; 4154 rcItem.bottom = size.cy; 4155 FillRect(hdc, &rcItem, infoPtr->hBkBrush); 4156 4157 pos.x = pos.y = 0; 4158 if (LISTVIEW_DrawItem(infoPtr, hdc, iItem, 0, pos, infoPtr->cditemmode)) 4159 { 4160 dragList = ImageList_Create(size.cx, size.cy, ILC_COLOR, 10, 10); 4161 SelectObject(hdc, hOldbmp); 4162 ImageList_Add(dragList, hbmp, 0); 4163 } 4164 else 4165 SelectObject(hdc, hOldbmp); 4166 4167 DeleteObject(hbmp); 4168 DeleteDC(hdc); 4169 ReleaseDC(infoPtr->hwndSelf, hdcOrig); 4170 4171 TRACE("ret=%p\n", dragList); 4172 4173 return dragList; 4174 } 4114 4175 4115 4176 … … 4168 4229 infoPtr->nItemCount --; 4169 4230 } 4170 4231 4171 4232 LISTVIEW_UpdateScroll(infoPtr); 4172 4233 4173 4234 LISTVIEW_InvalidateList(infoPtr); 4174 4235 4175 4236 return TRUE; 4176 4237 } … … 4193 4254 RECT rcOld, rcCol; 4194 4255 INT nCol; 4195 4256 4196 4257 lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, min(nColumn, infoPtr->hdpaColumns->nItemCount - 1)); 4197 4258 rcCol = lpColumnInfo->rcHeader; 4198 4259 if (nColumn >= infoPtr->hdpaColumns->nItemCount) 4199 4260 rcCol.left = rcCol.right; 4200 4261 4201 4262 /* ajust the other columns */ 4202 4263 for (nCol = nColumn; nCol < infoPtr->hdpaColumns->nItemCount; nCol++) … … 4209 4270 /* do not update screen if not in report mode */ 4210 4271 if (!is_redrawing(infoPtr) || (infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return; 4211 4272 4212 4273 /* if we have a focus, must first erase the focus rect */ 4213 4274 if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, FALSE); 4214 4275 4215 4276 /* Need to reset the item width when inserting a new column */ 4216 4277 infoPtr->nItemWidth += dx; … … 4222 4283 rcOld.left = rcCol.left; 4223 4284 ScrollWindowEx(infoPtr->hwndSelf, dx, 0, &rcOld, &rcOld, 0, 0, SW_ERASE | SW_INVALIDATE); 4224 4285 4225 4286 /* we can restore focus now */ 4226 4287 if (infoPtr->bFocus) LISTVIEW_ShowFocusRect(infoPtr, TRUE); … … 4242 4303 { 4243 4304 RECT rcCol; 4244 4305 4245 4306 TRACE("nColumn=%d\n", nColumn); 4246 4307 … … 4251 4312 it does in fact work on WinNT, and at least one app depends on it. On 4252 4313 WinNT, deleting column zero deletes the last column of items but the 4253 first header. Since no app will ever depend on that bizarre behavior, 4314 first header. Since no app will ever depend on that bizarre behavior, 4254 4315 we just delete the last column including the header. 4255 4316 */ … … 4258 4319 4259 4320 LISTVIEW_GetHeaderRect(infoPtr, nColumn, &rcCol); 4260 4321 4261 4322 if (!Header_DeleteItem(infoPtr->hwndHeader, nColumn)) 4262 4323 return FALSE; … … 4264 4325 COMCTL32_Free(DPA_GetPtr(infoPtr->hdpaColumns, nColumn)); 4265 4326 DPA_DeletePtr(infoPtr->hdpaColumns, nColumn); 4266 4327 4267 4328 if (!(infoPtr->dwStyle & LVS_OWNERDATA)) 4268 4329 { … … 4273 4334 if (nColumn == 0) 4274 4335 return LISTVIEW_DeleteAllItems(infoPtr); 4275 4336 4276 4337 for (nItem = 0; nItem < infoPtr->nItemCount; nItem++) 4277 4338 { … … 4287 4348 lpDelItem = lpSubItem; 4288 4349 } 4289 else if (lpSubItem->iSubItem > nColumn) 4350 else if (lpSubItem->iSubItem > nColumn) 4290 4351 { 4291 4352 lpSubItem->iSubItem--; … … 4336 4397 /* if we don't refresh, what's the point of scrolling? */ 4337 4398 if (!is_redrawing(infoPtr)) return; 4338 4399 4339 4400 assert (abs(dir) == 1); 4340 4401 … … 4351 4412 LISTVIEW_UpdateScroll(infoPtr); 4352 4413 4353 /* figure out the item's position */ 4414 /* figure out the item's position */ 4354 4415 if (uView == LVS_REPORT) 4355 4416 nPerCol = infoPtr->nItemCount + 1; … … 4358 4419 else /* LVS_ICON, or LVS_SMALLICON */ 4359 4420 return; 4360 4421 4361 4422 nItemCol = nItem / nPerCol; 4362 4423 nItemRow = nItem % nPerCol; … … 4373 4434 { 4374 4435 TRACE("Scrolling rcScroll=%s, rcList=%s\n", debugrect(&rcScroll), debugrect(&infoPtr->rcList)); 4375 ScrollWindowEx(infoPtr->hwndSelf, 0, dir * infoPtr->nItemHeight, 4436 ScrollWindowEx(infoPtr->hwndSelf, 0, dir * infoPtr->nItemHeight, 4376 4437 &rcScroll, &rcScroll, 0, 0, SW_ERASE | SW_INVALIDATE); 4377 4438 } … … 4411 4472 4412 4473 if (nItem < 0 || nItem >= infoPtr->nItemCount) return FALSE; 4413 4474 4414 4475 /* remove selection, and focus */ 4415 4476 item.state = 0; 4416 4477 item.stateMask = LVIS_SELECTED | LVIS_FOCUSED; 4417 4478 LISTVIEW_SetItemState(infoPtr, nItem, &item); 4418 4479 4419 4480 /* send LVN_DELETEITEM notification. */ 4420 4481 notify_deleteitem(infoPtr, nItem); 4421 4482 4422 /* we need to do this here, because we'll be deleting stuff */ 4483 /* we need to do this here, because we'll be deleting stuff */ 4423 4484 if (uView == LVS_SMALLICON || uView == LVS_ICON) 4424 4485 LISTVIEW_InvalidateItem(infoPtr, nItem); 4425 4486 4426 4487 if (!(infoPtr->dwStyle & LVS_OWNERDATA)) 4427 4488 { … … 4537 4598 rect.left = LVIR_LABEL; 4538 4599 if (!LISTVIEW_GetItemRect(infoPtr, nItem, &rect)) return 0; 4539 4600 4540 4601 ZeroMemory(&dispInfo, sizeof(dispInfo)); 4541 4602 dispInfo.item.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT; … … 4550 4611 rect.left-2, rect.top-1, 0, rect.bottom - rect.top+2, isW); 4551 4612 if (!infoPtr->hwndEdit) return 0; 4552 4613 4553 4614 if (notify_dispinfoT(infoPtr, LVN_BEGINLABELEDITW, &dispInfo, isW)) 4554 4615 { … … 4593 4654 4594 4655 if (bPartial && IntersectRect(&rcTemp, &infoPtr->rcList, &rcItem)) return TRUE; 4595 4656 4596 4657 if (rcItem.left < infoPtr->rcList.left || rcItem.right > infoPtr->rcList.right) 4597 4658 { … … 4678 4739 4679 4740 if (!lpFindInfo || nItem < 0) return -1; 4680 4741 4681 4742 lvItem.mask = 0; 4682 4743 if (lpFindInfo->flags & (LVFI_STRING | LVFI_PARTIAL)) … … 4690 4751 bWrap = TRUE; 4691 4752 4692 if ((lpFindInfo->flags & LVFI_NEARESTXY) && 4753 if ((lpFindInfo->flags & LVFI_NEARESTXY) && 4693 4754 (uView == LVS_ICON || uView ==LVS_SMALLICON)) 4694 4755 { … … 4710 4771 case VK_END: 4711 4772 LISTVIEW_GetAreaRect(infoPtr, &rcArea); 4712 Destination.x = rcArea.right; 4713 Destination.y = rcArea.bottom; 4773 Destination.x = rcArea.right; 4774 Destination.y = rcArea.bottom; 4714 4775 break; 4715 4776 default: ERR("Unknown vkDirection=%d\n", lpFindInfo->vkDirection); … … 5091 5152 5092 5153 /* if focus is handled by us, report it */ 5093 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 5154 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 5094 5155 { 5095 5156 lpLVItem->state &= ~LVIS_FOCUSED; … … 5099 5160 5100 5161 /* and do the same for selection, if we handle it */ 5101 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 5162 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 5102 5163 { 5103 5164 lpLVItem->state &= ~LVIS_SELECTED; … … 5128 5189 dispInfo.item.stateMask = infoPtr->uCallbackMask; 5129 5190 } 5130 5191 5131 5192 /* Do we need to enquire about the image? */ 5132 5193 if ((lpLVItem->mask & LVIF_IMAGE) && pItemHdr->iImage == I_IMAGECALLBACK) … … 5182 5243 /* if this is a subitem, we're done */ 5183 5244 if (lpLVItem->iSubItem) return TRUE; 5184 5245 5185 5246 /* Next is the lParam field */ 5186 5247 if (dispInfo.item.mask & LVIF_PARAM) … … 5194 5255 5195 5256 /* ... the state field (this one is different due to uCallbackmask) */ 5196 if (lpLVItem->mask & LVIF_STATE) 5257 if (lpLVItem->mask & LVIF_STATE) 5197 5258 { 5198 5259 lpLVItem->state = lpItem->state; … … 5202 5263 lpLVItem->state |= (dispInfo.item.state & dispInfo.item.stateMask); 5203 5264 } 5204 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 5265 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_FOCUSED ) 5205 5266 { 5206 5267 lpLVItem->state &= ~LVIS_FOCUSED; … … 5208 5269 lpLVItem->state |= LVIS_FOCUSED; 5209 5270 } 5210 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 5271 if ( lpLVItem->stateMask & ~infoPtr->uCallbackMask & LVIS_SELECTED ) 5211 5272 { 5212 5273 lpLVItem->state &= ~LVIS_SELECTED; 5213 5274 if (ranges_contain(infoPtr->selectionRanges, lpLVItem->iItem)) 5214 5275 lpLVItem->state |= LVIS_SELECTED; 5215 } 5276 } 5216 5277 } 5217 5278 … … 5293 5354 lpptPosition->x += Origin.x; 5294 5355 lpptPosition->y += Origin.y; 5295 5356 5296 5357 TRACE (" lpptPosition=%s\n", debugpoint(lpptPosition)); 5297 5358 return TRUE; … … 5444 5505 * on input, lprc->top = nSubItem 5445 5506 * lprc->left = LVIR_ICON | LVIR_BOUNDS | LVIR_LABEL 5446 * 5507 * 5447 5508 * NOTE: for subItem = 0, we should return the bounds of the _entire_ item, 5448 5509 * not only those of the first column. 5449 5510 * Fortunately, LISTVIEW_GetItemMetrics does the right thing. 5450 * 5511 * 5451 5512 * RETURN: 5452 5513 * TRUE: success … … 5457 5518 POINT Position; 5458 5519 LVITEMW lvItem; 5459 5520 5460 5521 if (!lprc || (infoPtr->dwStyle & LVS_TYPEMASK) != LVS_REPORT) return FALSE; 5461 5522 5462 5523 TRACE("(nItem=%d, nSubItem=%ld)\n", nItem, lprc->top); 5463 5524 /* On WinNT, a subitem of '0' calls LISTVIEW_GetItemRect */ … … 5470 5531 lvItem.iItem = nItem; 5471 5532 lvItem.iSubItem = lprc->top; 5472 5533 5473 5534 if (lvItem.mask && !LISTVIEW_GetItemW(infoPtr, &lvItem)) return FALSE; 5474 5535 switch(lprc->left) … … 5517 5578 lvItem.cchTextMax = DISP_TEXT_SIZE; 5518 5579 if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return 0; 5519 5580 5520 5581 return LISTVIEW_GetStringWidthT(infoPtr, lvItem.pszText, TRUE); 5521 5582 } … … 5641 5702 uMask |= LVIS_SELECTED; 5642 5703 5643 /* if we're asked for the focused item, that's only one, 5704 /* if we're asked for the focused item, that's only one, 5644 5705 * so it's worth optimizing */ 5645 5706 if (uFlags & LVNI_FOCUSED) … … 5648 5709 return (infoPtr->nFocusedItem == nItem) ? -1 : infoPtr->nFocusedItem; 5649 5710 } 5650 5711 5651 5712 if (uFlags & LVNI_ABOVE) 5652 5713 { … … 5825 5886 SCROLLINFO scrollInfo; 5826 5887 5827 scrollInfo.cbSize = sizeof(SCROLLINFO); 5888 scrollInfo.cbSize = sizeof(SCROLLINFO); 5828 5889 scrollInfo.fMask = SIF_POS; 5829 5890 5830 5891 if ((infoPtr->dwStyle & WS_HSCROLL) && GetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo)) 5831 5892 nHorzPos = scrollInfo.nPos; … … 5841 5902 else if (uView == LVS_REPORT) 5842 5903 nVertPos *= infoPtr->nItemHeight; 5843 5904 5844 5905 lpptOrigin->x -= nHorzPos; 5845 5906 lpptOrigin->y -= nVertPos; … … 5864 5925 { 5865 5926 SIZE stringSize; 5866 5867 stringSize.cx = 0; 5927 5928 stringSize.cx = 0; 5868 5929 if (is_textT(lpszText, isW)) 5869 5930 { … … 5890 5951 mis.itemHeight = 0; 5891 5952 mis.itemWidth = 0; 5892 if (isW) 5953 if (isW) 5893 5954 SendMessageW(GetParent(infoPtr->hwndSelf), WM_MEASUREITEM, id, (LPARAM)&mis ); 5894 5955 else … … 5915 5976 * an app might pass only a structure with space up to iItem! 5916 5977 * (MS Office 97 does that for instance in the file open dialog) 5917 * 5978 * 5918 5979 * RETURN: 5919 5980 * SUCCESS : item index … … 5928 5989 LVITEMW lvItem; 5929 5990 ITERATOR i; 5930 5991 5931 5992 TRACE("(pt=%s, subitem=%d, select=%d)\n", debugpoint(&lpht->pt), subitem, select); 5932 5993 5933 5994 lpht->flags = 0; 5934 5995 lpht->iItem = -1; … … 5939 6000 else if (infoPtr->rcList.right < lpht->pt.x) 5940 6001 lpht->flags |= LVHT_TORIGHT; 5941 6002 5942 6003 if (infoPtr->rcList.top > lpht->pt.y) 5943 6004 lpht->flags |= LVHT_ABOVE; … … 5951 6012 5952 6013 LISTVIEW_GetOrigin(infoPtr, &Origin); 5953 6014 5954 6015 /* first deal with the large items */ 5955 6016 rcSearch.left = lpht->pt.x; … … 5957 6018 rcSearch.right = rcSearch.left + 1; 5958 6019 rcSearch.bottom = rcSearch.top + 1; 5959 6020 5960 6021 iterator_frameditems(&i, infoPtr, &rcSearch); 5961 6022 iterator_next(&i); /* go to first item in the sequence */ 5962 6023 lpht->iItem = i.nItem; 5963 6024 iterator_destroy(&i); 5964 5965 TRACE("lpht->iItem=%d\n", lpht->iItem); 6025 6026 TRACE("lpht->iItem=%d\n", lpht->iItem); 5966 6027 if (lpht->iItem == -1) return -1; 5967 6028 … … 5975 6036 lvItem.cchTextMax = DISP_TEXT_SIZE; 5976 6037 if (!LISTVIEW_GetItemW(infoPtr, &lvItem)) return -1; 5977 if (!infoPtr->bFocus) lvItem.state &= ~LVIS_FOCUSED; 5978 6038 if (!infoPtr->bFocus) lvItem.state &= ~LVIS_FOCUSED; 6039 5979 6040 LISTVIEW_GetItemMetrics(infoPtr, &lvItem, &rcBox, &rcState, &rcIcon, &rcLabel); 5980 6041 LISTVIEW_GetItemOrigin(infoPtr, lpht->iItem, &Position); 5981 6042 opt.x = lpht->pt.x - Position.x - Origin.x; 5982 6043 opt.y = lpht->pt.y - Position.y - Origin.y; 5983 6044 5984 6045 if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) 5985 6046 rcBounds = rcBox; … … 5997 6058 if (lpht->flags & LVHT_ONITEM) 5998 6059 lpht->flags &= ~LVHT_NOWHERE; 5999 6000 TRACE("lpht->flags=0x%x\n", lpht->flags); 6060 6061 TRACE("lpht->flags=0x%x\n", lpht->flags); 6001 6062 if (uView == LVS_REPORT && lpht->iItem != -1 && subitem) 6002 6063 { … … 6019 6080 6020 6081 if (uView == LVS_REPORT && (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT)) return lpht->iItem; 6021 6082 6022 6083 if (uView == LVS_REPORT) UnionRect(&rcBounds, &rcIcon, &rcLabel); 6023 6084 return PtInRect(&rcBounds, opt) ? lpht->iItem : -1; … … 6045 6106 ITEM_INFO* lv_first = (ITEM_INFO*) DPA_GetPtr( (HDPA)first, 0 ); 6046 6107 ITEM_INFO* lv_second = (ITEM_INFO*) DPA_GetPtr( (HDPA)second, 0 ); 6047 INT cmpv = textcmpWT(lv_first->hdr.pszText, lv_second->hdr.pszText, TRUE); 6108 INT cmpv = textcmpWT(lv_first->hdr.pszText, lv_second->hdr.pszText, TRUE); 6048 6109 6049 6110 /* if we're sorting descending, negate the return value */ … … 6085 6146 if ( !(lpItem = (ITEM_INFO *)COMCTL32_Alloc(sizeof(ITEM_INFO))) ) 6086 6147 return -1; 6087 6148 6088 6149 /* insert item in listview control data structure */ 6089 6150 if ( !(hdpaSubItems = DPA_Create(8)) ) goto fail; … … 6138 6199 } 6139 6200 } 6140 6201 6141 6202 /* Add the subitem list to the items array. Do this last in case we go to 6142 6203 * fail during the above. 6143 6204 */ 6144 6205 LISTVIEW_ShiftIndices(infoPtr, nItem, 1); 6145 6206 6146 6207 /* send LVN_INSERTITEM notification */ 6147 6208 ZeroMemory(&nmlv, sizeof(NMLISTVIEW)); … … 6193 6254 { 6194 6255 INT i; 6195 6196 if (nLast < nFirst || min(nFirst, nLast) < 0 || 6256 6257 if (nLast < nFirst || min(nFirst, nLast) < 0 || 6197 6258 max(nFirst, nLast) >= infoPtr->nItemCount) 6198 6259 return FALSE; 6199 6260 6200 6261 for (i = nFirst; i <= nLast; i++) 6201 6262 LISTVIEW_InvalidateItem(infoPtr, i); … … 6254 6315 if (dx != 0) LISTVIEW_HScroll(infoPtr, SB_INTERNAL, dx, 0); 6255 6316 if (dy != 0) LISTVIEW_VScroll(infoPtr, SB_INTERNAL, dy, 0); 6256 6317 6257 6318 return TRUE; 6258 6319 } … … 6387 6448 if (!lpColumn || nColumn < 0) return -1; 6388 6449 nColumn = min(nColumn, infoPtr->hdpaColumns->nItemCount); 6389 6450 6390 6451 ZeroMemory(&hdi, sizeof(HDITEMW)); 6391 6452 column_fill_hditem(infoPtr, &hdi, nColumn, lpColumn, isW); 6392 6453 6393 6454 /* insert item in header control */ 6394 nNewColumn = SendMessageW(infoPtr->hwndHeader, 6455 nNewColumn = SendMessageW(infoPtr->hwndHeader, 6395 6456 isW ? HDM_INSERTITEMW : HDM_INSERTITEMA, 6396 6457 (WPARAM)nColumn, (LPARAM)&hdi); 6397 6458 if (nNewColumn == -1) return -1; 6398 6459 if (nNewColumn != nColumn) ERR("nColumn=%d, nNewColumn=%d\n", nColumn, nNewColumn); 6399 6400 /* create our own column info */ 6460 6461 /* create our own column info */ 6401 6462 if (!(lpColumnInfo = COMCTL32_Alloc(sizeof(COLUMN_INFO)))) goto fail; 6402 6463 if (DPA_InsertPtr(infoPtr->hdpaColumns, nNewColumn, lpColumnInfo) == -1) goto fail; … … 6455 6516 /* make space for the new column */ 6456 6517 LISTVIEW_ScrollColumns(infoPtr, nNewColumn + 1, lpColumnInfo->rcHeader.right - lpColumnInfo->rcHeader.left); 6457 6518 6458 6519 return nNewColumn; 6459 6520 … … 6489 6550 6490 6551 TRACE("(nColumn=%d, lpColumn=%s, isW=%d)\n", nColumn, debuglvcolumn_t(lpColumn, isW), isW); 6491 6552 6492 6553 if (!lpColumn || nColumn < 0 || nColumn >= infoPtr->hdpaColumns->nItemCount) return FALSE; 6493 6554 … … 6576 6637 6577 6638 /* resize all columns if in LVS_LIST mode */ 6578 if(uView == LVS_LIST) 6639 if(uView == LVS_LIST) 6579 6640 { 6580 6641 infoPtr->nItemWidth = cx; … … 6612 6673 { 6613 6674 /* if iCol is the last column make it fill the remainder of the controls width */ 6614 if(nColumn == infoPtr->hdpaColumns->nItemCount - 1) 6675 if(nColumn == infoPtr->hdpaColumns->nItemCount - 1) 6615 6676 { 6616 6677 RECT rcHeader; … … 6700 6761 { 6701 6762 HCURSOR oldCursor = infoPtr->hHotCursor; 6702 6763 6703 6764 infoPtr->hHotCursor = hCursor; 6704 6765 … … 6722 6783 { 6723 6784 INT iOldIndex = infoPtr->nHotItem; 6724 6785 6725 6786 infoPtr->nHotItem = iIndex; 6726 6787 6727 6788 return iOldIndex; 6728 6789 } … … 6743 6804 { 6744 6805 DWORD oldHoverTime = infoPtr->dwHoverTime; 6745 6806 6746 6807 infoPtr->dwHoverTime = dwHoverTime; 6747 6808 6748 6809 return oldHoverTime; 6749 6810 } … … 6767 6828 6768 6829 TRACE("requested=(%d,%d)\n", cx, cy); 6769 6830 6770 6831 /* this is supported only for LVS_ICON style */ 6771 6832 if (uView != LVS_ICON) return oldspacing; 6772 6833 6773 6834 /* set to defaults, if instructed to */ 6774 6835 if (cx == -1) cx = GetSystemMetrics(SM_CXICONSPACING); … … 6782 6843 6783 6844 /* if 0 then compute height */ 6784 if (cy == 0) 6845 if (cy == 0) 6785 6846 cy = infoPtr->iconSize.cy + 2 * infoPtr->ntmHeight + 6786 6847 ICON_BOTTOM_PADDING + ICON_TOP_PADDING + LABEL_VERT_PADDING; 6787 6848 6788 6849 6789 6850 infoPtr->iconSpacing.cx = cx; … … 6791 6852 6792 6853 TRACE("old=(%d,%d), new=(%d,%d), iconSize=(%ld,%ld), ntmH=%d\n", 6793 LOWORD(oldspacing), HIWORD(oldspacing), cx, cy, 6854 LOWORD(oldspacing), HIWORD(oldspacing), cx, cy, 6794 6855 infoPtr->iconSize.cx, infoPtr->iconSize.cy, 6795 6856 infoPtr->ntmHeight); … … 6804 6865 { 6805 6866 INT cx, cy; 6806 6867 6807 6868 if (himl && ImageList_GetIconSize(himl, &cx, &cy)) 6808 6869 { … … 6921 6982 POINT Origin; 6922 6983 RECT rcErase; 6923 6984 6924 6985 LISTVIEW_GetOrigin(infoPtr, &Origin); 6925 6986 nFrom = min(nOldCount, nItems); 6926 6987 nTo = max(nOldCount, nItems); 6927 6988 6928 6989 if (uView == LVS_REPORT) 6929 6990 { … … 6998 7059 6999 7060 /* This point value seems to be an undocumented feature. 7000 * The best guess is that it means either at the origin, 7061 * The best guess is that it means either at the origin, 7001 7062 * or at true beginning of the list. I will assume the origin. */ 7002 7063 if ((pt.x == -1) && (pt.y == -1)) 7003 7064 pt = Origin; 7004 7065 7005 7066 if (uView == LVS_ICON) 7006 7067 { … … 7072 7133 7073 7134 if (nItem < 0 && nItem >= infoPtr->nItemCount) return FALSE; 7074 7135 7075 7136 lvItem.iItem = nItem; 7076 7137 lvItem.iSubItem = lpLVItem->iSubItem; … … 7078 7139 lvItem.pszText = lpLVItem->pszText; 7079 7140 lvItem.cchTextMax = lpLVItem->cchTextMax; 7080 7141 7081 7142 TRACE("(nItem=%d, lpLVItem=%s, isW=%d)\n", nItem, debuglvitem_t(&lvItem, isW), isW); 7082 7143 7083 return LISTVIEW_SetItemT(infoPtr, &lvItem, isW); 7144 return LISTVIEW_SetItemT(infoPtr, &lvItem, isW); 7084 7145 } 7085 7146 … … 7127 7188 LISTVIEW_InvalidateList(infoPtr); 7128 7189 } 7129 7190 7130 7191 return TRUE; 7131 7192 } … … 7241 7302 /* clear the lpItem->state for non-selected ones */ 7242 7303 /* remove the selection ranges */ 7243 7304 7244 7305 infoPtr->pfnCompare = pfnCompare; 7245 7306 infoPtr->lParamSort = lParamSort; … … 7391 7452 /* init item size to avoid division by 0 */ 7392 7453 LISTVIEW_UpdateItemSize (infoPtr); 7393 7454 7394 7455 if (uView == LVS_REPORT) 7395 7456 { … … 7456 7517 { 7457 7518 /* now we can scroll the list */ 7458 ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList, 7519 ScrollWindowEx(infoPtr->hwndSelf, dx, dy, &infoPtr->rcList, 7459 7520 &infoPtr->rcList, 0, 0, SW_ERASE | SW_INVALIDATE); 7460 7521 /* if we have focus, adjust rect */ … … 7483 7544 * 7484 7545 */ 7485 static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode, 7546 static LRESULT LISTVIEW_VScroll(LISTVIEW_INFO *infoPtr, INT nScrollCode, 7486 7547 INT nScrollDiff, HWND hScrollWnd) 7487 7548 { … … 7491 7552 BOOL is_an_icon; 7492 7553 7493 TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode, 7554 TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode, 7494 7555 debugscrollcode(nScrollCode), nScrollDiff); 7495 7556 … … 7536 7597 /* quit right away if pos isn't changing */ 7537 7598 if (nScrollDiff == 0) return 0; 7538 7599 7539 7600 /* calculate new position, and handle overflows */ 7540 7601 nNewScrollPos = scrollInfo.nPos + nScrollDiff; … … 7553 7614 scrollInfo.nPos = nNewScrollPos; 7554 7615 nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_VERT, &scrollInfo, TRUE); 7555 7616 7556 7617 /* carry on only if it really changed */ 7557 7618 if (nNewScrollPos == nOldScrollPos) return 0; 7558 7619 7559 7620 /* now adjust to client coordinates */ 7560 7621 nScrollDiff = nOldScrollPos - nNewScrollPos; 7561 7622 if (uView == LVS_REPORT) nScrollDiff *= infoPtr->nItemHeight; 7562 7563 /* and scroll the window */ 7623 7624 /* and scroll the window */ 7564 7625 scroll_list(infoPtr, 0, nScrollDiff); 7565 7626 … … 7595 7656 SCROLLINFO scrollInfo; 7596 7657 7597 TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode, 7658 TRACE("(nScrollCode=%d(%s), nScrollDiff=%d)\n", nScrollCode, 7598 7659 debugscrollcode(nScrollCode), nScrollDiff); 7599 7660 … … 7639 7700 /* quit right away if pos isn't changing */ 7640 7701 if (nScrollDiff == 0) return 0; 7641 7702 7642 7703 /* calculate new position, and handle overflows */ 7643 7704 nNewScrollPos = scrollInfo.nPos + nScrollDiff; … … 7656 7717 scrollInfo.nPos = nNewScrollPos; 7657 7718 nNewScrollPos = SetScrollInfo(infoPtr->hwndSelf, SB_HORZ, &scrollInfo, TRUE); 7658 7719 7659 7720 /* carry on only if it really changed */ 7660 7721 if (nNewScrollPos == nOldScrollPos) return 0; 7661 7722 7662 7723 if(uView == LVS_REPORT) 7663 7724 LISTVIEW_UpdateHeaderSize(infoPtr, nNewScrollPos); 7664 7725 7665 7726 /* now adjust to client coordinates */ 7666 7727 nScrollDiff = nOldScrollPos - nNewScrollPos; 7667 7728 if (uView == LVS_LIST) nScrollDiff *= infoPtr->nItemWidth; 7668 7729 7669 7730 /* and scroll the window */ 7670 7731 scroll_list(infoPtr, nScrollDiff, 0); … … 7740 7801 nmKeyDown.flags = 0; 7741 7802 #ifdef __WIN32OS2__ 7742 if(notify_hdr(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr) == TRUE) 7803 if(notify_hdr(infoPtr, LVN_KEYDOWN, &nmKeyDown.hdr) == TRUE) 7743 7804 return 0; //application processed this key press 7744 7805 #else … … 7823 7884 /* if we did not have the focus, there's nothing to do */ 7824 7885 if (!infoPtr->bFocus) return 0; 7825 7886 7826 7887 /* send NM_KILLFOCUS notification */ 7827 7888 notify(infoPtr, NM_KILLFOCUS); … … 7829 7890 /* if we have a focus rectagle, get rid of it */ 7830 7891 LISTVIEW_ShowFocusRect(infoPtr, FALSE); 7831 7892 7832 7893 /* set window focus flag */ 7833 7894 infoPtr->bFocus = FALSE; … … 7835 7896 /* invalidate the selected items before reseting focus flag */ 7836 7897 LISTVIEW_InvalidateSelectedItems(infoPtr); 7837 7898 7838 7899 return 0; 7839 7900 } 7901 7902 7903 /*** 7904 * DESCRIPTION: 7905 * Track mouse/dragging 7906 * 7907 * PARAMETER(S): 7908 * [I] infoPtr : valid pointer to the listview structure 7909 * [I] pt : mouse coordinate 7910 * 7911 * RETURN: 7912 * Zero 7913 */ 7914 static LRESULT LISTVIEW_TrackMouse(LISTVIEW_INFO *infoPtr, POINT pt) 7915 { 7916 INT cxDrag = GetSystemMetrics(SM_CXDRAG); 7917 INT cyDrag = GetSystemMetrics(SM_CYDRAG); 7918 RECT r; 7919 MSG msg; 7920 7921 TRACE("\n"); 7922 7923 r.top = pt.y - cyDrag; 7924 r.left = pt.x - cxDrag; 7925 r.bottom = pt.y + cyDrag; 7926 r.right = pt.x + cxDrag; 7927 7928 SetCapture(infoPtr->hwndSelf); 7929 7930 while (1) 7931 { 7932 if (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) 7933 { 7934 if (msg.message == WM_MOUSEMOVE) 7935 { 7936 pt.x = (short)LOWORD(msg.lParam); 7937 pt.y = (short)HIWORD(msg.lParam); 7938 if (PtInRect(&r, pt)) 7939 continue; 7940 else 7941 { 7942 ReleaseCapture(); 7943 return 1; 7944 } 7945 } 7946 else if (msg.message >= WM_LBUTTONDOWN && 7947 msg.message <= WM_RBUTTONDBLCLK) 7948 { 7949 break; 7950 } 7951 7952 DispatchMessageW(&msg); 7953 } 7954 7955 if (GetCapture() != infoPtr->hwndSelf) 7956 return 0; 7957 } 7958 7959 ReleaseCapture(); 7960 return 0; 7961 } 7962 7840 7963 7841 7964 /*** … … 7910 8033 if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) 7911 8034 { 8035 if ((infoPtr->dwLvExStyle & LVS_EX_CHECKBOXES) && (lvHitTestInfo.flags & LVHT_ONITEMSTATEICON)) 8036 { 8037 DWORD state = LISTVIEW_GetItemState(infoPtr, nItem, LVIS_STATEIMAGEMASK) >> 12; 8038 if(state == 1 || state == 2) 8039 { 8040 LVITEMW lvitem; 8041 state ^= 3; 8042 lvitem.state = state << 12; 8043 lvitem.stateMask = LVIS_STATEIMAGEMASK; 8044 LISTVIEW_SetItemState(infoPtr, nItem, &lvitem); 8045 } 8046 return 0; 8047 } 8048 if (LISTVIEW_TrackMouse(infoPtr, lvHitTestInfo.pt)) 8049 { 8050 NMLISTVIEW nmlv; 8051 8052 ZeroMemory(&nmlv, sizeof(nmlv)); 8053 nmlv.iItem = nItem; 8054 nmlv.ptAction.x = lvHitTestInfo.pt.x; 8055 nmlv.ptAction.y = lvHitTestInfo.pt.y; 8056 8057 notify_listview(infoPtr, LVN_BEGINDRAG, &nmlv); 8058 8059 return 0; 8060 } 8061 7912 8062 if (infoPtr->dwStyle & LVS_SINGLESEL) 7913 8063 { … … 7967 8117 /* remove all selections */ 7968 8118 LISTVIEW_DeselectAll(infoPtr); 8119 ReleaseCapture(); 7969 8120 } 7970 8121 … … 7992 8143 { 7993 8144 LVHITTESTINFO lvHitTestInfo; 7994 8145 7995 8146 TRACE("(key=%hu, X=%hu, Y=%hu)\n", wKey, pts.x, pts.y); 7996 8147 … … 8010 8161 if(lvHitTestInfo.iItem == infoPtr->nEditLabelItem && (lvHitTestInfo.flags & LVHT_ONITEMLABEL)) 8011 8162 LISTVIEW_EditLabelT(infoPtr, lvHitTestInfo.iItem, TRUE); 8012 8013 #ifdef __WIN32OS2__8014 if(infoPtr->bDragInProcess) {8015 infoPtr->bDragInProcess = FALSE;8016 }8017 #endif8018 8163 8019 8164 return 0; … … 8083 8228 { 8084 8229 UINT uView = infoPtr->dwStyle & LVS_TYPEMASK; 8085 8230 8086 8231 TRACE("(lpnmh=%p)\n", lpnmh); 8087 8232 8088 8233 if (!lpnmh || lpnmh->iItem < 0 || lpnmh->iItem >= infoPtr->hdpaColumns->nItemCount) return 0; 8089 8234 8090 8235 switch (lpnmh->hdr.code) 8091 { 8236 { 8092 8237 case HDN_TRACKW: 8093 8238 case HDN_TRACKA: … … 8101 8246 { 8102 8247 HDITEMW hdi; 8103 8248 8104 8249 hdi.mask = HDI_WIDTH; 8105 8250 if (!Header_GetItemW(infoPtr->hwndHeader, lpnmh->iItem, (LPARAM)&hdi)) return 0; … … 8108 8253 else 8109 8254 cxy = lpnmh->pitem->cxy; 8110 8255 8111 8256 /* determine how much we change since the last know position */ 8112 8257 lpColumnInfo = LISTVIEW_GetColumnInfo(infoPtr, lpnmh->iItem); … … 8168 8313 8169 8314 if (nCommand != NF_REQUERY) return 0; 8170 8315 8171 8316 infoPtr->notifyFormat = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwndSelf, NF_QUERY); 8172 8317 8173 8318 return 0; 8174 8319 } … … 8200 8345 LISTVIEW_UpdateScroll(infoPtr); 8201 8346 } 8202 if (hdc) 8347 if (hdc) 8203 8348 LISTVIEW_Refresh(infoPtr, hdc); 8204 8349 else … … 8231 8376 { 8232 8377 LVHITTESTINFO lvHitTestInfo; 8233 8378 8234 8379 TRACE("(key=%hu,X=%hu,Y=%hu)\n", wKey, pts.x, pts.y); 8235 8380 … … 8278 8423 lvHitTestInfo.pt.y = pts.y; 8279 8424 nItem = LISTVIEW_HitTest(infoPtr, &lvHitTestInfo, TRUE, TRUE); 8280 8425 8281 8426 if ((nItem >= 0) && (nItem < infoPtr->nItemCount)) 8282 8427 { … … 8314 8459 8315 8460 if (!infoPtr->bRButtonDown) return 0; 8316 8461 8317 8462 /* set button flag */ 8318 8463 infoPtr->bRButtonDown = FALSE; … … 8383 8528 /* if we have the focus already, there's nothing to do */ 8384 8529 if (infoPtr->bFocus) return 0; 8385 8530 8386 8531 /* send NM_SETFOCUS notification */ 8387 8532 notify(infoPtr, NM_SETFOCUS); … … 8419 8564 infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont; 8420 8565 if (infoPtr->hFont == oldFont) return 0; 8421 8566 8422 8567 LISTVIEW_SaveTextMetrics(infoPtr); 8423 8568 … … 8452 8597 8453 8598 if(!bRedraw) return 0; 8454 8599 8455 8600 if (is_autoarrange(infoPtr)) 8456 8601 LISTVIEW_Arrange(infoPtr, LVA_DEFAULT); … … 8485 8630 LISTVIEW_UpdateSize(infoPtr); 8486 8631 if (EqualRect(&rcOld, &infoPtr->rcList)) return 0; 8487 8488 /* do not bother with display related stuff if we're not redrawing */ 8632 8633 /* do not bother with display related stuff if we're not redrawing */ 8489 8634 if (!is_redrawing(infoPtr)) return 0; 8490 8491 if (is_autoarrange(infoPtr)) 8635 8636 if (is_autoarrange(infoPtr)) 8492 8637 LISTVIEW_Arrange(infoPtr, LVA_DEFAULT); 8493 8638 … … 8495 8640 8496 8641 /* refresh all only for lists whose height changed significantly */ 8497 if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_LIST && 8642 if ((infoPtr->dwStyle & LVS_TYPEMASK) == LVS_LIST && 8498 8643 (rcOld.bottom - rcOld.top) / infoPtr->nItemHeight != 8499 8644 (infoPtr->rcList.bottom - infoPtr->rcList.top) / infoPtr->nItemHeight) … … 8518 8663 8519 8664 TRACE("uView=%d, rcList(old)=%s\n", uView, debugrect(&infoPtr->rcList)); 8520 8665 8521 8666 GetClientRect(infoPtr->hwndSelf, &infoPtr->rcList); 8522 8667 … … 8573 8718 8574 8719 if (wStyleType != GWL_STYLE) return 0; 8575 8720 8576 8721 /* FIXME: if LVS_NOSORTHEADER changed, update header */ 8577 8722 /* what if LVS_OWNERDATA changed? */ … … 8593 8738 SIZE oldIconSize = infoPtr->iconSize; 8594 8739 HIMAGELIST himl; 8595 8740 8596 8741 SendMessageW(infoPtr->hwndEdit, WM_KILLFOCUS, 0, 0); 8597 8742 ShowWindow(infoPtr->hwndHeader, SW_HIDE); … … 8602 8747 himl = (uNewView == LVS_ICON ? infoPtr->himlNormal : infoPtr->himlSmall); 8603 8748 set_icon_size(&infoPtr->iconSize, himl, uNewView != LVS_ICON); 8604 8749 8605 8750 if (uNewView == LVS_ICON) 8606 8751 { … … 8628 8773 if (uNewView == LVS_REPORT) 8629 8774 ShowWindow(infoPtr->hwndHeader, (lpss->styleNew & LVS_NOCOLUMNHEADER) ? SW_HIDE : SW_SHOWNORMAL); 8630 8775 8631 8776 if ( (uNewView == LVS_ICON || uNewView == LVS_SMALLICON) && 8632 8777 (uNewView != uOldView || ((lpss->styleNew ^ lpss->styleOld) & LVS_ALIGNMASK)) ) … … 8958 9103 /* case LVM_CANCELEDITLABEL: */ 8959 9104 8960 /* case LVM_CREATEDRAGIMAGE: */ 9105 case LVM_CREATEDRAGIMAGE: 9106 return (LRESULT)LISTVIEW_CreateDragImage(infoPtr, (INT)wParam, (LPPOINT)lParam); 8961 9107 8962 9108 case LVM_DELETEALLITEMS: … … 9393 9539 9394 9540 case WM_WINDOWPOSCHANGED: 9395 if (!(((WINDOWPOS *)lParam)->flags & SWP_NOSIZE)) 9541 if (!(((WINDOWPOS *)lParam)->flags & SWP_NOSIZE)) 9396 9542 { 9397 9543 SetWindowPos(infoPtr->hwndSelf, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE |
Note:
See TracChangeset
for help on using the changeset viewer.