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.

516 lines
12 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. // PropQualsPg.cpp : implementation file
  8. //
  9. #include "stdafx.h"
  10. #include "wmitest.h"
  11. #include "WMITestDoc.h"
  12. #include "MainFrm.h"
  13. #include "OpWrap.h"
  14. #include "PropQualsPg.h"
  15. #include "EditQualDlg.h"
  16. #include "OpView.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CPropQualsPg property page
  24. IMPLEMENT_DYNCREATE(CPropQualsPg, CPropertyPage)
  25. CPropQualsPg::CPropQualsPg() :
  26. CPropertyPage(CPropQualsPg::IDD),
  27. m_mode(QMODE_PROP),
  28. m_bIsInstance(FALSE),
  29. m_pObj(NULL),
  30. m_pQuals(NULL)
  31. {
  32. //{{AFX_DATA_INIT(CPropQualsPg)
  33. // NOTE: the ClassWizard will add member initialization here
  34. //}}AFX_DATA_INIT
  35. }
  36. CPropQualsPg::~CPropQualsPg()
  37. {
  38. if (m_pQuals)
  39. m_pQuals->Release();
  40. }
  41. void CPropQualsPg::DoDataExchange(CDataExchange* pDX)
  42. {
  43. CPropertyPage::DoDataExchange(pDX);
  44. //{{AFX_DATA_MAP(CPropQualsPg)
  45. DDX_Control(pDX, IDC_QUALS, m_ctlQuals);
  46. //}}AFX_DATA_MAP
  47. if (!pDX->m_bSaveAndValidate)
  48. {
  49. }
  50. else
  51. {
  52. /*
  53. // Delete the quals in m_listQualsToDelete.
  54. POSITION pos = m_listQualsToDelete.GetHeadPosition();
  55. while(pos)
  56. {
  57. CQual &qual = m_listQualsToDelete.GetNext(pos);
  58. HRESULT hr;
  59. hr = m_pQuals->Delete(_bstr_t(qual.m_strName));
  60. }
  61. // Add our quals.
  62. BOOL bNoFlavor = m_bIsInstance || !m_bInPropQualMode;
  63. pos = m_listQuals.GetHeadPosition();
  64. while(pos)
  65. {
  66. CQual &qual = m_listQuals.GetNext(pos);
  67. HRESULT hr;
  68. hr =
  69. m_pQuals->Put(
  70. _bstr_t(qual.m_strName),
  71. &qual.m_var,
  72. bNoFlavor ? 0 : qual.m_lFlavor);
  73. if (FAILED(hr))
  74. // TODO: We need to tell the user which qualifer
  75. // failed here.
  76. CWMITestDoc::DisplayWMIErrorBox(hr, NULL);
  77. }
  78. */
  79. if (!m_bIsInstance)
  80. {
  81. // Now put in the standard qualifer.
  82. PROP_TYPE type = (PROP_TYPE) (GetCheckedRadioButton(IDC_KEY,
  83. IDC_NORMAL) - IDC_KEY);
  84. // Get rid of the previous one since these are apparently mutually
  85. // exclusive but winmgmt doesn't do it for us.
  86. if (type != m_type && m_type != PROP_NORMAL)
  87. m_pQuals->Delete(TypeToQual(m_type));
  88. if (type != PROP_NORMAL)
  89. {
  90. _variant_t var = true;
  91. LPCWSTR szVar = TypeToQual(type);
  92. HRESULT hr;
  93. hr =
  94. m_pQuals->Put(
  95. szVar,
  96. &var,
  97. 0);
  98. if (FAILED(hr))
  99. // TODO: We need to tell the user which qualifer
  100. // failed here.
  101. CWMITestDoc::DisplayWMIErrorBox(hr);
  102. }
  103. }
  104. }
  105. }
  106. void CPropQualsPg::InitListCtrl()
  107. {
  108. RECT rect;
  109. CString strTemp;
  110. m_ctlQuals.SetExtendedStyle(LVS_EX_FULLROWSELECT);
  111. m_ctlQuals.SetImageList(&((CMainFrame *) AfxGetMainWnd())->m_imageList,
  112. LVSIL_SMALL);
  113. m_ctlQuals.GetClientRect(&rect);
  114. strTemp.LoadString(IDS_NAME);
  115. m_ctlQuals.InsertColumn(0, strTemp, LVCFMT_LEFT, rect.right * 25 / 100);
  116. strTemp.LoadString(IDS_TYPE);
  117. m_ctlQuals.InsertColumn(1, strTemp, LVCFMT_LEFT, rect.right * 25 / 100);
  118. strTemp.LoadString(IDS_VALUE);
  119. m_ctlQuals.InsertColumn(2, strTemp, LVCFMT_LEFT, rect.right * 50 / 100);
  120. }
  121. LPCWSTR CPropQualsPg::TypeToQual(PROP_TYPE type)
  122. {
  123. LPCWSTR szRet = NULL;
  124. switch(type)
  125. {
  126. case PROP_KEY:
  127. szRet = L"key";
  128. break;
  129. case PROP_INDEXED:
  130. szRet = L"indexed";
  131. break;
  132. case PROP_NOT_NULL:
  133. szRet = L"not_null";
  134. break;
  135. }
  136. return szRet;
  137. }
  138. HRESULT CPropQualsPg::InitQualSet()
  139. {
  140. HRESULT hr;
  141. if (m_mode == QMODE_PROP)
  142. hr = m_pObj->GetPropertyQualifierSet(
  143. _bstr_t(m_propInfo.m_strName),
  144. &m_pQuals);
  145. else if (m_mode == QMODE_CLASS)
  146. hr = m_pObj->GetQualifierSet(&m_pQuals);
  147. else
  148. hr = m_pObj->GetMethodQualifierSet(
  149. _bstr_t(m_strMethodName),
  150. &m_pQuals);
  151. return hr;
  152. }
  153. void CPropQualsPg::LoadQuals()
  154. {
  155. HRESULT hr;
  156. //CString strType;
  157. //int iImage;
  158. //m_propInfo.GetPropType(strType, &iImage);
  159. //SetDlgItemText(IDC_TYPE, strType);
  160. m_ctlQuals.DeleteAllItems();
  161. m_listQuals.RemoveAll();
  162. m_type = PROP_NORMAL;
  163. if (SUCCEEDED(hr = InitQualSet()))
  164. {
  165. int iItem = 0;
  166. if (SUCCEEDED(hr = m_pQuals->BeginEnumeration(0)))
  167. {
  168. BSTR pName = NULL;
  169. _variant_t var;
  170. long lFlavor;
  171. BOOL bIgnoreQual = FALSE;
  172. while(1)
  173. {
  174. hr =
  175. m_pQuals->Next(
  176. 0,
  177. &pName,
  178. &var,
  179. &lFlavor);
  180. if (FAILED(hr) || hr == WBEM_S_NO_MORE_DATA)
  181. break;
  182. // We won't add every qual to our list when editing a property's
  183. // qualifiers.
  184. if (IsInPropMode())
  185. {
  186. bIgnoreQual = TRUE;
  187. if (!_wcsicmp(pName, L"key"))
  188. {
  189. if ((bool) var)
  190. m_type = PROP_KEY;
  191. }
  192. else if (!_wcsicmp(pName, L"indexed"))
  193. {
  194. if ((bool) var)
  195. m_type = PROP_INDEXED;
  196. }
  197. else if (!_wcsicmp(pName, L"not_null"))
  198. {
  199. if ((bool) var)
  200. m_type = PROP_NOT_NULL;
  201. }
  202. // Just skip this lame one.
  203. else if (!_wcsicmp(pName, L"CIMTYPE"))
  204. {
  205. }
  206. else
  207. bIgnoreQual = FALSE;
  208. }
  209. if (!bIgnoreQual)
  210. AddQualifier(_bstr_t(pName), &var, lFlavor);
  211. SysFreeString(pName);
  212. }
  213. }
  214. }
  215. UpdateButtons();
  216. CheckRadioButton(IDC_KEY, IDC_NORMAL, IDC_KEY + m_type);
  217. if (FAILED(hr))
  218. CWMITestDoc::DisplayWMIErrorBox(hr);
  219. }
  220. CIMTYPE CPropQualsPg::QualTypeToCIMTYPE(VARENUM vt)
  221. {
  222. CIMTYPE type;
  223. switch((long) vt & ~VT_ARRAY)
  224. {
  225. case VT_BSTR:
  226. type = CIM_STRING;
  227. break;
  228. case VT_BOOL:
  229. type = CIM_BOOLEAN;
  230. break;
  231. case VT_I4:
  232. type = CIM_SINT32;
  233. break;
  234. case VT_R8:
  235. type = CIM_REAL64;
  236. break;
  237. }
  238. if (vt & VT_ARRAY)
  239. type |= CIM_FLAG_ARRAY;
  240. return type;
  241. }
  242. BEGIN_MESSAGE_MAP(CPropQualsPg, CPropertyPage)
  243. //{{AFX_MSG_MAP(CPropQualsPg)
  244. ON_BN_CLICKED(IDC_ADD, OnAdd)
  245. ON_BN_CLICKED(IDC_EDIT, OnEdit)
  246. ON_BN_CLICKED(IDC_DELETE, OnDelete)
  247. ON_NOTIFY(NM_DBLCLK, IDC_QUALS, OnDblclkQuals)
  248. ON_NOTIFY(LVN_ITEMCHANGED, IDC_QUALS, OnItemchangedQuals)
  249. //}}AFX_MSG_MAP
  250. END_MESSAGE_MAP()
  251. /////////////////////////////////////////////////////////////////////////////
  252. // CPropQualsPg message handlers
  253. BOOL CPropQualsPg::OnInitDialog()
  254. {
  255. CPropertyPage::OnInitDialog();
  256. InitListCtrl();
  257. if (m_bIsInstance || m_mode == QMODE_METHOD)
  258. {
  259. const DWORD dwIDs[] =
  260. {
  261. IDC_KEY,
  262. IDC_INDEXED,
  263. IDC_NON_NULL,
  264. IDC_NORMAL,
  265. };
  266. for (int i = 0; i < sizeof(dwIDs) / sizeof(dwIDs[0]); i++)
  267. GetDlgItem(dwIDs[i])->EnableWindow(FALSE);
  268. }
  269. LoadQuals();
  270. return TRUE; // return TRUE unless you set the focus to a control
  271. // EXCEPTION: OCX Property Pages should return FALSE
  272. }
  273. #define DEF_FLAVOR (WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE | \
  274. WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS | \
  275. WBEM_FLAVOR_OVERRIDABLE | \
  276. WBEM_FLAVOR_NOT_AMENDED)
  277. void CPropQualsPg::OnAdd()
  278. {
  279. CEditQualDlg dlg;
  280. _variant_t var;
  281. dlg.m_propUtil.m_bNewProperty = TRUE;
  282. dlg.m_propUtil.m_bIsQualifier = TRUE;
  283. dlg.m_propUtil.m_pNamespace = g_pOpView->GetDocument()->m_pNamespace;
  284. dlg.m_bIsInstance = m_bIsInstance;
  285. dlg.m_propUtil.m_prop.SetType(CIM_STRING);
  286. dlg.m_propUtil.m_pVar = &var;
  287. dlg.m_lFlavor = DEF_FLAVOR;
  288. if (dlg.DoModal() == IDOK)
  289. {
  290. HRESULT hr;
  291. if (SUCCEEDED(hr =
  292. m_pQuals->Put(
  293. _bstr_t(dlg.m_propUtil.m_prop.m_strName),
  294. &var,
  295. m_bIsInstance ? 0 : dlg.m_lFlavor)))
  296. {
  297. AddQualifier(
  298. dlg.m_propUtil.m_prop.m_strName,
  299. &var,
  300. dlg.m_lFlavor);
  301. }
  302. else
  303. CWMITestDoc::DisplayWMIErrorBox(hr);
  304. }
  305. }
  306. void CPropQualsPg::OnEdit()
  307. {
  308. int iItem = m_ctlQuals.GetSelectionMark();
  309. if (iItem != -1)
  310. {
  311. CEditQualDlg dlg;
  312. CQual &qual = m_listQuals.GetAt(m_listQuals.FindIndex(iItem));
  313. _variant_t var = qual.m_var;
  314. dlg.m_propUtil.m_bNewProperty = FALSE;
  315. dlg.m_propUtil.m_bIsQualifier = TRUE;
  316. dlg.m_bIsInstance = m_bIsInstance;
  317. dlg.m_propUtil.m_prop.m_strName = qual.m_strName;
  318. dlg.m_propUtil.m_prop.SetType(QualTypeToCIMTYPE((VARENUM) qual.m_var.vt));
  319. dlg.m_propUtil.m_pVar = &var;
  320. dlg.m_lFlavor = qual.m_lFlavor;
  321. if (dlg.DoModal() == IDOK)
  322. {
  323. CString strValue;
  324. HRESULT hr;
  325. if (SUCCEEDED(hr =
  326. m_pQuals->Put(
  327. _bstr_t(qual.m_strName),
  328. &var,
  329. m_bIsInstance ? 0 : dlg.m_lFlavor)))
  330. {
  331. qual.m_lFlavor = dlg.m_lFlavor;
  332. qual.m_var = var;
  333. dlg.m_propUtil.m_prop.VariantToString(&qual.m_var, strValue, TRUE);
  334. m_ctlQuals.SetItemText(iItem, 2, strValue);
  335. }
  336. else
  337. CWMITestDoc::DisplayWMIErrorBox(hr);
  338. }
  339. }
  340. }
  341. void CPropQualsPg::OnDelete()
  342. {
  343. int iItem = m_ctlQuals.GetSelectionMark();
  344. if (iItem != -1)
  345. {
  346. CQual qual = m_listQuals.GetAt(m_listQuals.FindIndex(iItem));
  347. HRESULT hr;
  348. if (SUCCEEDED(hr =
  349. m_pQuals->Delete(_bstr_t(qual.m_strName))))
  350. {
  351. m_ctlQuals.DeleteItem(iItem);
  352. m_listQuals.RemoveAt(m_listQuals.FindIndex(iItem));
  353. // Save this so we can delete it later.
  354. //m_listQualsToDelete.AddTail(qual);
  355. int nItems = m_ctlQuals.GetItemCount();
  356. if (iItem >= nItems)
  357. iItem--;
  358. if (iItem >= 0)
  359. m_ctlQuals.SetItemState(iItem, LVIS_SELECTED, LVIS_SELECTED);
  360. }
  361. else
  362. CWMITestDoc::DisplayWMIErrorBox(hr);
  363. }
  364. }
  365. void CPropQualsPg::UpdateButtons()
  366. {
  367. int iIndex = GetSelectedItem();
  368. GetDlgItem(IDC_DELETE)->EnableWindow(iIndex != -1);
  369. GetDlgItem(IDC_EDIT)->EnableWindow(iIndex != -1);
  370. }
  371. void CPropQualsPg::AddQualifier(LPCTSTR szName, VARIANT *pVar, long lFlavor)
  372. {
  373. CQual qual;
  374. qual.m_strName = szName;
  375. qual.m_var = *pVar;
  376. qual.m_lFlavor = lFlavor;
  377. m_listQuals.AddTail(qual);
  378. CPropInfo prop;
  379. int iImage,
  380. iItem = m_ctlQuals.GetItemCount();
  381. CIMTYPE type = QualTypeToCIMTYPE((VARENUM) pVar->vt);
  382. CString strType,
  383. strValue;
  384. prop.SetType(type);
  385. prop.GetPropType(strType, &iImage);
  386. prop.VariantToString(&qual.m_var, strValue, TRUE);
  387. m_ctlQuals.InsertItem(iItem, qual.m_strName, iImage);
  388. m_ctlQuals.SetItemText(iItem, 1, strType);
  389. m_ctlQuals.SetItemText(iItem, 2, strValue);
  390. }
  391. int CPropQualsPg::GetSelectedItem()
  392. {
  393. POSITION pos = m_ctlQuals.GetFirstSelectedItemPosition();
  394. if (pos)
  395. return m_ctlQuals.GetNextSelectedItem(pos);
  396. else
  397. return -1;
  398. }
  399. void CPropQualsPg::OnDblclkQuals(NMHDR* pNMHDR, LRESULT* pResult)
  400. {
  401. OnEdit();
  402. *pResult = 0;
  403. }
  404. void CPropQualsPg::OnItemchangedQuals(NMHDR* pNMHDR, LRESULT* pResult)
  405. {
  406. //NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  407. UpdateButtons();
  408. *pResult = 0;
  409. }