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.

1029 lines
24 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. // ObjVw.cpp : implementation of the CObjView class
  8. //
  9. #include "stdafx.h"
  10. #include "WMITest.h"
  11. #include "MainFrm.h"
  12. #include "WMITestDoc.h"
  13. #include "OpView.h"
  14. #include "ObjVw.h"
  15. #include "ValuePg.h"
  16. #include "PropQualsPg.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CObjView
  24. IMPLEMENT_DYNCREATE(CObjView, CListView)
  25. BEGIN_MESSAGE_MAP(CObjView, CListView)
  26. //{{AFX_MSG_MAP(CObjView)
  27. ON_WM_SIZE()
  28. ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetDispInfo)
  29. ON_NOTIFY_REFLECT(NM_RCLICK, OnRclick)
  30. ON_NOTIFY_REFLECT(NM_DBLCLK, OnDblclk)
  31. ON_COMMAND(ID_MODIFY, OnModify)
  32. ON_UPDATE_COMMAND_UI(ID_MODIFY, OnUpdateModify)
  33. ON_COMMAND(ID_NEW_PROP, OnNewProp)
  34. ON_UPDATE_COMMAND_UI(ID_NEW_PROP, OnUpdateNewProp)
  35. ON_COMMAND(ID_DELETE, OnDelete)
  36. ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  37. ON_WM_DESTROY()
  38. ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  39. //}}AFX_MSG_MAP
  40. END_MESSAGE_MAP()
  41. #define DEF_NAME_COL_CX 175
  42. #define DEF_TYPE_COL_CX 150
  43. #define DEF_VAL_COL_CX 250
  44. #define DEF_SINGLE_COL_CX 300
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CObjView construction/destruction
  47. CObjView::CObjView() :
  48. m_pList(NULL),
  49. m_hitemLastChildUpdate(NULL),
  50. m_hitemLastParentUpdate(NULL),
  51. m_nCols(0),
  52. m_iColHint(0),
  53. m_pWrap(NULL)
  54. {
  55. CString strCols;
  56. strCols =
  57. theApp.GetProfileString(_T("Settings"), _T("ColWidths"), _T("175 150 250 300"));
  58. if (_stscanf(
  59. strCols,
  60. _T("%d %d %d %d"),
  61. &m_cxPropertyCols[0],
  62. &m_cxPropertyCols[1],
  63. &m_cxPropertyCols[2],
  64. &m_cxSingleCol) != 4)
  65. {
  66. m_cxPropertyCols[0] = DEF_NAME_COL_CX;
  67. m_cxPropertyCols[1] = DEF_TYPE_COL_CX;
  68. m_cxPropertyCols[2] = DEF_VAL_COL_CX;
  69. m_cxSingleCol = DEF_SINGLE_COL_CX;
  70. }
  71. }
  72. CObjView::~CObjView()
  73. {
  74. }
  75. BOOL CObjView::PreCreateWindow(CREATESTRUCT& cs)
  76. {
  77. cs.style |= WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SHAREIMAGELISTS;
  78. return CListView::PreCreateWindow(cs);
  79. }
  80. /////////////////////////////////////////////////////////////////////////////
  81. // CObjView drawing
  82. void CObjView::OnInitialUpdate()
  83. {
  84. CListView::OnInitialUpdate();
  85. m_pList->SetExtendedStyle(LVS_EX_FULLROWSELECT);
  86. m_pList->SetImageList(&((CMainFrame *) GetParentFrame())->m_imageList,
  87. LVSIL_SMALL);
  88. GetDocument()->m_pObjView = this;
  89. }
  90. /////////////////////////////////////////////////////////////////////////////
  91. // CObjView diagnostics
  92. #ifdef _DEBUG
  93. void CObjView::AssertValid() const
  94. {
  95. CListView::AssertValid();
  96. }
  97. void CObjView::Dump(CDumpContext& dc) const
  98. {
  99. CListView::Dump(dc);
  100. }
  101. CWMITestDoc* CObjView::GetDocument() // non-debug version is inline
  102. {
  103. ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CWMITestDoc)));
  104. return (CWMITestDoc*)m_pDocument;
  105. }
  106. #endif //_DEBUG
  107. void CObjView::OnSize(UINT nType, int cx, int cy)
  108. {
  109. CListView::OnSize(nType, cx, cy);
  110. if (!m_pList)
  111. m_pList = &GetListCtrl();
  112. }
  113. void CObjView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
  114. {
  115. CTreeCtrl *pTree = GetDocument()->m_pOpView->m_pTree;
  116. HTREEITEM hItem = (HTREEITEM) pHint;
  117. CObjInfo *pInfo = NULL;
  118. if (!pTree)
  119. return;
  120. switch(lHint)
  121. {
  122. case HINT_NEW_CHILD:
  123. {
  124. // A child was added. We only need to do stuff if the child's
  125. // parent is the same one that's selected.
  126. if (m_hitemLastParentUpdate == pTree->GetParentItem(hItem))
  127. {
  128. int iImage;
  129. pTree->GetItemImage(hItem, iImage, iImage);
  130. if (!m_nCols ||
  131. (m_pWrap && m_pWrap->m_piDisplayCols.GetUpperBound() >=
  132. m_nCols))
  133. {
  134. // Don't need to remove columns here.
  135. AddColumns(m_hitemLastParentUpdate);
  136. }
  137. m_pList->InsertItem(
  138. LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE,
  139. m_pList->GetItemCount(),
  140. LPSTR_TEXTCALLBACK,
  141. 0,
  142. 0,
  143. iImage,
  144. (LPARAM) hItem);
  145. }
  146. break;
  147. }
  148. case HINT_NEW_OP:
  149. // We don't care unless we start to display stuff for the root
  150. // item.
  151. break;
  152. case HINT_OP_SEL:
  153. {
  154. COpWrap *pWrap = (COpWrap*) pTree->GetItemData(hItem);
  155. if (!pWrap->IsObject())
  156. {
  157. m_hitemLastParentUpdate = hItem;
  158. m_hitemLastChildUpdate = NULL;
  159. // Need to get rid of all columns.
  160. RemoveColumns();
  161. m_iColHint = HINT_OP_SEL;
  162. AddColumns(hItem);
  163. // So we don't have to keep asking for this.
  164. m_pWrap = (COpWrap*) pTree->GetItemData(m_hitemLastParentUpdate);
  165. // Fill the list with all the items in this parent.
  166. AddChildItems(hItem);
  167. break;
  168. }
  169. else
  170. {
  171. // If we're an op that's itself an object (Get Obj and Get
  172. // Class).
  173. // Fake an object selection.
  174. pInfo = pWrap->GetObjInfo();
  175. // Fall through to finish our fakery.
  176. }
  177. }
  178. case HINT_OBJ_SEL:
  179. m_hitemLastParentUpdate = NULL;
  180. if (m_iColHint != HINT_OBJ_SEL || !m_nCols)
  181. {
  182. RemoveColumns();
  183. m_iColHint = HINT_OBJ_SEL;
  184. AddColumns();
  185. }
  186. m_pWrap = NULL;
  187. m_hitemLastChildUpdate = hItem;
  188. if (!pInfo)
  189. pInfo = (CObjInfo*) pTree->GetItemData(hItem);
  190. AddObjValues(pInfo);
  191. break;
  192. case HINT_ROOT_SEL:
  193. m_hitemLastParentUpdate = NULL;
  194. m_hitemLastChildUpdate = NULL;
  195. if (m_iColHint != HINT_ROOT_SEL)
  196. {
  197. RemoveColumns();
  198. m_iColHint = HINT_ROOT_SEL;
  199. // Need to get rid of all columns.
  200. AddColumns();
  201. }
  202. m_pWrap = NULL;
  203. break;
  204. }
  205. }
  206. void CObjView::OnGetDispInfo(NMHDR* pNMHDR, LRESULT* pResult)
  207. {
  208. LV_DISPINFO *pDispInfo = (LV_DISPINFO*) pNMHDR;
  209. int iItem = pDispInfo->item.iItem,
  210. iSubItem = pDispInfo->item.iSubItem;
  211. CString str;
  212. HTREEITEM hitem = (HTREEITEM) m_pList->GetItemData(iItem);
  213. // Op node selected in tree?
  214. if (m_hitemLastParentUpdate)
  215. {
  216. pDispInfo->item.mask |= LVIF_DI_SETITEM;
  217. if (pDispInfo->item.mask & LVIF_IMAGE)
  218. {
  219. pDispInfo->item.iImage = m_iItemImage;
  220. }
  221. if (pDispInfo->item.mask & LVIF_TEXT)
  222. {
  223. CObjInfo *pInfo = (CObjInfo*) GetDocument()->m_pOpView->m_pTree->
  224. GetItemData(hitem);
  225. if (!m_pWrap->ShowPathsOnly())
  226. {
  227. int iProperty = m_piDisplayCols[iSubItem];
  228. pDispInfo->item.pszText[pDispInfo->item.cchTextMax - 1] = '\0';
  229. if (pInfo)
  230. {
  231. CString strValue;
  232. m_pWrap->GetPropValue(
  233. pInfo, iProperty, strValue, theApp.m_bTranslateValues);
  234. lstrcpyn(pDispInfo->item.pszText, strValue, pDispInfo->item.cchTextMax - 1);
  235. }
  236. }
  237. else
  238. {
  239. CString strName = pInfo->GetStringPropValue(L"__RELPATH");
  240. lstrcpyn(pDispInfo->item.pszText, strName, pDispInfo->item.cchTextMax - 1);
  241. }
  242. }
  243. }
  244. *pResult = 0;
  245. }
  246. void CObjView::SaveColumns()
  247. {
  248. if (m_iColHint == HINT_OP_SEL)
  249. {
  250. if (m_pWrap->ShowPathsOnly())
  251. m_cxSingleCol = m_pList->GetColumnWidth(0);
  252. else
  253. {
  254. for (int i = 0; i < m_nCols; i++)
  255. m_pWrap->m_piDisplayColsWidth[i] = m_pList->GetColumnWidth(i);
  256. }
  257. }
  258. else if (m_iColHint == HINT_OBJ_SEL)
  259. {
  260. for (int i = 0; i < 3; i++)
  261. m_cxPropertyCols[i] = m_pList->GetColumnWidth(i);
  262. }
  263. }
  264. void CObjView::RemoveColumns()
  265. {
  266. while (m_nCols > 0)
  267. m_pList->DeleteColumn(--m_nCols);
  268. m_pList->DeleteAllItems();
  269. }
  270. void CObjView::AddColumns(HTREEITEM hItem)
  271. {
  272. //if (bRemovePrevCols)
  273. // RemoveAllColumns();
  274. switch(m_iColHint)
  275. {
  276. case HINT_OBJ_SEL:
  277. {
  278. CString strTemp;
  279. strTemp.LoadString(IDS_NAME);
  280. m_pList->InsertColumn(0, strTemp, LVCFMT_LEFT, m_cxPropertyCols[0]);
  281. strTemp.LoadString(IDS_TYPE);
  282. m_pList->InsertColumn(1, strTemp, LVCFMT_LEFT, m_cxPropertyCols[1]);
  283. strTemp.LoadString(IDS_VALUE);
  284. m_pList->InsertColumn(2, strTemp, LVCFMT_LEFT, m_cxPropertyCols[2]);
  285. m_nCols = 3;
  286. break;
  287. }
  288. case HINT_OP_SEL:
  289. {
  290. CTreeCtrl *pTree = GetDocument()->m_pOpView->m_pTree;
  291. COpWrap *pWrap = (COpWrap*) pTree->GetItemData(hItem);
  292. if (!pWrap->ShowPathsOnly())
  293. {
  294. int nItems = pWrap->m_piDisplayCols.GetUpperBound() + 1;
  295. m_piDisplayCols.SetSize(nItems);
  296. for (int i = m_nCols; i < nItems; i++)
  297. {
  298. CString &strClass = pWrap->m_strProps[pWrap->m_piDisplayCols[i]];
  299. m_piDisplayCols[i] = pWrap->m_piDisplayCols[i];
  300. m_pList->InsertColumn(
  301. i,
  302. strClass,
  303. LVCFMT_LEFT,
  304. pWrap->m_piDisplayColsWidth[i]);
  305. }
  306. // Set the number of columns to nItems.
  307. m_nCols = nItems;
  308. }
  309. else
  310. {
  311. if (m_nCols == 0)
  312. {
  313. CString strClass;
  314. strClass.LoadString(pWrap->HoldsObjects() ? IDS_OBJ_PATH : IDS_CLASS);
  315. m_pList->InsertColumn(m_nCols++, strClass, LVCFMT_LEFT, m_cxSingleCol);
  316. }
  317. }
  318. break;
  319. }
  320. }
  321. }
  322. void CObjView::AddChildItems(HTREEITEM hItem)
  323. {
  324. CTreeCtrl *pTree = GetDocument()->m_pOpView->m_pTree;
  325. for (HTREEITEM itemChild = pTree->GetChildItem(hItem);
  326. itemChild != NULL;
  327. itemChild = pTree->GetNextSiblingItem(itemChild))
  328. {
  329. int iImage;
  330. pTree->GetItemImage(itemChild, iImage, iImage);
  331. m_pList->InsertItem(
  332. LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE,
  333. m_pList->GetItemCount(),
  334. LPSTR_TEXTCALLBACK,
  335. 0,
  336. 0,
  337. iImage,
  338. (LPARAM) itemChild);
  339. }
  340. }
  341. void CObjView::AddObjValues(HTREEITEM hItem)
  342. {
  343. CTreeCtrl *pTree = GetDocument()->m_pOpView->m_pTree;
  344. CObjInfo *pInfo = (CObjInfo*) pTree->GetItemData(hItem);
  345. AddObjValues(pInfo);
  346. }
  347. void CObjView::AddObjValues(CObjInfo *pInfo)
  348. {
  349. m_pList->DeleteAllItems();
  350. CPropInfoArray *pProps = pInfo->GetProps();
  351. if (pInfo->m_pObj != NULL && pProps != NULL)
  352. {
  353. for (int i = 0; i <= pProps->GetUpperBound(); i++)
  354. {
  355. int iFlavor,
  356. iImage;
  357. CString strType,
  358. strValue;
  359. pInfo->GetPropInfo(i, strValue, strType, &iImage, &iFlavor,
  360. theApp.m_bTranslateValues);
  361. if ((theApp.m_bShowSystemProperties ||
  362. iFlavor != WBEM_FLAVOR_ORIGIN_SYSTEM) &&
  363. (theApp.m_bShowInheritedProperties ||
  364. iFlavor != WBEM_FLAVOR_ORIGIN_PROPAGATED))
  365. {
  366. int iIndex;
  367. iIndex =
  368. m_pList->InsertItem(
  369. LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE,
  370. m_pList->GetItemCount(),
  371. (*pProps)[i].m_strName,
  372. 0,
  373. 0,
  374. iImage,
  375. i);
  376. m_pList->SetItemText(iIndex, 1, strType);
  377. m_pList->SetItemText(iIndex, 2, strValue);
  378. }
  379. }
  380. }
  381. }
  382. void CObjView::Flush()
  383. {
  384. CString strCols;
  385. strCols.Format(
  386. _T("%d %d %d %d"),
  387. m_cxPropertyCols[0],
  388. m_cxPropertyCols[1],
  389. m_cxPropertyCols[2],
  390. m_cxSingleCol);
  391. theApp.WriteProfileString(_T("Settings"), _T("ColWidths"), strCols);
  392. RemoveColumns();
  393. }
  394. void CObjView::DoPopupMenu(UINT nMenuID)
  395. {
  396. CMenu popMenu;
  397. popMenu.LoadMenu(nMenuID);
  398. CPoint posMouse;
  399. GetCursorPos(&posMouse);
  400. CWnd* pWndPopupOwner = this;
  401. while (pWndPopupOwner->GetStyle() & WS_CHILD)
  402. pWndPopupOwner = pWndPopupOwner->GetParent();
  403. popMenu.GetSubMenu(0)->TrackPopupMenu(0,posMouse.x,posMouse.y,pWndPopupOwner);
  404. }
  405. CObjInfo *CObjView::GetCurrentObj()
  406. {
  407. CObjInfo *pInfo = NULL;
  408. if (m_iColHint == HINT_OP_SEL)
  409. {
  410. HTREEITEM hitem = GetSelectedItem();
  411. if (hitem)
  412. pInfo = (CObjInfo*) GetDocument()->m_pOpView->m_pTree->
  413. GetItemData(hitem);
  414. }
  415. return pInfo;
  416. }
  417. void CObjView::OnDelete()
  418. {
  419. int iItem = GetSelectedItemIndex();
  420. if (iItem == -1)
  421. return;
  422. // Object selected?
  423. if (m_pWrap != NULL)
  424. {
  425. HTREEITEM hItem = (HTREEITEM) m_pList->GetItemData(iItem);
  426. if (hItem)
  427. GetDocument()->m_pOpView->RemoveItemFromTree(hItem, FALSE);
  428. }
  429. // Property selected
  430. else
  431. {
  432. CString strProperty;
  433. CObjInfo *pObj = GetDocument()->m_pOpView->GetCurrentObj();
  434. if (pObj)
  435. {
  436. HRESULT hr;
  437. strProperty = m_pList->GetItemText(iItem, 0);
  438. hr = pObj->m_pObj->Delete(_bstr_t(strProperty));
  439. if (SUCCEEDED(hr))
  440. {
  441. pObj->SetModified(TRUE);
  442. GetDocument()->m_pOpView->UpdateCurrentObject(TRUE);
  443. }
  444. else
  445. CWMITestDoc::DisplayWMIErrorBox(hr);
  446. }
  447. }
  448. }
  449. void CObjView::OnRclick(NMHDR* pNMHDR, LRESULT* pResult)
  450. {
  451. CPoint curPoint;
  452. GetCursorPos(&curPoint);
  453. ScreenToClient(&curPoint);
  454. int iItem = m_pList->HitTest(curPoint);
  455. // Object selected?
  456. if (m_pWrap != NULL)
  457. {
  458. if (iItem != -1)
  459. {
  460. HTREEITEM hItem = (HTREEITEM) m_pList->GetItemData(iItem);
  461. if (hItem)
  462. GetDocument()->m_pOpView->DoContextMenuForItem(hItem);
  463. }
  464. }
  465. // Property selected
  466. else
  467. {
  468. CString strTemp;
  469. if (iItem == -1)
  470. GetDocument()->m_pOpView->DoPopupMenu(IDR_NEW_PROP);
  471. else
  472. {
  473. if (GetSelectedObjPath(strTemp))
  474. GetDocument()->m_pOpView->DoPopupMenu(IDR_PROP_AND_INST);
  475. else
  476. GetDocument()->m_pOpView->DoPopupMenu(IDR_PROP);
  477. }
  478. }
  479. *pResult = 0;
  480. }
  481. int CObjView::GetSelectedItemIndex()
  482. {
  483. POSITION pos = m_pList->GetFirstSelectedItemPosition();
  484. if (pos)
  485. return m_pList->GetNextSelectedItem(pos);
  486. else
  487. return -1;
  488. }
  489. HTREEITEM CObjView::GetSelectedItem()
  490. {
  491. int iItem = GetSelectedItemIndex();
  492. if (iItem != -1 && m_iColHint == HINT_OP_SEL)
  493. return (HTREEITEM) m_pList->GetItemData(iItem);
  494. else
  495. return NULL;
  496. }
  497. BOOL CObjView::GetSelectedObjPath(CString &strPath)
  498. {
  499. BOOL bRet = FALSE;
  500. CObjInfo *pInfo = GetCurrentObj();
  501. if (pInfo)
  502. {
  503. strPath = pInfo->GetStringPropValue(L"__RELPATH");
  504. bRet = TRUE;
  505. }
  506. else
  507. {
  508. int iItem = GetSelectedItemIndex();
  509. if (iItem != -1)
  510. {
  511. pInfo = GetDocument()->m_pOpView->GetCurrentObj();
  512. if (pInfo && pInfo->GetProps()->GetData()[iItem].m_type == CIM_REFERENCE)
  513. {
  514. CString strItem = pInfo->GetStringPropValue(iItem);
  515. // Assume we need an equal sign for this to be an object path.
  516. if (strItem.Find('=') != -1)
  517. {
  518. strPath = strItem;
  519. bRet = TRUE;
  520. }
  521. }
  522. }
  523. }
  524. return bRet;
  525. }
  526. BOOL CObjView::GetSelectedClass(CString &strClass)
  527. {
  528. BOOL bRet = FALSE;
  529. CObjInfo *pInfo = GetCurrentObj();
  530. if (pInfo)
  531. {
  532. strClass = pInfo->GetStringPropValue(L"__CLASS");
  533. bRet = TRUE;
  534. }
  535. else
  536. {
  537. int iItem = GetSelectedItemIndex();
  538. if (iItem != -1)
  539. {
  540. pInfo = GetDocument()->m_pOpView->GetCurrentObj();
  541. if (pInfo && pInfo->GetProps()->GetData()[iItem].m_type == CIM_REFERENCE)
  542. {
  543. CString strItem = pInfo->GetStringPropValue(iItem);
  544. if (!strItem.IsEmpty())
  545. {
  546. int iWhere = strItem.Find(':');
  547. if (iWhere != -1)
  548. strItem = strItem.Mid(iWhere + 1);
  549. iWhere = strItem.Find('.');
  550. if (iWhere != -1)
  551. strItem = strItem.Left(iWhere);
  552. strClass = strItem;
  553. bRet = TRUE;
  554. }
  555. }
  556. }
  557. }
  558. return bRet;
  559. }
  560. void CObjView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
  561. {
  562. EditCurrentSelection();
  563. *pResult = 0;
  564. }
  565. BOOL CObjView::EditProperty(CObjInfo *pObj, CPropInfo *pProp, VARIANT *pVar)
  566. {
  567. CString strTitle;
  568. strTitle.Format(IDS_EDIT_PROPERTY, pProp->m_strName);
  569. CPropertySheet sheet(strTitle);
  570. CValuePg pgValue;
  571. CPropQualsPg pgQuals;
  572. BOOL bRet = FALSE;
  573. pgValue.m_propUtil.m_prop = *pProp;
  574. pgValue.m_propUtil.m_pVar = pVar;
  575. pgValue.m_propUtil.m_bTranslate = theApp.m_bTranslateValues;
  576. pgValue.m_propUtil.m_pNamespace = g_pOpView->GetDocument()->m_pNamespace;
  577. pgQuals.m_pObj = pObj->m_pObj;
  578. pgQuals.m_propInfo = *pProp;
  579. pgQuals.m_mode = CPropQualsPg::QMODE_PROP;
  580. pgQuals.m_bIsInstance = pObj->IsInstance();
  581. sheet.AddPage(&pgValue);
  582. sheet.AddPage(&pgQuals);
  583. if (sheet.DoModal() == IDOK)
  584. {
  585. // TODO: Save this property, indicate the object has changed.
  586. HRESULT hr;
  587. hr = pObj->m_pObj->Put(
  588. _bstr_t(pProp->m_strName),
  589. 0,
  590. pVar,
  591. 0);
  592. if (SUCCEEDED(hr))
  593. bRet = TRUE;
  594. else
  595. CWMITestDoc::DisplayWMIErrorBox(hr);
  596. }
  597. return bRet;
  598. }
  599. void CObjView::EditCurrentSelection()
  600. {
  601. // Property selected?
  602. if (InPropertyMode())
  603. {
  604. CObjInfo *pObj = NULL;
  605. CPropInfo *pProp = NULL;
  606. _variant_t var;
  607. if (GetCurrentProperty(&pObj, &pProp, &var))
  608. {
  609. int iItem = GetSelectedItemIndex();
  610. if (EditProperty(pObj, pProp, &var))
  611. {
  612. pObj->SetModified(TRUE);
  613. GetDocument()->m_pOpView->UpdateCurrentObject(TRUE);
  614. if (iItem != -1)
  615. {
  616. m_pList->EnsureVisible(iItem, FALSE);
  617. m_pList->SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED);
  618. }
  619. }
  620. }
  621. // Otherwise the destructor freaks out because it doesn't know what to
  622. // do with VT_I8.
  623. if (var.vt == VT_I8)
  624. var.vt = VT_I4;
  625. }
  626. else
  627. // In object mode
  628. {
  629. CObjInfo *pObj = GetCurrentObj();
  630. if (pObj)
  631. {
  632. GetDocument()->m_pOpView->EditObj(pObj);
  633. /* Bring this back once we make the 1st column be __RELPATH.
  634. LVFINDINFO find;
  635. int iItem;
  636. CString strItem = pObj->GetObjText();
  637. find.flags = LVFI_STRING;
  638. find.psz = strItem;
  639. iItem = m_pList->FindItem(&find);
  640. if (iItem != -1)
  641. {
  642. m_pList->EnsureVisible(iItem, FALSE);
  643. m_pList->SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED);
  644. }
  645. */
  646. }
  647. }
  648. }
  649. BOOL CObjView::GetCurrentProperty(CObjInfo **ppObj, CPropInfo **ppProp, VARIANT *pVar)
  650. {
  651. BOOL bRet = FALSE;
  652. // Property selected?
  653. if (InPropertyMode())
  654. {
  655. int iItem = GetSelectedItemIndex();
  656. if (iItem != -1)
  657. {
  658. // Translate the selected index to the property index.
  659. iItem = m_pList->GetItemData(iItem);
  660. *ppObj = GetDocument()->m_pOpView->GetCurrentObj();
  661. *ppProp = &(*ppObj)->GetProps()->GetData()[iItem];
  662. (*ppObj)->ValueToVariant(iItem, pVar);
  663. bRet = TRUE;
  664. }
  665. }
  666. return bRet;
  667. }
  668. void CObjView::OnModify()
  669. {
  670. EditCurrentSelection();
  671. }
  672. void CObjView::OnUpdateModify(CCmdUI* pCmdUI)
  673. {
  674. pCmdUI->Enable(GetSelectedItemIndex() != -1);
  675. }
  676. void CObjView::OnNewProp()
  677. {
  678. // Property selected?
  679. if (InPropertyMode())
  680. {
  681. CObjInfo *pObj = GetDocument()->m_pOpView->GetCurrentObj();
  682. CString strProperty;
  683. if (AddProperty(pObj, strProperty))
  684. {
  685. pObj->SetModified(TRUE);
  686. GetDocument()->m_pOpView->UpdateCurrentObject(TRUE);
  687. LVFINDINFO find;
  688. int iItem;
  689. find.flags = LVFI_STRING;
  690. find.psz = strProperty;
  691. iItem = m_pList->FindItem(&find);
  692. if (iItem != -1)
  693. {
  694. m_pList->EnsureVisible(iItem, FALSE);
  695. m_pList->SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED);
  696. }
  697. }
  698. }
  699. }
  700. BOOL CObjView::AddProperty(CObjInfo *pObj, CString &strName)
  701. {
  702. CPropertySheet sheet(IDS_NEW_PROPERTY);
  703. CValuePg pg;
  704. _variant_t var;
  705. BOOL bRet = FALSE;
  706. var.vt = VT_NULL;
  707. pg.m_propUtil.m_pVar = &var;
  708. pg.m_propUtil.m_bTranslate = theApp.m_bTranslateValues;
  709. pg.m_propUtil.m_bNewProperty = TRUE;
  710. pg.m_propUtil.m_pNamespace = g_pOpView->GetDocument()->m_pNamespace;
  711. sheet.AddPage(&pg);
  712. if (sheet.DoModal() == IDOK)
  713. {
  714. HRESULT hr;
  715. hr = pObj->m_pObj->Put(
  716. _bstr_t(pg.m_propUtil.m_prop.m_strName),
  717. 0,
  718. &var,
  719. pg.m_propUtil.m_prop.m_type);
  720. if (SUCCEEDED(hr))
  721. {
  722. bRet = TRUE;
  723. strName = pg.m_propUtil.m_prop.m_strName;
  724. }
  725. else
  726. CWMITestDoc::DisplayWMIErrorBox(hr);
  727. }
  728. return bRet;
  729. }
  730. void CObjView::OnUpdateNewProp(CCmdUI* pCmdUI)
  731. {
  732. BOOL bEnable = FALSE;
  733. if (InPropertyMode())
  734. {
  735. CObjInfo *pObj = GetDocument()->m_pOpView->GetCurrentObj();
  736. if (pObj && !pObj->IsInstance())
  737. bEnable = TRUE;
  738. }
  739. pCmdUI->Enable(bEnable);
  740. }
  741. BOOL CObjView::CanCopy()
  742. {
  743. return GetSelectedItemIndex() != -1;
  744. }
  745. void CObjView::OnUpdateEditCopy(CCmdUI* pCmdUI)
  746. {
  747. pCmdUI->Enable(CanCopy());
  748. }
  749. void CObjView::OnEditCopy()
  750. {
  751. if (InPropertyMode())
  752. {
  753. POSITION pos = m_pList->GetFirstSelectedItemPosition();
  754. CString strFinal;
  755. while (pos)
  756. {
  757. int iIndex = m_pList->GetNextSelectedItem(pos);
  758. if (!strFinal.IsEmpty())
  759. strFinal += "\r\n";
  760. strFinal += m_pList->GetItemText(iIndex, 2);
  761. }
  762. // Set the ANSI text data.
  763. DWORD dwSize = strFinal.GetLength() + 1;
  764. HGLOBAL hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwSize);
  765. memcpy(GlobalLock(hglob), (LPCTSTR) strFinal, dwSize);
  766. GlobalUnlock(hglob);
  767. ::OpenClipboard(NULL);
  768. SetClipboardData(CF_TEXT, hglob);
  769. // Set the Unicode text data.
  770. _bstr_t strUnicode = strFinal;
  771. dwSize *= 2;
  772. hglob = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, dwSize);
  773. memcpy(GlobalLock(hglob), (LPCWSTR) strUnicode, dwSize);
  774. GlobalUnlock(hglob);
  775. SetClipboardData(CF_UNICODETEXT, hglob);
  776. CloseClipboard();
  777. }
  778. else
  779. {
  780. COpList list;
  781. BuildSelectedOpList(list);
  782. GetDocument()->m_pOpView->DoCopy(list);
  783. }
  784. }
  785. void CObjView::BuildSelectedOpList(COpList &list)
  786. {
  787. POSITION pos = m_pList->GetFirstSelectedItemPosition();
  788. CTreeCtrl *pTree = GetDocument()->m_pOpView->m_pTree;
  789. list.RemoveAll();
  790. while (pos)
  791. {
  792. int iIndex = m_pList->GetNextSelectedItem(pos);
  793. HTREEITEM hitem = (HTREEITEM) m_pList->GetItemData(iIndex);
  794. CObjInfo *pObj = GetDocument()->m_pOpView->GetObjInfo(hitem);
  795. CString strRelpath = pObj->GetStringPropValue(L"__RELPATH");
  796. if (!strRelpath.IsEmpty())
  797. {
  798. BOOL bIsClass = strRelpath.Find('=') == -1;
  799. COpWrap wrap(bIsClass ? WMI_GET_CLASS : WMI_GET_OBJ, strRelpath);
  800. list.AddTail(wrap);
  801. }
  802. }
  803. }