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.

1057 lines
25 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1998 - 2001
  4. Module Name:
  5. IASMultivaluedEditorPage.cpp
  6. Abstract:
  7. Implementation file for the CMultivaluedEditorPage class.
  8. Revision History:
  9. mmaguire 06/25/98 - created
  10. --*/
  11. //////////////////////////////////////////////////////////////////////////////
  12. //////////////////////////////////////////////////////////////////////////////
  13. // BEGIN INCLUDES
  14. //
  15. // standard includes:
  16. //
  17. #include "Precompiled.h"
  18. //
  19. // where we can find declaration for main class in this file:
  20. //
  21. #include "IASMultivaluedEditorPage.h"
  22. //
  23. // where we can find declarations needed in this file:
  24. //
  25. #include "iasdebug.h"
  26. //
  27. // END INCLUDES
  28. //////////////////////////////////////////////////////////////////////////////
  29. const int NOTHING_SELECTED = -1;
  30. #define ATTRIBUTE_VENDOR_COLUMN_WIDTH 120
  31. #define ATTRIBUTE_VALUE_COLUMN_WIDTH 300
  32. //////////////////////////////////////////////////////////////////////////////
  33. /*++
  34. ::GetSelectedItemIndex
  35. Utility function which returns index value of first selected item in list control.
  36. Returns NOTHING_SELECTED if no item is selected.
  37. --*/
  38. //////////////////////////////////////////////////////////////////////////////
  39. inline int GetSelectedItemIndex( CListCtrl & ListCtrl )
  40. {
  41. int iIndex = 0;
  42. int iFlags = LVNI_ALL | LVNI_SELECTED;
  43. // Note: GetNextItem excludes the current item passed in. So to
  44. // find the first item which matches, you must pass in -1.
  45. iIndex = ListCtrl.GetNextItem( -1, iFlags );
  46. // Note: GetNextItem returns -1 (which is NOTHING_SELECTED for us) if it can't find anything.
  47. return iIndex;
  48. }
  49. /////////////////////////////////////////////////////////////////////////////
  50. // CMultivaluedEditorPage property page
  51. IMPLEMENT_DYNCREATE(CMultivaluedEditorPage, CHelpDialog)
  52. BEGIN_MESSAGE_MAP(CMultivaluedEditorPage, CHelpDialog)
  53. //{{AFX_MSG_MAP(CMultivaluedEditorPage)
  54. ON_NOTIFY(NM_DBLCLK, IDC_IAS_LIST_MULTI_ATTRS, OnDblclkListIasMultiAttrs)
  55. ON_NOTIFY(LVN_ITEMCHANGED, IDC_IAS_LIST_MULTI_ATTRS, OnItemChangedListIasMultiAttrs)
  56. ON_BN_CLICKED(IDC_IAS_BUTTON_ADD_VALUE, OnButtonAddValue)
  57. ON_BN_CLICKED(IDC_IAS_BUTTON_MOVE_UP, OnButtonMoveUp)
  58. ON_BN_CLICKED(IDC_IAS_BUTTON_MOVE_DOWN, OnButtonMoveDown)
  59. ON_BN_CLICKED(IDC_IAS_BUTTON_REMOVE, OnButtonRemove)
  60. ON_BN_CLICKED(IDC_IAS_BUTTON_EDIT, OnButtonEdit)
  61. // ON_WM_CONTEXTMENU()
  62. // ON_WM_HELPINFO()
  63. //}}AFX_MSG_MAP
  64. END_MESSAGE_MAP()
  65. //////////////////////////////////////////////////////////////////////////////
  66. /*++
  67. CMultivaluedEditorPage::CMultivaluedEditorPage
  68. Constructor
  69. --*/
  70. //////////////////////////////////////////////////////////////////////////////
  71. CMultivaluedEditorPage::CMultivaluedEditorPage() : CHelpDialog(CMultivaluedEditorPage::IDD)
  72. {
  73. TRACE_FUNCTION("CMultivaluedEditorPage::CMultivaluedEditorPage");
  74. //{{AFX_DATA_INIT(CMultivaluedEditorPage)
  75. m_strAttrFormat = _T("");
  76. m_strAttrName = _T("");
  77. m_strAttrType = _T("");
  78. //}}AFX_DATA_INIT
  79. m_fIsDirty = FALSE;
  80. }
  81. //////////////////////////////////////////////////////////////////////////////
  82. /*++
  83. CMultivaluedEditorPage::~CMultivaluedEditorPage
  84. Destructor
  85. --*/
  86. //////////////////////////////////////////////////////////////////////////////
  87. CMultivaluedEditorPage::~CMultivaluedEditorPage()
  88. {
  89. TRACE_FUNCTION("CMultivaluedEditorPage::~CMultivaluedEditorPage");
  90. }
  91. //////////////////////////////////////////////////////////////////////////////
  92. /*++
  93. CMultivaluedEditorPage::SetData
  94. --*/
  95. //////////////////////////////////////////////////////////////////////////////
  96. HRESULT CMultivaluedEditorPage::SetData( IIASAttributeInfo *pIASAttributeInfo, VARIANT * pvarVariant )
  97. {
  98. TRACE_FUNCTION("CMultivaluedEditorPage::SetData");
  99. // ISSUE: Should assert that pvarVariant contains a safe array.
  100. HRESULT hr = S_OK;
  101. // Store off some pointers.
  102. m_spIASAttributeInfo = pIASAttributeInfo;
  103. m_pvarData = pvarVariant;
  104. // Open the variant up into a safe array of its constiuent parts.
  105. // To have this page close the array back up again and save it
  106. // using the pvarVariant pointer supplied above, call CommitArrayToVariant.
  107. try
  108. {
  109. // Check to see whether the variant passed was empty.
  110. if( V_VT( m_pvarData ) == VT_EMPTY )
  111. {
  112. // Create a new 1-dimensional safearray with no elements.
  113. DWORD dwInitialElements = 0;
  114. m_osaValueList.Create( VT_VARIANT, 1, &dwInitialElements );
  115. }
  116. else
  117. {
  118. _ASSERTE( V_VT( m_pvarData ) == (VT_VARIANT | VT_ARRAY) );
  119. // This creates a new copy of the SAFEARRAY pointed to by m_pvarData
  120. // wrapped by the standard COleSafeArray instance m_osaValueList.
  121. m_osaValueList = m_pvarData;
  122. }
  123. }
  124. catch(...)
  125. {
  126. return E_FAIL;
  127. }
  128. return hr;
  129. }
  130. //////////////////////////////////////////////////////////////////////////////
  131. /*++
  132. CMultivaluedEditorPage::DoDataExchange
  133. --*/
  134. //////////////////////////////////////////////////////////////////////////////
  135. void CMultivaluedEditorPage::DoDataExchange(CDataExchange* pDX)
  136. {
  137. TRACE_FUNCTION("CMultivaluedEditorPage::DoDataExchange");
  138. CHelpDialog::DoDataExchange(pDX);
  139. //{{AFX_DATA_MAP(CMultivaluedEditorPage)
  140. DDX_Control(pDX, IDC_IAS_LIST_MULTI_ATTRS, m_listMultiValues);
  141. DDX_Text(pDX, IDC_IAS_EDIT_MULTI_ATTR_FORMAT, m_strAttrFormat);
  142. DDX_Text(pDX, IDC_IAS_EDIT_MULTI_ATTR_NAME, m_strAttrName);
  143. DDX_Text(pDX, IDC_IAS_EDIT_MULTI_ATTR_NUMBER, m_strAttrType);
  144. //}}AFX_DATA_MAP
  145. }
  146. /////////////////////////////////////////////////////////////////////////////
  147. // CMultivaluedEditorPage message handlers
  148. //////////////////////////////////////////////////////////////////////////////
  149. /*++
  150. CMultivaluedEditorPage::OnInitDialog
  151. --*/
  152. //////////////////////////////////////////////////////////////////////////////
  153. BOOL CMultivaluedEditorPage::OnInitDialog()
  154. {
  155. TRACE_FUNCTION("CMultivaluedEditorPage::OnInitDialog");
  156. CHelpDialog::OnInitDialog();
  157. HRESULT hr = S_OK;
  158. //
  159. // first, set the list box to 3 columns
  160. //
  161. LVCOLUMN lvc;
  162. ::CString strColumnHeader;
  163. WCHAR wzColumnHeader[MAX_PATH];
  164. // initialize the LVCOLUMN structure
  165. lvc.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  166. lvc.fmt = LVCFMT_LEFT;
  167. lvc.pszText = wzColumnHeader;
  168. // Add the vendor column.
  169. strColumnHeader.LoadString(IDS_IAS_MULTI_ATTR_COLUMN_VENDOR);
  170. wcscpy(wzColumnHeader, strColumnHeader);
  171. lvc.cx = ATTRIBUTE_VENDOR_COLUMN_WIDTH;
  172. m_listMultiValues.InsertColumn(0, &lvc);
  173. // Add the value column.
  174. strColumnHeader.LoadString(IDS_IAS_MULTI_ATTR_COLUMN_VALUE);
  175. wcscpy(wzColumnHeader, strColumnHeader);
  176. lvc.cx = ATTRIBUTE_VALUE_COLUMN_WIDTH;
  177. m_listMultiValues.InsertColumn(1, &lvc);
  178. hr = UpdateAttrListCtrl();
  179. // Take action based on whether list is empty or not.
  180. DWORD dwSize;
  181. try
  182. {
  183. dwSize = m_osaValueList.GetOneDimSize();
  184. }
  185. catch(...)
  186. {
  187. dwSize = 0;
  188. }
  189. if( dwSize > 0 )
  190. {
  191. // We have at least one element.
  192. // Select the first element.
  193. m_listMultiValues.SetItemState(0, LVIS_FOCUSED, LVIS_FOCUSED);
  194. m_listMultiValues.SetItemState(0, LVIS_SELECTED, LVIS_SELECTED);
  195. }
  196. else
  197. {
  198. // We are currently empty.
  199. GetDlgItem(IDOK)->EnableWindow(FALSE);
  200. GetDlgItem(IDC_IAS_BUTTON_MOVE_UP)->EnableWindow(FALSE);
  201. GetDlgItem(IDC_IAS_BUTTON_MOVE_DOWN)->EnableWindow(FALSE);
  202. GetDlgItem(IDC_IAS_BUTTON_REMOVE)->EnableWindow(FALSE);
  203. GetDlgItem(IDC_IAS_BUTTON_EDIT)->EnableWindow(FALSE);
  204. }
  205. return TRUE; // return TRUE unless you set the focus to a control
  206. // EXCEPTION: OCX Property Pages should return FALSE
  207. }
  208. //////////////////////////////////////////////////////////////////////////////
  209. /*++
  210. CMultivaluedEditorPage::UpdateAttrListCtrl
  211. --*/
  212. //////////////////////////////////////////////////////////////////////////////
  213. HRESULT CMultivaluedEditorPage::UpdateAttrListCtrl()
  214. {
  215. TRACE_FUNCTION("CMultivaluedEditorPage::UpdateAttrListCtrl");
  216. HRESULT hr = S_OK;
  217. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  218. // Get the editor to use.
  219. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &spIASAttributeEditor );
  220. if( FAILED( hr ) ) return hr;
  221. //
  222. // clear up the whole list first
  223. //
  224. m_listMultiValues.DeleteAllItems();
  225. try
  226. {
  227. DWORD dwSize = m_osaValueList.GetOneDimSize(); // number of multi-valued attrs.
  228. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  229. CMyOleSafeArrayLock osaLock( m_osaValueList );
  230. for (long lIndex = 0; (DWORD) lIndex < dwSize; lIndex++)
  231. {
  232. VARIANT * pvar;
  233. m_osaValueList.PtrOfIndex( &lIndex, (void**) &pvar );
  234. CComBSTR bstrVendor;
  235. CComBSTR bstrValue;
  236. CComBSTR bstrReserved;
  237. // Ignore HRESULT if fails -- we will just end up with empty strings.
  238. HRESULT hrTemp = spIASAttributeEditor->GetDisplayInfo(m_spIASAttributeInfo.p, pvar, &bstrVendor, &bstrValue, &bstrReserved );
  239. m_listMultiValues.InsertItem(lIndex, bstrVendor );
  240. m_listMultiValues.SetItemText( lIndex, 1, bstrValue );
  241. }
  242. }
  243. catch(...)
  244. {
  245. return E_FAIL;
  246. }
  247. return hr;
  248. }
  249. //////////////////////////////////////////////////////////////////////////////
  250. /*++
  251. CMultivaluedEditorPage::OnDblclkListIasMultiAttrs
  252. --*/
  253. //////////////////////////////////////////////////////////////////////////////
  254. void CMultivaluedEditorPage::OnDblclkListIasMultiAttrs(NMHDR* pNMHDR, LRESULT* pResult)
  255. {
  256. TRACE_FUNCTION("CMultivaluedEditorPage::OnDblclkListIasMultiAttrs");
  257. //
  258. // see if there is an item already selected in ProfAttr list
  259. //
  260. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  261. if (NOTHING_SELECTED == iSelected )
  262. {
  263. // do nothing
  264. return;
  265. }
  266. HRESULT hr;
  267. hr = EditItemInList( iSelected );
  268. *pResult = 0;
  269. }
  270. //////////////////////////////////////////////////////////////////////////////
  271. /*++
  272. CMultivaluedEditorPage::UpdateProfAttrListItem
  273. --*/
  274. //////////////////////////////////////////////////////////////////////////////
  275. HRESULT CMultivaluedEditorPage::UpdateProfAttrListItem(int iItem)
  276. {
  277. TRACE_FUNCTION("CMultivaluedEditorPage::UpdateProfAttrListItem");
  278. HRESULT hr = S_OK;
  279. CComBSTR bstrVendor;
  280. CComBSTR bstrValue;
  281. CComBSTR bstrReserved;
  282. try
  283. {
  284. // Get the editor to use.
  285. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  286. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &spIASAttributeEditor );
  287. if( FAILED( hr ) ) throw hr;
  288. // Retrieve item from array.
  289. VARIANT * pvar;
  290. // Scope for osaLock only.
  291. {
  292. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  293. CMyOleSafeArrayLock osaLock( m_osaValueList );
  294. long lIndex = iItem;
  295. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvar );
  296. }
  297. hr = spIASAttributeEditor->GetDisplayInfo(m_spIASAttributeInfo.p, pvar, &bstrVendor, &bstrValue, &bstrReserved );
  298. if( FAILED( hr ) ) throw hr;
  299. }
  300. catch(...)
  301. {
  302. // Do nothing -- we'll just show what we have.
  303. }
  304. // Update the item's display.
  305. m_listMultiValues.SetItemText( iItem, 0, bstrVendor );
  306. m_listMultiValues.SetItemText( iItem, 1, bstrValue );
  307. return S_OK;
  308. }
  309. //////////////////////////////////////////////////////////////////////////////
  310. /*++
  311. CMultivaluedEditorPage::CommitArrayToVariant
  312. --*/
  313. //////////////////////////////////////////////////////////////////////////////
  314. HRESULT CMultivaluedEditorPage::CommitArrayToVariant()
  315. {
  316. TRACE_FUNCTION("CMultivaluedEditorPage::CommitArrayToVariant");
  317. // Commit the safe array passed in to the variant whose pointer
  318. // was passed in in set data.
  319. // Any changes made to the safe array won't be preserver unless
  320. // you call this method.
  321. HRESULT hr;
  322. // VariantCopy initializes the existing m_pvarData
  323. // -- releasing all data associated with it, before
  324. // copying the new value into this destination.
  325. try
  326. {
  327. hr = VariantCopy( m_pvarData, (LPVARIANT) m_osaValueList );
  328. }
  329. catch(...)
  330. {
  331. return E_FAIL;
  332. }
  333. return hr;
  334. }
  335. //////////////////////////////////////////////////////////////////////////////
  336. /*++
  337. CMultivaluedEditorPage::OnButtonMoveUp
  338. --*/
  339. //////////////////////////////////////////////////////////////////////////////
  340. void CMultivaluedEditorPage::OnButtonMoveUp()
  341. {
  342. TRACE_FUNCTION("CMultivaluedEditorPage::OnButtonMoveUp");
  343. HRESULT hr;
  344. try
  345. {
  346. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  347. if( NOTHING_SELECTED == iSelected )
  348. {
  349. // Do nothing.
  350. return;
  351. }
  352. // Swap the currently selected variant with the one above it.
  353. long lIndex = iSelected;
  354. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  355. CMyOleSafeArrayLock osaLock( m_osaValueList );
  356. VARIANT *pvarTop, *pvarBottom;
  357. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvarBottom );
  358. lIndex--;
  359. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvarTop );
  360. void* pvarTemp = pvarTop;
  361. pvarTop = pvarBottom;
  362. pvarBottom = reinterpret_cast<VARIANT*> (pvarTemp);
  363. // Update items that have changed.
  364. UpdateProfAttrListItem( iSelected - 1 );
  365. UpdateProfAttrListItem( iSelected );
  366. // Move the selection down one item.
  367. m_listMultiValues.SetItemState( iSelected, 0, LVIS_SELECTED);
  368. m_listMultiValues.SetItemState( iSelected - 1, LVIS_SELECTED, LVIS_SELECTED);
  369. }
  370. catch(...)
  371. {
  372. // Error message
  373. }
  374. }
  375. //////////////////////////////////////////////////////////////////////////////
  376. /*++
  377. CMultivaluedEditorPage::OnButtonMoveDown
  378. --*/
  379. //////////////////////////////////////////////////////////////////////////////
  380. void CMultivaluedEditorPage::OnButtonMoveDown()
  381. {
  382. TRACE_FUNCTION("CMultivaluedEditorPage::OnButtonMoveDown");
  383. HRESULT hr;
  384. try
  385. {
  386. long lSize = m_osaValueList.GetOneDimSize();
  387. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  388. if( iSelected >= lSize )
  389. {
  390. // Do nothing.
  391. return;
  392. }
  393. // Swap the currently selected variant with the one below it.
  394. long lIndex = iSelected;
  395. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  396. CMyOleSafeArrayLock osaLock( m_osaValueList );
  397. VARIANT *pvarTop, *pvarBottom;
  398. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvarTop );
  399. lIndex++;
  400. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvarBottom );
  401. void* pvarTemp = pvarTop;
  402. pvarTop = pvarBottom;
  403. pvarBottom = reinterpret_cast<VARIANT*> (pvarTemp);
  404. // Update items that have changed.
  405. UpdateProfAttrListItem( iSelected );
  406. UpdateProfAttrListItem( iSelected + 1 );
  407. // Move the selection down one item.
  408. m_listMultiValues.SetItemState( iSelected, 0, LVIS_SELECTED);
  409. m_listMultiValues.SetItemState( iSelected + 1, LVIS_SELECTED, LVIS_SELECTED);
  410. }
  411. catch(...)
  412. {
  413. // Error message
  414. }
  415. }
  416. //////////////////////////////////////////////////////////////////////////////
  417. /*++
  418. CMultivaluedEditorPage::OnButtonAddValue
  419. --*/
  420. //////////////////////////////////////////////////////////////////////////////
  421. void CMultivaluedEditorPage::OnButtonAddValue()
  422. {
  423. TRACE_FUNCTION("CMultivaluedEditorPage::OnButtonAddValue");
  424. CComVariant varNewVariant;
  425. HRESULT hr = S_OK;
  426. try
  427. {
  428. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  429. // Get the editor to use.
  430. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &spIASAttributeEditor );
  431. if( FAILED( hr ) ) throw hr;
  432. // Edit it!
  433. CComBSTR bstrReserved;
  434. hr = spIASAttributeEditor->Edit( m_spIASAttributeInfo.p, &varNewVariant, &bstrReserved );
  435. if( hr == S_OK )
  436. {
  437. VARIANT *pvar;
  438. // Make the safe array bigger by 1
  439. long lSize = m_osaValueList.GetOneDimSize();
  440. m_osaValueList.ResizeOneDim( lSize + 1 );
  441. // Get a pointer to the variant at new position (indexed by lSize+1-1 == lSize)
  442. // Scope for osaLock only.
  443. {
  444. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  445. CMyOleSafeArrayLock osaLock( m_osaValueList );
  446. m_osaValueList.PtrOfIndex( &lSize, (void **) &pvar );
  447. }
  448. hr = VariantCopy( pvar, &varNewVariant );
  449. if (FAILED(hr))
  450. {
  451. throw hr;
  452. }
  453. // The user added the value.
  454. m_fIsDirty = TRUE;
  455. // Make a new place for the newly added value in the list control.
  456. // We pass a null string because we will let UpdataProfAttrListItem do the display text.
  457. m_listMultiValues.InsertItem( lSize, L"" );
  458. // Update the view of that item.
  459. UpdateProfAttrListItem( lSize );
  460. // Take action based on whether list is no longer empty.
  461. DWORD dwSize;
  462. try
  463. {
  464. dwSize = m_osaValueList.GetOneDimSize();
  465. }
  466. catch(...)
  467. {
  468. dwSize = 0;
  469. }
  470. if( dwSize > 0 )
  471. {
  472. // We currently have at least one item.
  473. GetDlgItem(IDOK)->EnableWindow(TRUE);
  474. }
  475. // Deselect any currently selected item.
  476. int iSelected = GetSelectedItemIndex( m_listMultiValues );
  477. if( iSelected != NOTHING_SELECTED )
  478. {
  479. m_listMultiValues.SetItemState( iSelected, 0, LVIS_SELECTED);
  480. }
  481. // Select the newly added item.
  482. m_listMultiValues.SetItemState( lSize, LVIS_SELECTED, LVIS_SELECTED);
  483. if( FAILED( hr ) ) throw hr;
  484. }
  485. }
  486. catch( HRESULT &hr )
  487. {
  488. // Print out error message saying that there was an error adding.
  489. return;
  490. }
  491. catch(...)
  492. {
  493. // Print out error message saying that there was an error adding.
  494. return;
  495. }
  496. }
  497. //////////////////////////////////////////////////////////////////////////////
  498. /*++
  499. CMultivaluedEditorPage::OnButtonRemove
  500. --*/
  501. //////////////////////////////////////////////////////////////////////////////
  502. void CMultivaluedEditorPage::OnButtonRemove()
  503. {
  504. TRACE_FUNCTION("CMultivaluedEditorPage::OnButtonRemove");
  505. //
  506. // see if there is an item already selected in ProfAttr list
  507. //
  508. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  509. if (NOTHING_SELECTED == iSelected )
  510. {
  511. // do nothing
  512. return;
  513. }
  514. HRESULT hr;
  515. try
  516. {
  517. // Swap the currently selected variant with the one below it.
  518. long lTarget = iSelected;
  519. VARIANT *pvarTop, *pvarBottom;
  520. long lSize = m_osaValueList.GetOneDimSize();
  521. // Do some sanity checks.
  522. _ASSERTE( lSize > 0 );
  523. _ASSERTE( lTarget >= 0 && lTarget < lSize );
  524. // Scope for osaLock only.
  525. {
  526. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  527. CMyOleSafeArrayLock osaLock( m_osaValueList );
  528. for( long lIndex = lTarget; lIndex < lSize - 1 ; lIndex++ )
  529. {
  530. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvarTop );
  531. long lNext = lIndex + 1;
  532. m_osaValueList.PtrOfIndex( &lNext, (void **) &pvarBottom );
  533. hr = VariantCopy( pvarTop, pvarBottom );
  534. if( FAILED( hr ) ) throw hr;
  535. }
  536. }
  537. // Reduce the size of the safe array by one.
  538. // NOTE: You must make sure that you have unlocked the safearray before calling this.
  539. // ISSUE: We are assuming this deletes the element in the last position.
  540. m_osaValueList.ResizeOneDim( lSize - 1 );
  541. m_listMultiValues.SetItemState( iSelected, 0, LVIS_SELECTED);
  542. // Remove the item from our list.
  543. if(m_listMultiValues.GetItemCount() > iSelected + 1)
  544. m_listMultiValues.SetItemState( iSelected + 1, LVIS_SELECTED, LVIS_SELECTED);
  545. else if (iSelected > 0)
  546. m_listMultiValues.SetItemState( iSelected - 1, LVIS_SELECTED, LVIS_SELECTED);
  547. else // iSelected == 0; and it's the only one
  548. ::SetFocus(GetDlgItem(IDC_IAS_BUTTON_ADD_VALUE)->m_hWnd);
  549. m_listMultiValues.DeleteItem( iSelected );
  550. // Take action based on whether list is empty or not.
  551. DWORD dwSize;
  552. try
  553. {
  554. dwSize = m_osaValueList.GetOneDimSize();
  555. }
  556. catch(...)
  557. {
  558. dwSize = 0;
  559. }
  560. if( dwSize > 0 )
  561. {
  562. // We have at least one element.
  563. // Make sure the selection stays on the same position in the list.
  564. if( ! m_listMultiValues.SetItemState( iSelected, LVIS_SELECTED, LVIS_SELECTED) )
  565. {
  566. // We failed, probably because the item that was deleted was the last
  567. // in the list, so try to select the one before the deleted item.
  568. m_listMultiValues.SetItemState( iSelected -1, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
  569. }
  570. }
  571. else
  572. {
  573. // We are currently empty.
  574. GetDlgItem(IDOK)->EnableWindow(FALSE);
  575. }
  576. }
  577. catch(...)
  578. {
  579. //ISSUE: Put up error message.
  580. }
  581. }
  582. //////////////////////////////////////////////////////////////////////////////
  583. /*++
  584. CMultivaluedEditorPage::OnButtonEdit
  585. --*/
  586. //////////////////////////////////////////////////////////////////////////////
  587. void CMultivaluedEditorPage::OnButtonEdit()
  588. {
  589. TRACE_FUNCTION("CMultivaluedEditorPage::OnButtonEdit");
  590. //
  591. // see if there is an item already selected in ProfAttr list
  592. //
  593. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  594. if (NOTHING_SELECTED == iSelected )
  595. {
  596. // do nothing
  597. return;
  598. }
  599. HRESULT hr;
  600. hr = EditItemInList( iSelected );
  601. }
  602. //////////////////////////////////////////////////////////////////////////////
  603. /*++
  604. CMultivaluedEditorPage::EditItemInList
  605. --*/
  606. //////////////////////////////////////////////////////////////////////////////
  607. STDMETHODIMP CMultivaluedEditorPage::EditItemInList( long lIndex )
  608. {
  609. TRACE_FUNCTION("CMultivaluedEditorPage::EditItemInList");
  610. HRESULT hr = S_OK;
  611. VARIANT * pvar;
  612. //
  613. // get the current node
  614. //
  615. try
  616. {
  617. // Scope for osaLock only.
  618. {
  619. // Lock the safearray. This wrapper class will unlock as soon as it goes out of scope.
  620. CMyOleSafeArrayLock osaLock( m_osaValueList );
  621. m_osaValueList.PtrOfIndex( &lIndex, (void **) &pvar );
  622. }
  623. CComPtr<IIASAttributeEditor> spIASAttributeEditor;
  624. // Get the editor to use.
  625. hr = SetUpAttributeEditor( m_spIASAttributeInfo.p, &spIASAttributeEditor );
  626. if( FAILED( hr ) ) throw hr;
  627. // Edit it!
  628. CComBSTR bstrReserved;
  629. hr = spIASAttributeEditor->Edit( m_spIASAttributeInfo.p, pvar, &bstrReserved );
  630. if( hr == S_OK )
  631. {
  632. // The user changed the value.
  633. m_fIsDirty = TRUE;
  634. hr = UpdateProfAttrListItem(lIndex);
  635. if( FAILED( hr ) ) throw hr;
  636. }
  637. }
  638. catch( HRESULT & hr )
  639. {
  640. // ISSUE: Should put up an error message.
  641. return hr;
  642. }
  643. catch(...)
  644. {
  645. // ISSUE: Should put up an error message.
  646. return E_FAIL;
  647. }
  648. return hr;
  649. }
  650. //////////////////////////////////////////////////////////////////////////////
  651. /*++
  652. ::SetUpAttributeEditor
  653. --*/
  654. //////////////////////////////////////////////////////////////////////////////
  655. STDMETHODIMP SetUpAttributeEditor( /* in */ IIASAttributeInfo *pIASAttributeInfo
  656. , /* out */ IIASAttributeEditor ** ppIASAttributeEditor
  657. )
  658. {
  659. TRACE_FUNCTION("::SetUpAttributeEditor");
  660. // Check for preconditions:
  661. _ASSERTE( pIASAttributeInfo );
  662. _ASSERTE( ppIASAttributeEditor );
  663. // Query the schema attribute to see which attribute editor to use.
  664. CLSID clsidEditorToUse;
  665. CComBSTR bstrProgID;
  666. HRESULT hr;
  667. hr = pIASAttributeInfo->get_EditorProgID( &bstrProgID );
  668. if( FAILED( hr ) )
  669. {
  670. // We could try putting up a default (e.g. hex) editor, but for now:
  671. return hr;
  672. }
  673. hr = CLSIDFromProgID( bstrProgID, &clsidEditorToUse );
  674. if( FAILED( hr ) )
  675. {
  676. // We could try putting up a default (e.g. hex) editor, but for now:
  677. return hr;
  678. }
  679. hr = CoCreateInstance( clsidEditorToUse , NULL, CLSCTX_INPROC_SERVER, IID_IIASAttributeEditor, (LPVOID *) ppIASAttributeEditor );
  680. if( FAILED( hr ) )
  681. {
  682. return hr;
  683. }
  684. if( ! *ppIASAttributeEditor )
  685. {
  686. return E_FAIL;
  687. }
  688. return hr;
  689. }
  690. //+---------------------------------------------------------------------------
  691. //
  692. // Function: OnItemchangedListIasAllattrs
  693. //
  694. // Class: CDlgIASAddAttr
  695. //
  696. // Synopsis: something has changed in All Attribute list box
  697. // We'll try to get the currently selected one
  698. //
  699. // Arguments: NMHDR* pNMHDR -
  700. // LRESULT* pResult -
  701. //
  702. // Returns: Nothing
  703. //
  704. // History: Created Header 2/19/98 3:32:05 PM
  705. //
  706. //+---------------------------------------------------------------------------
  707. void CMultivaluedEditorPage::OnItemChangedListIasMultiAttrs(NMHDR* pNMHDR, LRESULT* pResult)
  708. {
  709. TRACE(_T("CDlgIASAddAttr::OnItemchangedListIasAllattrs\n"));
  710. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  711. // NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  712. // if (pNMListView->uNewState & LVIS_SELECTED)
  713. // {
  714. // m_dAllAttrCurSel = pNMListView->iItem;
  715. // }
  716. // Set button states depending on whether anything is selected.
  717. int iSelected = GetSelectedItemIndex(m_listMultiValues);
  718. if (NOTHING_SELECTED == iSelected )
  719. {
  720. HWND hFocus = ::GetFocus();
  721. if(hFocus == GetDlgItem(IDC_IAS_BUTTON_REMOVE)->m_hWnd)
  722. ::SetFocus(GetDlgItem(IDC_IAS_BUTTON_ADD_VALUE)->m_hWnd);
  723. GetDlgItem(IDC_IAS_BUTTON_MOVE_UP)->EnableWindow(FALSE);
  724. GetDlgItem(IDC_IAS_BUTTON_MOVE_DOWN)->EnableWindow(FALSE);
  725. GetDlgItem(IDC_IAS_BUTTON_REMOVE)->EnableWindow(FALSE);
  726. GetDlgItem(IDC_IAS_BUTTON_EDIT)->EnableWindow(FALSE);
  727. }
  728. else
  729. {
  730. // Something is selected.
  731. GetDlgItem(IDC_IAS_BUTTON_MOVE_UP)->EnableWindow(TRUE);
  732. GetDlgItem(IDC_IAS_BUTTON_MOVE_DOWN)->EnableWindow(TRUE);
  733. GetDlgItem(IDC_IAS_BUTTON_REMOVE)->EnableWindow(TRUE);
  734. GetDlgItem(IDC_IAS_BUTTON_EDIT)->EnableWindow(TRUE);
  735. }
  736. *pResult = 0;
  737. }