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.

576 lines
15 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: ColumnPickerDlg.cxx
  7. //
  8. // Contents: Implementation of class that displays the column picker
  9. // dialog
  10. //
  11. // Classes: CColumnPickerDlg
  12. //
  13. // History: 06-10-2000 DavidMun Created
  14. //
  15. //---------------------------------------------------------------------------
  16. #include "headers.hxx"
  17. #pragma hdrstop
  18. static ULONG
  19. s_aulHelpIds[] =
  20. {
  21. IDC_AVAILABLE_LIST, IDH_AVAILABLE_LIST,
  22. IDC_ADD_COL_BTN, IDH_ADD_COL_BTN,
  23. IDC_REMOVE_COL_BTN, IDH_REMOVE_COL_BTN,
  24. IDC_SHOWN_LIST, IDH_SHOWN_LIST,
  25. 0,0
  26. };
  27. //+--------------------------------------------------------------------------
  28. //
  29. // Member: CColumnPickerDlg::DoModal
  30. //
  31. // Synopsis: Invoke the Column Picker as a modal dialog
  32. //
  33. // Arguments: [hwndParent] - handle to parent window
  34. //
  35. // History: 06-14-2000 DavidMun Created
  36. //
  37. //---------------------------------------------------------------------------
  38. BOOL
  39. CColumnPickerDlg::DoModal(
  40. HWND hwndParent)
  41. {
  42. TRACE_METHOD(CColumnPickerDlg, DoModal);
  43. return (BOOL) _DoModalDlg(hwndParent, IDD_COLUMN_PICKER);
  44. }
  45. //+--------------------------------------------------------------------------
  46. //
  47. // Member: CColumnPickerDlg::_OnInit
  48. //
  49. // Synopsis: Initialize the contents of the 'available' and 'shown'
  50. // listviews.
  51. //
  52. // Arguments: [pfSetFocus] - unused
  53. //
  54. // Returns: S_OK
  55. //
  56. // History: 06-14-2000 DavidMun Created
  57. //
  58. //---------------------------------------------------------------------------
  59. HRESULT
  60. CColumnPickerDlg::_OnInit(
  61. BOOL *pfSetFocus)
  62. {
  63. TRACE_METHOD(CColumnPickerDlg, _OnInit);
  64. //
  65. // Add a full-width column to each of the listviews
  66. //
  67. HWND hwndLV = _hCtrl(IDC_AVAILABLE_LIST);
  68. if (!hwndLV)
  69. {
  70. DBG_OUT_LASTERROR;
  71. return HRESULT_FROM_LASTERROR;
  72. }
  73. RECT rcLV;
  74. VERIFY(GetClientRect(hwndLV, &rcLV));
  75. rcLV.right -= GetSystemMetrics(SM_CXVSCROLL);
  76. LVCOLUMN col;
  77. //REVIEWED-2002-02-20-lucios.
  78. ZeroMemory(&col, sizeof col);
  79. col.mask = LVCF_WIDTH;
  80. col.cx = rcLV.right;
  81. int iCol = ListView_InsertColumn(hwndLV, 0, &col);
  82. if (iCol == -1)
  83. {
  84. DBG_OUT_LASTERROR;
  85. }
  86. ListView_SetExtendedListViewStyleEx(hwndLV,
  87. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT,
  88. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
  89. hwndLV = _hCtrl(IDC_SHOWN_LIST);
  90. if (!hwndLV)
  91. {
  92. DBG_OUT_LASTERROR;
  93. return HRESULT_FROM_LASTERROR;
  94. }
  95. VERIFY(GetClientRect(hwndLV, &rcLV));
  96. rcLV.right -= GetSystemMetrics(SM_CXVSCROLL);
  97. iCol = ListView_InsertColumn(hwndLV, 0, &col);
  98. if (iCol == -1)
  99. {
  100. DBG_OUT_LASTERROR;
  101. }
  102. ListView_SetExtendedListViewStyleEx(hwndLV,
  103. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT,
  104. LVS_EX_LABELTIP | LVS_EX_FULLROWSELECT);
  105. const CAttributeManager &ram = m_rop.GetAttributeManager();
  106. m_vakAvailable = ram.GetAttrKeysForSelectedClasses(m_hwnd);
  107. if (m_vakAvailable.empty())
  108. {
  109. SafeEnableWindow(_hCtrl(IDC_ADD_COL_BTN), FALSE);
  110. }
  111. else
  112. {
  113. AttrKeyVector::iterator it;
  114. for (it = m_vakShown.begin(); it != m_vakShown.end(); it++)
  115. {
  116. AttrKeyVector::iterator itAvail;
  117. do
  118. {
  119. itAvail = find(m_vakAvailable.begin(), m_vakAvailable.end(), *it);
  120. if (itAvail != m_vakAvailable.end())
  121. {
  122. m_vakAvailable.erase(itAvail);
  123. }
  124. } while (itAvail != m_vakAvailable.end());
  125. }
  126. }
  127. _EnsureAttributePresent(AK_NAME);
  128. _EnsureAttributePresent(AK_DISPLAY_PATH);
  129. _AddAttributesToListview(_hCtrl(IDC_AVAILABLE_LIST), m_vakAvailable);
  130. _AddAttributesToListview(_hCtrl(IDC_SHOWN_LIST), *m_pvakColumns);
  131. SetListViewSelection(_hCtrl(IDC_AVAILABLE_LIST), 0);
  132. SetListViewSelection(_hCtrl(IDC_SHOWN_LIST), 0);
  133. return S_OK;
  134. }
  135. //+--------------------------------------------------------------------------
  136. //
  137. // Member: CColumnPickerDlg::_AddAttributesToListview
  138. //
  139. // Synopsis: Add the display names for all attributes in [vak] to the
  140. // listview with window handle [hwndLV].
  141. //
  142. // Arguments: [hwndLV] - handle to listview window
  143. // [vak] - (possibly empty) vector of attribute keys
  144. //
  145. // History: 06-14-2000 DavidMun Created
  146. //
  147. // Notes: Adds ATTR_KEY values as lParam of listview items.
  148. //
  149. //---------------------------------------------------------------------------
  150. void
  151. CColumnPickerDlg::_AddAttributesToListview(
  152. HWND hwndLV,
  153. const AttrKeyVector &vak)
  154. {
  155. LVITEM lvi;
  156. //REVIEWED-2002-02-20-lucios.
  157. ZeroMemory(&lvi, sizeof lvi);
  158. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  159. const CAttributeManager &ram = m_rop.GetAttributeManager();
  160. AttrKeyVector::const_iterator it;
  161. for (it = vak.begin(); it != vak.end(); it++)
  162. {
  163. lvi.pszText = const_cast<PWSTR>(ram.GetAttrDisplayName(*it).c_str());
  164. lvi.lParam = *it;
  165. lvi.iItem = INT_MAX;
  166. LONG lResult = ListView_InsertItem(hwndLV, &lvi);
  167. if (lResult == -1)
  168. {
  169. Dbg(DEB_ERROR,
  170. "Error %u inserting '%ws' in listview\n",
  171. GetLastError(),
  172. lvi.pszText);
  173. continue;
  174. }
  175. }
  176. }
  177. //+--------------------------------------------------------------------------
  178. //
  179. // Member: CColumnPickerDlg::_EnsureAttributePresent
  180. //
  181. // Synopsis: If [ak] is present in neither the available nor the shown
  182. // lists, add it to the available list.
  183. //
  184. // Arguments: [ak] - attribute key to check for
  185. //
  186. // History: 06-16-2000 DavidMun Created
  187. //
  188. //---------------------------------------------------------------------------
  189. void
  190. CColumnPickerDlg::_EnsureAttributePresent(
  191. ATTR_KEY ak)
  192. {
  193. AttrKeyVector::iterator itAvail;
  194. AttrKeyVector::iterator itShown;
  195. itAvail = find(m_vakAvailable.begin(), m_vakAvailable.end(), ak);
  196. itShown = find(m_vakShown.begin(), m_vakShown.end(), ak);
  197. if (itAvail == m_vakAvailable.end() && itShown == m_vakShown.end())
  198. {
  199. m_vakAvailable.push_back(ak);
  200. }
  201. }
  202. //+--------------------------------------------------------------------------
  203. //
  204. // Member: CColumnPickerDlg::_OnCommand
  205. //
  206. // Synopsis: Handle WM_COMMAND messages
  207. //
  208. // Arguments: [wParam] - standard windows
  209. // [lParam] - standard windows
  210. //
  211. // Returns: standard windows
  212. //
  213. // History: 06-22-2000 DavidMun Created
  214. //
  215. //---------------------------------------------------------------------------
  216. BOOL
  217. CColumnPickerDlg::_OnCommand(
  218. WPARAM wParam,
  219. LPARAM lParam)
  220. {
  221. BOOL fHandled = TRUE;
  222. switch (LOWORD(wParam))
  223. {
  224. case IDC_ADD_COL_BTN:
  225. {
  226. Dbg(DEB_TRACE, "UA: (CColumnPickerDlg) hit Add button\n");
  227. //
  228. // Move the selected item in the 'available' listview to the
  229. // 'shown' listview.
  230. //
  231. _MoveAttribute(IDC_AVAILABLE_LIST, IDC_SHOWN_LIST);
  232. //
  233. // Since the 'shown' listview must now contain at least one item,
  234. // ensure that the remove and OK buttons are enabled.
  235. //
  236. SafeEnableWindow(_hCtrl(IDC_REMOVE_COL_BTN), TRUE);
  237. SafeEnableWindow(_hCtrl(IDOK), TRUE);
  238. //
  239. // If the 'available' listview is now empty, disable the Add button.
  240. //
  241. if (!ListView_GetItemCount(_hCtrl(IDC_AVAILABLE_LIST)))
  242. {
  243. VERIFY(SetFocus(_hCtrl(IDC_REMOVE_COL_BTN)));
  244. SafeEnableWindow(_hCtrl(IDC_ADD_COL_BTN), FALSE);
  245. }
  246. break;
  247. }
  248. case IDC_REMOVE_COL_BTN:
  249. {
  250. Dbg(DEB_TRACE, "UA: (CColumnPickerDlg) hit Remove button\n");
  251. _MoveAttribute(IDC_SHOWN_LIST, IDC_AVAILABLE_LIST);
  252. SafeEnableWindow(_hCtrl(IDC_ADD_COL_BTN), TRUE);
  253. if (!ListView_GetItemCount(_hCtrl(IDC_SHOWN_LIST)))
  254. {
  255. SetFocus(_hCtrl(IDC_ADD_COL_BTN));
  256. SafeEnableWindow(_hCtrl(IDC_REMOVE_COL_BTN), FALSE);
  257. SafeEnableWindow(_hCtrl(IDOK), FALSE);
  258. }
  259. break;
  260. }
  261. case IDOK:
  262. ASSERT(!m_vakShown.empty());
  263. *m_pvakColumns = m_vakShown;
  264. EndDialog(m_hwnd, TRUE);
  265. break;
  266. case IDCANCEL:
  267. EndDialog(m_hwnd, FALSE);
  268. break;
  269. default:
  270. fHandled = FALSE;
  271. Dbg(DEB_WARN,
  272. "CColumnPickerDlg WM_COMMAND code=%#x, id=%#x, hwnd=%#x\n",
  273. HIWORD(wParam),
  274. LOWORD(wParam),
  275. lParam);
  276. break;
  277. }
  278. return fHandled;
  279. }
  280. //+--------------------------------------------------------------------------
  281. //
  282. // Member: CColumnPickerDlg::_MoveAttribute
  283. //
  284. // Synopsis: Move an entry from one listview (and its associated vector
  285. // of attribute keys) to the other.
  286. //
  287. // Arguments: [idFrom] - resource id of listview to take attribute from
  288. // [idTo] - resource id of listview to move attribute to
  289. //
  290. // History: 06-22-2000 DavidMun Created
  291. //
  292. //---------------------------------------------------------------------------
  293. void
  294. CColumnPickerDlg::_MoveAttribute(
  295. int idFrom,
  296. int idTo)
  297. {
  298. TRACE_METHOD(CColumnPickerDlg, _MoveAttribute);
  299. HWND hwndLvFrom = _hCtrl(idFrom);
  300. HWND hwndLvTo = _hCtrl(idTo);
  301. do
  302. {
  303. //
  304. // Find out which item is selected in the 'from' listview
  305. //
  306. int iItem = ListView_GetNextItem(hwndLvFrom, -1, LVNI_SELECTED);
  307. const CAttributeManager &ram = m_rop.GetAttributeManager();
  308. ASSERT(iItem != -1);
  309. if (iItem == -1)
  310. {
  311. break;
  312. }
  313. //
  314. // Get the ATTR_KEY of that item
  315. //
  316. LVITEM lvi;
  317. //REVIEWED-2002-02-20-lucios.
  318. ZeroMemory(&lvi, sizeof lvi);
  319. lvi.mask = LVIF_PARAM;
  320. lvi.iItem = iItem;
  321. if (!ListView_GetItem(hwndLvFrom, &lvi))
  322. {
  323. DBG_OUT_LASTERROR;
  324. break;
  325. }
  326. ATTR_KEY ak = static_cast<ATTR_KEY>(lvi.lParam);
  327. //
  328. // Remove that item from the 'from' listview
  329. //
  330. ListView_DeleteItem(hwndLvFrom, iItem);
  331. // Set the selection on the next item in the 'from' listview. The
  332. // next item is now at the same index as the one we just deleted.
  333. // NTRAID#NTBUG9-361131-2001/04/11-sburns
  334. int lastIndex = ListView_GetItemCount(hwndLvFrom) - 1;
  335. ListView_SetItemState(
  336. hwndLvFrom,
  337. min(iItem, lastIndex),
  338. LVIS_SELECTED,
  339. LVIS_SELECTED);
  340. //
  341. // Also remove it from the corresponding vector
  342. //
  343. if (idFrom == IDC_AVAILABLE_LIST)
  344. {
  345. m_vakAvailable.erase(find(m_vakAvailable.begin(), m_vakAvailable.end(), ak));
  346. }
  347. else
  348. {
  349. m_vakShown.erase(find(m_vakShown.begin(), m_vakShown.end(), ak));
  350. }
  351. //
  352. // Now add the item to the 'to' listview
  353. //
  354. lvi.mask = LVIF_TEXT | LVIF_PARAM;
  355. lvi.iItem = ListView_GetNextItem(hwndLvTo, -1, LVNI_SELECTED);
  356. if (lvi.iItem == -1)
  357. {
  358. lvi.iItem = INT_MAX;
  359. }
  360. lvi.pszText = const_cast<PWSTR>(ram.GetAttrDisplayName(ak).c_str());
  361. iItem = ListView_InsertItem(hwndLvTo, &lvi);
  362. if (iItem == -1)
  363. {
  364. DBG_OUT_LASTERROR;
  365. }
  366. ListView_SetItemState(hwndLvTo,
  367. iItem,
  368. LVIS_SELECTED | LVIS_FOCUSED,
  369. LVIS_SELECTED | LVIS_FOCUSED);
  370. ListView_EnsureVisible(hwndLvTo, iItem, FALSE);
  371. //
  372. // And add it to the corresponding vector
  373. //
  374. if (idTo == IDC_AVAILABLE_LIST)
  375. {
  376. m_vakAvailable.push_back(ak);
  377. }
  378. else
  379. {
  380. if (iItem == -1)
  381. {
  382. m_vakShown.push_back(ak);
  383. }
  384. else
  385. {
  386. m_vakShown.insert(m_vakShown.begin() + iItem, ak);
  387. }
  388. }
  389. } while (0);
  390. }
  391. //+--------------------------------------------------------------------------
  392. //
  393. // Member: CColumnPickerDlg::_OnNotify
  394. //
  395. // Synopsis: Handle WM_NOTIFY messages
  396. //
  397. // Arguments: [wParam] - standard windows
  398. // [lParam] - standard windows
  399. //
  400. // Returns: standard windows
  401. //
  402. // History: 06-22-2000 DavidMun Created
  403. //
  404. //---------------------------------------------------------------------------
  405. BOOL
  406. CColumnPickerDlg::_OnNotify(
  407. WPARAM wParam,
  408. LPARAM lParam)
  409. {
  410. LPNMHDR pnmh = reinterpret_cast<LPNMHDR> (lParam);
  411. do
  412. {
  413. // don't care about notifications from stuff other than listviews
  414. if (pnmh->idFrom != IDC_AVAILABLE_LIST &&
  415. pnmh->idFrom != IDC_SHOWN_LIST)
  416. {
  417. break;
  418. }
  419. switch (pnmh->code)
  420. {
  421. // NTRAID#NTBUG9-503615-2002/01/15-lucios
  422. case NM_DBLCLK:
  423. int iItem;
  424. iItem = ListView_GetNextItem(pnmh->hwndFrom,
  425. -1,
  426. LVNI_SELECTED);
  427. if (iItem != -1)
  428. {
  429. if(pnmh->idFrom==IDC_AVAILABLE_LIST)
  430. {
  431. SendMessage(m_hwnd,WM_COMMAND,IDC_ADD_COL_BTN,0);
  432. }
  433. else
  434. {
  435. SendMessage(m_hwnd,WM_COMMAND,IDC_REMOVE_COL_BTN,0);
  436. }
  437. }
  438. break;
  439. case LVN_ITEMCHANGED:
  440. HWND hwndBtn;
  441. HWND hwndFocusOnDisableBtn;
  442. if (pnmh->idFrom == IDC_AVAILABLE_LIST)
  443. {
  444. hwndBtn = _hCtrl(IDC_ADD_COL_BTN);
  445. hwndFocusOnDisableBtn = _hCtrl(IDC_SHOWN_LIST);
  446. }
  447. else
  448. {
  449. hwndBtn = _hCtrl(IDC_REMOVE_COL_BTN);
  450. hwndFocusOnDisableBtn = _hCtrl(IDC_AVAILABLE_LIST);
  451. }
  452. if (!hwndBtn)
  453. {
  454. DBG_OUT_HRESULT(E_OUTOFMEMORY);
  455. break;
  456. }
  457. break;
  458. }
  459. } while (0);
  460. return FALSE;
  461. }
  462. void
  463. CColumnPickerDlg::_OnHelp(
  464. UINT message,
  465. WPARAM wParam,
  466. LPARAM lParam)
  467. {
  468. TRACE_METHOD(CColumnPickerDlg, _OnHelp);
  469. InvokeWinHelp(message, wParam, lParam, c_wzHelpFilename, s_aulHelpIds);
  470. }