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.

560 lines
12 KiB

  1. #ifndef CTLLOGIC_H
  2. #define CTLLOGIC_H
  3. #include "dlglogic.h"
  4. #define MAX_ITEMTEXTLEN 50
  5. #define MAX_TILETEXT 50
  6. HRESULT _GetListViewSelectedLPARAM(HWND hwndList, LPARAM* plparam);
  7. HRESULT _GetComboBoxSelectedLRESULT(HWND hwndComboBox, LRESULT* plr);
  8. // ListView
  9. template<typename TData>
  10. class CDLUIDataLVItem : public CDLUIData<TData>
  11. {
  12. public:
  13. virtual ~CDLUIDataLVItem() {}
  14. virtual HRESULT GetText(LPWSTR pszText, DWORD cchText) PURE;
  15. virtual HRESULT GetIconLocation(LPWSTR pszIconLocation,
  16. DWORD cchIconLocation) PURE;
  17. virtual HRESULT GetTileText(int i, LPWSTR pszTileText,
  18. DWORD cchTileText)
  19. {
  20. return E_NOTIMPL;
  21. }
  22. };
  23. template<typename TData>
  24. class CUILListView
  25. {
  26. public:
  27. ~CUILListView();
  28. CUILListView();
  29. HRESULT Init(HWND hwndListView);
  30. HRESULT InitTileInfo(const UINT auTileSubItems[], DWORD cTileSubItems);
  31. HRESULT AddItem(CDLUIDataLVItem<TData>* plvitem);
  32. // Note: Caller needs to Release *ppdata at some point
  33. HRESULT GetSelectedItemData(TData** ppdata);
  34. // Assume Single select listview. Also assume that no other item is selected
  35. HRESULT SelectFirstItem();
  36. HRESULT ResetContent();
  37. protected:
  38. HWND _hwndList;
  39. private:
  40. const UINT* _auTileSubItems;
  41. int _cTileSubItems;
  42. };
  43. template<typename TData, typename TCompareData>
  44. class CUILListViewSelect : public CUILListView<TData>
  45. {
  46. public:
  47. HRESULT SelectItem(TCompareData comparedata)
  48. {
  49. HRESULT hr = E_FAIL;
  50. LVITEM lvitem = {0};
  51. int iCount = 0;
  52. lvitem.mask = LVIF_PARAM;
  53. iCount = ListView_GetItemCount(_hwndList);
  54. for (lvitem.iItem = 0; lvitem.iItem < iCount; ++lvitem.iItem)
  55. {
  56. if (ListView_GetItem(_hwndList, &lvitem))
  57. {
  58. CDLUIDataLVItem<TData>* plvitem = (CDLUIDataLVItem<TData>*)lvitem.lParam;
  59. TData* pdata = plvitem->GetData();
  60. if (pdata)
  61. {
  62. int iResult;
  63. hr = pdata->Compare(comparedata, &iResult);
  64. pdata->Release();
  65. if (SUCCEEDED(hr) && !iResult)
  66. {
  67. break;
  68. }
  69. }
  70. }
  71. }
  72. if (lvitem.iItem == iCount)
  73. {
  74. //No Match found, Select first item anyway
  75. lvitem.iItem = 0;
  76. hr = S_FALSE;
  77. }
  78. lvitem.mask = LVIF_STATE;
  79. lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  80. lvitem.state = LVIS_SELECTED | LVIS_FOCUSED;
  81. ListView_SetItem(_hwndList, &lvitem);
  82. ListView_EnsureVisible(_hwndList, lvitem.iItem, FALSE);
  83. return hr;
  84. }
  85. };
  86. // ComboBox
  87. template<typename TData>
  88. class CDLUIDataCBItem : public CDLUIData<TData>
  89. {
  90. public:
  91. virtual ~CDLUIDataCBItem() {}
  92. virtual HRESULT GetText(LPWSTR pszText, DWORD cchText) PURE;
  93. virtual HRESULT GetIconLocation(LPWSTR pszIconLocation,
  94. DWORD cchIconLocation) PURE;
  95. };
  96. template<typename TData>
  97. class CUILComboBox
  98. {
  99. public:
  100. ~CUILComboBox();
  101. HRESULT Init(HWND hwndComboBox);
  102. HRESULT AddItem(CDLUIDataCBItem<TData>* pcbitem);
  103. // Note: Caller needs to Release *ppdata at some point
  104. HRESULT GetSelectedItemData(TData** ppdata);
  105. HRESULT SelectFirstItem();
  106. HRESULT ResetContent();
  107. private:
  108. HWND _hwndCombo;
  109. };
  110. template<typename TData>
  111. class CUILComboBoxEx
  112. {
  113. public:
  114. ~CUILComboBoxEx();
  115. HRESULT Init(HWND hwndComboBox);
  116. HRESULT AddItem(CDLUIDataCBItem<TData>* pcbitem);
  117. // Note: Caller needs to Release *ppdata at some point
  118. HRESULT GetSelectedItemData(TData** ppdata);
  119. HRESULT SelectFirstItem();
  120. HRESULT ResetContent();
  121. private:
  122. HWND _hwndCombo;
  123. };
  124. // Implementations
  125. template<typename TData>
  126. CUILListView<TData>::CUILListView() : _cTileSubItems(0)
  127. {}
  128. template<typename TData>
  129. CUILListView<TData>::~CUILListView()
  130. {
  131. ResetContent();
  132. }
  133. template<typename TData>
  134. inline HRESULT CUILListView<TData>::Init(HWND hwndListView)
  135. {
  136. _hwndList = hwndListView;
  137. return S_OK;
  138. }
  139. template<typename TData>
  140. inline HRESULT CUILListView<TData>::InitTileInfo(const UINT auTileSubItems[],
  141. DWORD cTileSubItems)
  142. {
  143. _auTileSubItems = auTileSubItems;
  144. _cTileSubItems = cTileSubItems;
  145. return S_OK;
  146. }
  147. template<typename TData>
  148. inline HRESULT CUILListView<TData>::AddItem(CDLUIDataLVItem<TData>* plvitem)
  149. {
  150. WCHAR szText[MAX_ITEMTEXTLEN];
  151. int iImage;
  152. LVITEM lvitem = {0};
  153. HRESULT hr = plvitem->GetText(szText, ARRAYSIZE(szText));
  154. if (SUCCEEDED(hr))
  155. {
  156. WCHAR szIconLocation[MAX_PATH + 12];
  157. hr = plvitem->GetIconLocation(szIconLocation,
  158. ARRAYSIZE(szIconLocation));
  159. if (SUCCEEDED(hr))
  160. {
  161. int iIcon = PathParseIconLocation(szIconLocation);
  162. iImage = Shell_GetCachedImageIndex(szIconLocation, iIcon, 0);
  163. }
  164. }
  165. if (SUCCEEDED(hr))
  166. {
  167. int iItem;
  168. lvitem.mask = LVIF_IMAGE | LVIF_TEXT | LVIF_PARAM;
  169. lvitem.pszText = szText;
  170. lvitem.iItem = ListView_GetItemCount(_hwndList);
  171. lvitem.iImage = iImage;
  172. lvitem.lParam = (LPARAM)plvitem;
  173. iItem = ListView_InsertItem(_hwndList, &lvitem);
  174. if (-1 != iItem)
  175. {
  176. if (_cTileSubItems)
  177. {
  178. LVTILEINFO lvti = {0};
  179. lvti.cbSize = sizeof(LVTILEINFO);
  180. lvti.iItem = iItem;
  181. lvti.cColumns = ARRAYSIZE(_auTileSubItems);
  182. lvti.puColumns = (UINT*)_auTileSubItems;
  183. ListView_SetTileInfo(_hwndList, &lvti);
  184. for (int i = 0; i < _cTileSubItems; ++i)
  185. {
  186. WCHAR szTileText[MAX_TILETEXT];
  187. hr = plvitem->GetTileText(i, szTileText,
  188. ARRAYSIZE(szTileText));
  189. // 1 based
  190. ListView_SetItemText(_hwndList, iItem, i + 1, szTileText);
  191. }
  192. }
  193. }
  194. else
  195. {
  196. hr = E_FAIL;
  197. }
  198. }
  199. return hr;
  200. }
  201. template<typename TData>
  202. inline HRESULT CUILListView<TData>::GetSelectedItemData(TData** ppdata)
  203. {
  204. HRESULT hr;
  205. BOOL fFound = FALSE;
  206. int iCount = ListView_GetItemCount(_hwndList);
  207. LVITEM lvitem = {0};
  208. lvitem.mask = LVIF_PARAM | LVIF_STATE;
  209. lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  210. for (int j = 0; !fFound && (j < iCount); ++j)
  211. {
  212. lvitem.iItem = j;
  213. ListView_GetItem(_hwndList, &lvitem);
  214. if (lvitem.state & (LVIS_SELECTED | LVIS_FOCUSED))
  215. {
  216. fFound = TRUE;
  217. }
  218. }
  219. if (fFound)
  220. {
  221. CDLUIDataLVItem<TData>* plvitem = (CDLUIDataLVItem<TData>*)lvitem.lParam;
  222. *ppdata = plvitem->GetData();
  223. hr = ((*ppdata) ? S_OK : S_FALSE);
  224. }
  225. else
  226. {
  227. *ppdata = NULL;
  228. hr = E_FAIL;
  229. }
  230. return hr;
  231. }
  232. template<typename TData>
  233. inline HRESULT CUILListView<TData>::SelectFirstItem()
  234. {
  235. LVITEM lvitem = {0};
  236. lvitem.iItem = 0;
  237. lvitem.mask = LVIF_STATE;
  238. lvitem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  239. lvitem.state = LVIS_SELECTED | LVIS_FOCUSED;
  240. ListView_SetItem(_hwndList, &lvitem);
  241. ListView_EnsureVisible(_hwndList, lvitem.iItem, FALSE);
  242. return S_OK;
  243. }
  244. template<typename TData>
  245. HRESULT CUILListView<TData>::ResetContent()
  246. {
  247. int iCount = 0;
  248. LVITEM lvitem = {0};
  249. // go through all the items in the listview and delete the strings
  250. // dynamically allocated
  251. lvitem.mask = LVIF_PARAM;
  252. lvitem.iSubItem = 0;
  253. iCount = ListView_GetItemCount(_hwndList);
  254. for (lvitem.iItem = 0; lvitem.iItem < iCount; ++lvitem.iItem)
  255. {
  256. ListView_GetItem(_hwndList, &lvitem);
  257. CDLUIDataLVItem<TData>* plvitem = (CDLUIDataLVItem<TData>*)
  258. lvitem.lParam;
  259. if (plvitem)
  260. {
  261. delete plvitem;
  262. }
  263. }
  264. ListView_DeleteAllItems(_hwndList);
  265. return S_OK;
  266. }
  267. // CUILComboBox
  268. template<typename TData>
  269. CUILComboBox<TData>::~CUILComboBox()
  270. {
  271. ResetContent();
  272. }
  273. template<typename TData>
  274. HRESULT CUILComboBox<TData>::Init(HWND hwndComboBox)
  275. {
  276. _hwndCombo = hwndComboBox;
  277. return S_OK;
  278. }
  279. template<typename TData>
  280. HRESULT CUILComboBox<TData>::AddItem(CDLUIDataCBItem<TData>* pcbitem)
  281. {
  282. WCHAR szText[MAX_ITEMTEXTLEN];
  283. HRESULT hr = pcbitem->GetText(szText, ARRAYSIZE(szText));
  284. if (SUCCEEDED(hr))
  285. {
  286. int i = ComboBox_AddString(_hwndCombo, szText);
  287. if (CB_ERR != i)
  288. {
  289. ComboBox_SetItemData(_hwndCombo, i, pcbitem);
  290. }
  291. }
  292. return hr;
  293. }
  294. template<typename TData>
  295. HRESULT CUILComboBox<TData>::GetSelectedItemData(TData** ppdata)
  296. {
  297. HRESULT hr;
  298. int iCurSel = ComboBox_GetCurSel(_hwndCombo);
  299. LRESULT lr = ComboBox_GetItemData(_hwndCombo, iCurSel);
  300. if (CB_ERR != lr)
  301. {
  302. CDLUIDataCBItem<TData>* pcbitem = (CDLUIDataCBItem<TData>*)lr;
  303. *ppdata = pcbitem->GetData();
  304. hr = ((*ppdata) ? S_OK : S_FALSE);
  305. }
  306. else
  307. {
  308. *ppdata = NULL;
  309. hr = E_FAIL;
  310. }
  311. return hr;
  312. }
  313. template<typename TData>
  314. HRESULT CUILComboBox<TData>::ResetContent()
  315. {
  316. int c = ComboBox_GetCount(_hwndCombo);
  317. for (int i = 0; i < c; ++i)
  318. {
  319. CDLUIDataCBItem<TData>* pcbitem = (CDLUIDataCBItem<TData>*)
  320. ComboBox_GetItemData(_hwndCombo, i);
  321. if (pcbitem)
  322. {
  323. delete pcbitem;
  324. }
  325. }
  326. ComboBox_ResetContent(_hwndCombo);
  327. return S_OK;
  328. }
  329. template<typename TData>
  330. HRESULT CUILComboBox<TData>::SelectFirstItem()
  331. {
  332. ComboBox_SetCurSel(_hwndCombo, 0);
  333. return S_OK;
  334. }
  335. // CUILComboBoxEx
  336. template<typename TData>
  337. CUILComboBoxEx<TData>::~CUILComboBoxEx()
  338. {
  339. ResetContent();
  340. }
  341. template<typename TData>
  342. HRESULT CUILComboBoxEx<TData>::Init(HWND hwndComboBox)
  343. {
  344. _hwndCombo = hwndComboBox;
  345. return S_OK;
  346. }
  347. template<typename TData>
  348. HRESULT CUILComboBoxEx<TData>::AddItem(CDLUIDataCBItem<TData>* pcbitem)
  349. {
  350. WCHAR szText[MAX_ITEMTEXTLEN];
  351. int iImage;
  352. HRESULT hr = pcbitem->GetText(szText, ARRAYSIZE(szText));
  353. if (SUCCEEDED(hr))
  354. {
  355. WCHAR szIconLocation[MAX_PATH + 12];
  356. hr = pcbitem->GetIconLocation(szIconLocation,
  357. ARRAYSIZE(szIconLocation));
  358. if (SUCCEEDED(hr))
  359. {
  360. int iIcon = PathParseIconLocation(szIconLocation);
  361. iImage = Shell_GetCachedImageIndex(szIconLocation, iIcon, 0);
  362. }
  363. }
  364. if (SUCCEEDED(hr))
  365. {
  366. int iItem;
  367. COMBOBOXEXITEM cbitem = {0};
  368. cbitem.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
  369. cbitem.pszText = szText;
  370. cbitem.iItem = ComboBox_GetCount(_hwndCombo);
  371. cbitem.iImage = iImage;
  372. cbitem.iSelectedImage = iImage;
  373. cbitem.lParam = (LPARAM)pcbitem;
  374. iItem = SendMessage(_hwndCombo, CBEM_INSERTITEM, 0, (LPARAM)&cbitem);
  375. if (-1 != iItem)
  376. {
  377. hr = S_OK;
  378. }
  379. else
  380. {
  381. hr = E_FAIL;
  382. }
  383. }
  384. return hr;
  385. }
  386. template<typename TData>
  387. HRESULT CUILComboBoxEx<TData>::GetSelectedItemData(TData** ppdata)
  388. {
  389. HRESULT hr;
  390. COMBOBOXEXITEM cbitem = {0};
  391. cbitem.mask = CBEIF_LPARAM;
  392. cbitem.iItem = ComboBox_GetCurSel(_hwndCombo);
  393. if (SendMessage(_hwndCombo, CBEM_GETITEM, 0, (LPARAM)&cbitem))
  394. {
  395. CDLUIDataCBItem<TData>* pcbitem = (CDLUIDataCBItem<TData>*)cbitem.lParam;
  396. *ppdata = pcbitem->GetData();
  397. hr = ((*ppdata) ? S_OK : S_FALSE);
  398. }
  399. else
  400. {
  401. *ppdata = NULL;
  402. hr = E_FAIL;
  403. }
  404. return hr;
  405. }
  406. template<typename TData>
  407. HRESULT CUILComboBoxEx<TData>::ResetContent()
  408. {
  409. int c = ComboBox_GetCount(_hwndCombo);
  410. for (int i = 0; i < c; ++i)
  411. {
  412. CDLUIDataCBItem<TData>* pcbitem = (CDLUIDataCBItem<TData>*)
  413. ComboBox_GetItemData(_hwndCombo, i);
  414. if (pcbitem)
  415. {
  416. delete pcbitem;
  417. }
  418. }
  419. ComboBox_ResetContent(_hwndCombo);
  420. return S_OK;
  421. }
  422. template<typename TData>
  423. HRESULT CUILComboBoxEx<TData>::SelectFirstItem()
  424. {
  425. ComboBox_SetCurSel(_hwndCombo, 0);
  426. return S_OK;
  427. }
  428. #endif // CTLLOGIC_H