Source code of Windows XP (NT5)
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.

253 lines
6.4 KiB

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