Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

247 lines
6.5 KiB

  1. // small icon view (positional view, not list)
  2. #include "ctlspriv.h"
  3. #include "listview.h"
  4. int ListView_SItemHitTest(LV* plv, int x, int y, UINT* pflags, int *piSubItem)
  5. {
  6. int iHit;
  7. UINT flags;
  8. POINT pt;
  9. RECT rcState;
  10. RECT rcLabel;
  11. RECT rcIcon;
  12. if (piSubItem)
  13. *piSubItem = 0;
  14. // Map window-relative coordinates to view-relative coords...
  15. //
  16. pt.x = x + plv->ptOrigin.x;
  17. pt.y = y + plv->ptOrigin.y;
  18. // If we find an uncomputed item, recompute them all now...
  19. //
  20. if (plv->rcView.left == RECOMPUTE)
  21. ListView_Recompute(plv);
  22. flags = 0;
  23. if (ListView_IsOwnerData( plv ))
  24. {
  25. int cSlots;
  26. POINT ptWnd;
  27. LISTITEM item;
  28. int iWidth = 0, iHeight = 0;
  29. cSlots = ListView_GetSlotCount( plv, TRUE, &iWidth, &iHeight );
  30. iHit = ListView_CalcHitSlot( plv, pt, cSlots, iWidth, iHeight );
  31. ListView_SGetRectsOwnerData( plv, iHit, &rcIcon, &rcLabel, &item, FALSE );
  32. ptWnd.x = x;
  33. ptWnd.y = y;
  34. if (PtInRect(&rcIcon, ptWnd))
  35. {
  36. flags = LVHT_ONITEMICON;
  37. }
  38. else if (PtInRect(&rcLabel, ptWnd))
  39. {
  40. flags = LVHT_ONITEMLABEL;
  41. }
  42. }
  43. else
  44. {
  45. for (iHit = 0; iHit < ListView_Count(plv); iHit++)
  46. {
  47. LISTITEM* pitem = ListView_FastGetZItemPtr(plv, iHit);
  48. POINT ptItem;
  49. ptItem.x = pitem->pt.x;
  50. ptItem.y = pitem->pt.y;
  51. rcIcon.top = ptItem.y;
  52. rcIcon.bottom = ptItem.y + plv->cyItem;
  53. rcLabel.top = rcIcon.top;
  54. rcLabel.bottom = rcIcon.bottom;
  55. // Quick, easy rejection test...
  56. //
  57. if (pt.y < rcIcon.top || pt.y >= rcIcon.bottom)
  58. continue;
  59. rcIcon.left = ptItem.x;
  60. rcIcon.right = ptItem.x + plv->cxSmIcon;
  61. rcState.bottom = rcIcon.bottom;
  62. rcState.right = rcIcon.left;
  63. rcState.left = rcState.right - (plv->cxState + LV_ICONTOSTATEOFFSET(plv));
  64. rcState.top = rcState.bottom - plv->cyState;
  65. rcLabel.left = rcIcon.right;
  66. rcLabel.right = rcLabel.left + pitem->cxSingleLabel;
  67. if (PtInRect(&rcIcon, pt))
  68. {
  69. flags = LVHT_ONITEMICON;
  70. } else if (PtInRect(&rcLabel, pt))
  71. {
  72. flags = LVHT_ONITEMLABEL;
  73. } else if (PtInRect(&rcState, pt))
  74. {
  75. flags = LVHT_ONITEMSTATEICON;
  76. }
  77. if (flags)
  78. break;
  79. }
  80. }
  81. if (flags == 0)
  82. {
  83. flags = LVHT_NOWHERE;
  84. iHit = -1;
  85. }
  86. else
  87. {
  88. if (!ListView_IsOwnerData( plv ))
  89. iHit = DPA_GetPtrIndex(plv->hdpa, (void*)ListView_FastGetZItemPtr(plv, iHit));
  90. }
  91. *pflags = flags;
  92. return iHit;
  93. }
  94. void ListView_SGetRectsOwnerData( LV* plv,
  95. int iItem,
  96. RECT* prcIcon,
  97. RECT* prcLabel,
  98. LISTITEM* pitem,
  99. BOOL fUsepitem )
  100. {
  101. RECT rcIcon;
  102. RECT rcLabel;
  103. int cSlots;
  104. // calculate itemx, itemy, itemsSingleLabel from iItem
  105. cSlots = ListView_GetSlotCount( plv, TRUE, NULL, NULL );
  106. pitem->iWorkArea = 0; // OwnerData doesn't support workareas
  107. ListView_SetIconPos( plv, pitem, iItem, cSlots );
  108. // calculate lable sizes
  109. // Note the rect we return should be the min of the size returned and the slot size...
  110. ListView_IRecomputeLabelSize( plv, pitem, iItem, NULL, fUsepitem );
  111. rcIcon.left = pitem->pt.x - plv->ptOrigin.x;
  112. rcIcon.right = rcIcon.left + plv->cxSmIcon;
  113. rcIcon.top = pitem->pt.y - plv->ptOrigin.y;
  114. rcIcon.bottom = rcIcon.top + plv->cyItem;
  115. *prcIcon = rcIcon;
  116. rcLabel.left = rcIcon.right;
  117. if (pitem->cxSingleLabel < (plv->cxItem - plv->cxSmIcon))
  118. rcLabel.right = rcLabel.left + pitem->cxSingleLabel;
  119. else
  120. rcLabel.right = rcLabel.left + plv->cxItem - plv->cxSmIcon;
  121. rcLabel.top = rcIcon.top;
  122. rcLabel.bottom = rcIcon.bottom;
  123. *prcLabel = rcLabel;
  124. }
  125. void ListView_SGetRects(LV* plv, LISTITEM* pitem, RECT* prcIcon, RECT* prcLabel, LPRECT prcBounds)
  126. {
  127. ASSERT( !ListView_IsOwnerData( plv ));
  128. if (pitem->pt.x == RECOMPUTE)
  129. {
  130. ListView_Recompute(plv);
  131. }
  132. prcIcon->left = pitem->pt.x - plv->ptOrigin.x;
  133. prcIcon->right = prcIcon->left + plv->cxSmIcon;
  134. prcIcon->top = pitem->pt.y - plv->ptOrigin.y;
  135. prcIcon->bottom = prcIcon->top + plv->cyItem;
  136. prcLabel->left = prcIcon->right;
  137. prcLabel->right = prcLabel->left + pitem->cxSingleLabel;
  138. prcLabel->top = prcIcon->top;
  139. prcLabel->bottom = prcIcon->bottom;
  140. }
  141. // Return the index of the first item >= *pszLookup.
  142. //
  143. int ListView_DoLookupString(LV* plv, LPCTSTR pszLookup, UINT flags, int iStart, int j)
  144. {
  145. int i;
  146. BOOL fExact;
  147. int k;
  148. LISTITEM* pitem;
  149. LISTITEM* pitemLast = NULL;
  150. ASSERT( !ListView_IsOwnerData( plv ));
  151. fExact = FALSE;
  152. i = iStart;
  153. while ((i >= iStart) && (i < j))
  154. {
  155. int result;
  156. k = (i + j) / 2;
  157. pitem = ListView_FastGetItemPtr(plv, k);
  158. if (pitem == pitemLast)
  159. break;
  160. pitemLast = pitem;
  161. result = ListView_CompareString(plv,
  162. k, pszLookup, flags, 0);
  163. if (plv->ci.style & LVS_SORTDESCENDING)
  164. result = -result;
  165. switch (result)
  166. {
  167. case 0:
  168. fExact = TRUE;
  169. // fall through
  170. case 1:
  171. j = k;
  172. break;
  173. case -1:
  174. i = k + 1;
  175. break;
  176. }
  177. }
  178. // For substrings, return index only if exact match was found.
  179. //
  180. if (!(flags & (LVFI_SUBSTRING | LVFI_PARTIAL)) &&
  181. !fExact)
  182. return -1;
  183. if (i < 0)
  184. i = 0;
  185. if ((!(flags & LVFI_NEARESTXY)) &&
  186. ListView_CompareString(plv, i, pszLookup, flags, 1)) {
  187. i = -1;
  188. }
  189. return i;
  190. }
  191. int ListView_LookupString(LV* plv, LPCTSTR pszLookup, UINT flags, int iStart)
  192. {
  193. int iret;
  194. if (!pszLookup)
  195. return 0;
  196. iret = ListView_DoLookupString(plv, pszLookup, flags, iStart, ListView_Count(plv));
  197. if (iret == -1 && (flags & LVFI_WRAP)) {
  198. iret = ListView_DoLookupString(plv, pszLookup, flags, 0, iStart);
  199. }
  200. return iret;
  201. }