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.

1203 lines
29 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. // PropUtil.cpp: implementation of the CPropUtil class.
  8. //
  9. //////////////////////////////////////////////////////////////////////
  10. #include "stdafx.h"
  11. #include "wmitest.h"
  12. #include "GetTextDlg.h"
  13. #include "OpWrap.h"
  14. #include "PropUtil.h"
  15. #include "WMITestDoc.h"
  16. #include "OpView.h"
  17. #include "ArrayItemDlg.h"
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char THIS_FILE[]=__FILE__;
  21. #define new DEBUG_NEW
  22. #endif
  23. //////////////////////////////////////////////////////////////////////
  24. // Construction/Destruction
  25. //////////////////////////////////////////////////////////////////////
  26. CPropUtil::CPropUtil() :
  27. m_bTranslate(TRUE),
  28. m_bNewProperty(FALSE),
  29. m_bIsQualifier(FALSE),
  30. m_pNamespace(NULL),
  31. m_bOnInitDialog(FALSE)
  32. {
  33. }
  34. CPropUtil::~CPropUtil()
  35. {
  36. }
  37. void ArrayValuesToList(HWND hwnd, CPropInfo *pProp, VARIANT *pVar,
  38. BOOL bTranslate)
  39. {
  40. SendMessage(hwnd, LB_RESETCONTENT, 0, 0);
  41. if (pVar->vt != VT_NULL)
  42. {
  43. int nItems = pProp->GetArrayItemCount(pVar);
  44. BOOL bIsBitmask = pProp->IsBitmask() && bTranslate,
  45. bObjEdit = (pVar->vt & ~VT_ARRAY) == VT_UNKNOWN;
  46. for (int i = 0; i < nItems; i++)
  47. {
  48. CString strItem;
  49. int iIndex;
  50. pProp->ArrayItemToString(pVar, i, strItem, bTranslate);
  51. iIndex = SendMessage(hwnd, LB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strItem);
  52. if (bIsBitmask || bObjEdit)
  53. {
  54. DWORD dwItem = pProp->GetArrayItem(pVar, i);
  55. SendMessage(hwnd, LB_SETITEMDATA, iIndex, dwItem);
  56. if (bObjEdit)
  57. ((IUnknown*) dwItem)->AddRef();
  58. }
  59. }
  60. }
  61. }
  62. void ListToArrayValues(HWND hwnd, CPropInfo *pProp, VARIANT *pVar,
  63. BOOL bTranslate)
  64. {
  65. int nItems = SendMessage(hwnd, LB_GETCOUNT, 0, 0);
  66. BOOL bUseData = (pProp->IsBitmask() && bTranslate) ||
  67. pProp->GetRawType() == VT_UNKNOWN;
  68. pProp->PrepArrayVar(pVar, nItems);
  69. for (int i = 0; i < nItems; i++)
  70. {
  71. TCHAR szItem[1024] = _T("");
  72. if (!bUseData)
  73. {
  74. SendMessage(hwnd, LB_GETTEXT, i, (LPARAM) szItem);
  75. pProp->StringToArrayItem(szItem, pVar, i, bTranslate);
  76. }
  77. else
  78. {
  79. DWORD dwValue = SendMessage(hwnd, LB_GETITEMDATA, i, 0);
  80. pProp->SetArrayItem(pVar, i, dwValue);
  81. }
  82. }
  83. }
  84. void ValuemapValuesToCombo(HWND hwnd, CPropInfo *pProp, LPCTSTR szDefault)
  85. {
  86. SendMessage(hwnd, CB_RESETCONTENT, 0, 0);
  87. if (pProp->GetRawType() != CIM_BOOLEAN)
  88. {
  89. POSITION pos = pProp->m_mapValues.GetStartPosition();
  90. while(pos)
  91. {
  92. CString strKey,
  93. strValue;
  94. pProp->m_mapValues.GetNextAssoc(pos, strKey, strValue);
  95. SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strValue);
  96. }
  97. }
  98. else
  99. {
  100. CString strTemp;
  101. strTemp.LoadString(IDS_FALSE);
  102. SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strTemp);
  103. strTemp.LoadString(IDS_TRUE);
  104. SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM) (LPCTSTR) strTemp);
  105. }
  106. // Try to select the default.
  107. if (SendMessage(hwnd, CB_SELECTSTRING, 0, (LPARAM) szDefault) == CB_ERR)
  108. {
  109. DWORD dwStyle = GetWindowLong(hwnd, GWL_STYLE);
  110. // If that didn't work...
  111. if ((dwStyle & CBS_DROPDOWNLIST) == CBS_DROPDOWNLIST || !*szDefault)
  112. // If we're a drop down list, choose the first item.
  113. SendMessage(hwnd, CB_SETCURSEL, 0, 0);
  114. else
  115. // If we're a drop down, set the window text.
  116. SetWindowText(hwnd, szDefault);
  117. }
  118. }
  119. void BitmaskValuesToCheckListbox(CCheckListBox &ctlListbox, CPropInfo *pProp,
  120. DWORD dwDefValue)
  121. {
  122. int nValues = pProp->m_bitmaskValues.GetSize();
  123. ctlListbox.ResetContent();
  124. for (int i = 0; i < nValues; i++)
  125. {
  126. DWORD dwValue = pProp->m_bitmaskValues[i].m_dwBitmaskValue;
  127. int nIndex;
  128. nIndex = ctlListbox.AddString(pProp->m_bitmaskValues[i].m_strName);
  129. ctlListbox.SetItemData(nIndex, dwValue);
  130. if (dwDefValue & dwValue)
  131. ctlListbox.SetCheck(nIndex, TRUE);
  132. }
  133. }
  134. void BitmaskValueToCheckListbox(CCheckListBox &ctlListbox, DWORD dwValue)
  135. {
  136. int nValues = ctlListbox.GetCount();
  137. for (int i = 0; i < nValues; i++)
  138. {
  139. DWORD dwItemValue = ctlListbox.GetItemData(i);
  140. ctlListbox.SetCheck(i, (dwItemValue & dwValue) != 0);
  141. }
  142. }
  143. void CheckListboxToBitmaskValue(CCheckListBox &ctlListBox, DWORD *pdwValue)
  144. {
  145. int nItems = ctlListBox.GetCount();
  146. *pdwValue = 0;
  147. for (int i = 0; i < nItems; i++)
  148. {
  149. if (ctlListBox.GetCheck(i))
  150. *pdwValue |= ctlListBox.GetItemData(i);
  151. }
  152. }
  153. void CPropUtil::Init(CWnd *pWnd)
  154. {
  155. m_pWnd = pWnd;
  156. m_spropUtil.Init(pWnd);
  157. m_spropUtil.m_pVar = m_pVar;
  158. m_spropUtil.m_prop = m_prop;
  159. m_spropUtil.m_bTranslate = m_bTranslate;
  160. m_spropUtil.m_bNewProperty = m_bNewProperty;
  161. }
  162. CIMTYPE CPropUtil::GetCurrentType()
  163. {
  164. int iIndex = m_ctlTypes.GetCurSel();
  165. return (CIMTYPE) m_ctlTypes.GetItemData(iIndex);
  166. }
  167. void CPropUtil::DoDataExchange(CDataExchange* pDX)
  168. {
  169. DDX_Control(pDX, IDC_TYPE, m_ctlTypes);
  170. DDX_Control(pDX, IDC_ARRAY_VALUES, m_ctlArrayValues);
  171. //DDX_Control(pDX, IDC_BITMASK_ARRAY, m_ctlBitmaskValues);
  172. //DDX_Control(pDX, IDC_VALUE_LIST, m_ctlListValues);
  173. BOOL bNull = m_pVar->vt == VT_NULL,
  174. bArray = m_prop.IsArray();
  175. // Setup lots of stuff if we're entering the dialog.
  176. if (!pDX->m_bSaveAndValidate)
  177. {
  178. CString strValue,
  179. strType;
  180. BOOL bIsBool = m_prop.GetRawCIMType() == CIM_BOOLEAN;
  181. m_spropUtil.DoDataExchange(pDX);
  182. // Set the property name
  183. m_pWnd->SetDlgItemText(IDC_NAME, m_prop.m_strName);
  184. // Init the type combo box.
  185. InitTypeCombo();
  186. if (!m_bNewProperty)
  187. {
  188. m_pWnd->GetDlgItem(IDC_TYPE)->EnableWindow(FALSE);
  189. m_pWnd->GetDlgItem(IDC_ARRAY)->EnableWindow(FALSE);
  190. ((CEdit*) m_pWnd->GetDlgItem(IDC_NAME))->SetReadOnly(TRUE);
  191. }
  192. // Set the NULL checkbox.
  193. m_pWnd->CheckDlgButton(IDC_NULL, bNull);
  194. m_pWnd->CheckDlgButton(IDC_ARRAY, bArray);
  195. // This will simulate the array button getting checked so our
  196. // controls get hidden or shown.
  197. OnArray();
  198. // Add the array strings.
  199. if (bArray)
  200. {
  201. ArrayValuesToList(m_ctlArrayValues.m_hWnd, &m_prop, m_pVar,
  202. m_bTranslate);
  203. UpdateArrayButtons();
  204. }
  205. // This will simulate the null button getting checked so our
  206. // controls get enabled/disabled.
  207. OnNull();
  208. }
  209. else // Time to put the data back into the variant.
  210. {
  211. BOOL bArray = m_pWnd->IsDlgButtonChecked(IDC_ARRAY),
  212. bEmbeddedObject = GetCurrentType() == CIM_OBJECT;
  213. if (m_bNewProperty)
  214. {
  215. CIMTYPE type = GetCurrentType();
  216. m_pWnd->GetDlgItemText(IDC_NAME, m_prop.m_strName);
  217. if (bArray)
  218. type |= CIM_FLAG_ARRAY;
  219. m_prop.SetType(type);
  220. }
  221. if (m_pWnd->IsDlgButtonChecked(IDC_NULL))
  222. {
  223. VariantClear(m_pVar);
  224. m_pVar->vt = VT_NULL;
  225. }
  226. else
  227. {
  228. if (bArray)
  229. ListToArrayValues(m_ctlArrayValues.m_hWnd, &m_prop,
  230. m_pVar, m_bTranslate);
  231. else
  232. m_spropUtil.DoDataExchange(pDX);
  233. }
  234. }
  235. }
  236. /////////////////////////////////////////////////////////////////////////////
  237. // CPropUtil message handlers
  238. void CPropUtil::UpdateArrayButtons()
  239. {
  240. BOOL bIsNull = m_pWnd->IsDlgButtonChecked(IDC_NULL);
  241. if (!bIsNull)
  242. {
  243. int iWhere = m_ctlArrayValues.GetCurSel(),
  244. nItems = m_ctlArrayValues.GetCount();
  245. m_pWnd->GetDlgItem(IDC_UP)->EnableWindow(iWhere > 0);
  246. m_pWnd->GetDlgItem(IDC_DOWN)->EnableWindow(iWhere != -1 && iWhere != nItems - 1);
  247. m_pWnd->GetDlgItem(IDC_DELETE)->EnableWindow(iWhere != -1);
  248. m_pWnd->GetDlgItem(IDC_EDIT)->EnableWindow(iWhere != -1);
  249. }
  250. }
  251. void CPropUtil::OnNull()
  252. {
  253. BOOL bIsNull = m_pWnd->IsDlgButtonChecked(IDC_NULL);
  254. const DWORD dwToEnable[] =
  255. {
  256. IDC_ARRAY_VALUES,
  257. IDC_ADD,
  258. IDC_EDIT,
  259. IDC_DELETE,
  260. IDC_UP,
  261. IDC_DOWN,
  262. };
  263. for (int i = 0; i < sizeof(dwToEnable) / sizeof(DWORD); i++)
  264. m_pWnd->GetDlgItem(dwToEnable[i])->EnableWindow(!bIsNull);
  265. m_spropUtil.EnableControls(!bIsNull);
  266. UpdateArrayButtons();
  267. }
  268. void CPropUtil::OnAdd()
  269. {
  270. Modify(FALSE);
  271. }
  272. void CPropUtil::OnEdit()
  273. {
  274. int iWhich = m_ctlArrayValues.GetCurSel();
  275. Modify(iWhich != -1);
  276. }
  277. void CPropUtil::Modify(BOOL bEdit)
  278. {
  279. if (GetCurrentType() == CIM_OBJECT)
  280. {
  281. int iItem = m_ctlArrayValues.GetCurSel();
  282. if (bEdit)
  283. {
  284. IUnknown *pUnk = (IUnknown*) m_ctlArrayValues.GetItemData(iItem);
  285. CSinglePropUtil::EditObj(pUnk);
  286. }
  287. else
  288. {
  289. // Not a smart pointer because we'll release it later.
  290. IUnknown *pUnk = NULL;
  291. if (CSinglePropUtil::GetNewObj(&pUnk))
  292. {
  293. CString strText;
  294. CSinglePropUtil::EditObj(pUnk);
  295. //strText.Format(IDS_EMBEDDED_OBJECT, (IUnknown*) pUnk);
  296. strText = GetEmbeddedObjectText(pUnk);
  297. iItem = m_ctlArrayValues.InsertString(iItem, strText);
  298. m_ctlArrayValues.SetItemData(iItem, (DWORD_PTR) pUnk);
  299. }
  300. }
  301. return;
  302. }
  303. DWORD dwData = 0;
  304. CArrayItemDlg dlg;
  305. _variant_t var;
  306. dlg.m_spropUtil.m_bNewProperty = !bEdit;
  307. dlg.m_spropUtil.m_bTranslate = m_bTranslate;
  308. dlg.m_spropUtil.m_pVar = &var;
  309. if (!m_bNewProperty)
  310. dlg.m_spropUtil.m_prop = m_prop;
  311. else
  312. dlg.m_spropUtil.m_prop.SetType(GetCurrentType());
  313. if (bEdit)
  314. {
  315. int iItem = m_ctlArrayValues.GetCurSel();
  316. BOOL bIsBitmap = m_prop.IsBitmask() && m_bTranslate;
  317. if (bIsBitmap)
  318. {
  319. var = (long) m_ctlArrayValues.GetItemData(iItem);
  320. var.vt = m_prop.GetRawType();
  321. }
  322. else
  323. {
  324. CString strValue;
  325. BOOL bIsObjEdit = GetCurrentType() == CIM_OBJECT;
  326. if (!bIsObjEdit)
  327. {
  328. m_ctlArrayValues.GetText(iItem, strValue);
  329. dlg.m_spropUtil.m_prop.StringToVariant(strValue, &var, m_bTranslate);
  330. }
  331. else
  332. {
  333. var.vt = VT_UNKNOWN;
  334. var.punkVal = (IUnknown*) m_ctlArrayValues.GetItemData(iItem);
  335. // So var doesn't nuke us when it goes away.
  336. var.punkVal->AddRef();
  337. }
  338. }
  339. }
  340. if (dlg.DoModal() != IDOK)
  341. return;
  342. int iNewIndex;
  343. if (!bEdit)
  344. {
  345. if (!m_ctlArrayValues.GetCount())
  346. iNewIndex = 0;
  347. else
  348. {
  349. iNewIndex = m_ctlArrayValues.GetCurSel() + 1;
  350. if (iNewIndex == 0)
  351. iNewIndex = m_ctlArrayValues.GetCount();
  352. }
  353. }
  354. else
  355. {
  356. iNewIndex = m_ctlArrayValues.GetCurSel();
  357. m_ctlArrayValues.DeleteString(iNewIndex);
  358. }
  359. CString strValue;
  360. m_prop.VariantToString(&var, strValue, m_bTranslate);
  361. m_ctlArrayValues.InsertString(iNewIndex, strValue);
  362. m_ctlArrayValues.SetCurSel(iNewIndex);
  363. // This also works if var is VT_IUNKNOWN.
  364. m_ctlArrayValues.SetItemData(iNewIndex, var.iVal);
  365. UpdateArrayButtons();
  366. }
  367. void CPropUtil::OnDelete()
  368. {
  369. int iWhere = m_ctlArrayValues.GetCurSel();
  370. if (iWhere != -1)
  371. {
  372. if (IsObjEdit())
  373. {
  374. IUnknown *pUnk = (IUnknown *) m_ctlArrayValues.GetItemData(iWhere);
  375. pUnk->Release();
  376. }
  377. m_ctlArrayValues.DeleteString(iWhere);
  378. if (iWhere >= m_ctlArrayValues.GetCount())
  379. iWhere = m_ctlArrayValues.GetCount() - 1;
  380. m_ctlArrayValues.SetCurSel(iWhere);
  381. UpdateArrayButtons();
  382. }
  383. }
  384. void CPropUtil::OnUp()
  385. {
  386. int iWhere = m_ctlArrayValues.GetCurSel();
  387. if (iWhere > 0)
  388. {
  389. CString strValue;
  390. DWORD dwVal;
  391. m_ctlArrayValues.GetText(iWhere, strValue);
  392. dwVal = m_ctlArrayValues.GetItemData(iWhere);
  393. m_ctlArrayValues.DeleteString(iWhere);
  394. iWhere--;
  395. m_ctlArrayValues.InsertString(iWhere, strValue);
  396. m_ctlArrayValues.SetItemData(iWhere, dwVal);
  397. m_ctlArrayValues.SetCurSel(iWhere);
  398. UpdateArrayButtons();
  399. }
  400. }
  401. void CPropUtil::OnDown()
  402. {
  403. int iWhere = m_ctlArrayValues.GetCurSel();
  404. if (iWhere != -1 && iWhere != m_ctlArrayValues.GetCount())
  405. {
  406. CString strValue;
  407. DWORD dwVal;
  408. m_ctlArrayValues.GetText(iWhere, strValue);
  409. dwVal = m_ctlArrayValues.GetItemData(iWhere);
  410. m_ctlArrayValues.DeleteString(iWhere);
  411. iWhere++;
  412. m_ctlArrayValues.InsertString(iWhere, strValue);
  413. m_ctlArrayValues.SetItemData(iWhere, dwVal);
  414. m_ctlArrayValues.SetCurSel(iWhere);
  415. UpdateArrayButtons();
  416. }
  417. }
  418. void CPropUtil::OnSelchangeValueArray()
  419. {
  420. UpdateArrayButtons();
  421. }
  422. void CPropUtil::OnSelchangeType()
  423. {
  424. if (!m_pWnd->IsDlgButtonChecked(IDC_ARRAY))
  425. {
  426. m_spropUtil.SetType(GetCurrentType());
  427. OnNull();
  428. }
  429. else
  430. {
  431. m_ctlArrayValues.ResetContent();
  432. UpdateArrayButtons();
  433. }
  434. }
  435. void CPropUtil::InitTypeCombo()
  436. {
  437. const DWORD dwIDs[] =
  438. {
  439. IDS_CIM_STRING,
  440. IDS_CIM_BOOLEAN,
  441. IDS_CIM_SINT32,
  442. IDS_CIM_REAL64,
  443. IDS_CIM_SINT8,
  444. IDS_CIM_UINT8,
  445. IDS_CIM_SINT16,
  446. IDS_CIM_UINT16,
  447. IDS_CIM_UINT32,
  448. IDS_CIM_SINT64,
  449. IDS_CIM_UINT64,
  450. IDS_CIM_REAL32,
  451. IDS_CIM_DATETIME,
  452. IDS_CIM_REFERENCE,
  453. IDS_CIM_CHAR16,
  454. IDS_CIM_OBJECT,
  455. };
  456. const CIMTYPE types[] =
  457. {
  458. CIM_STRING,
  459. CIM_BOOLEAN,
  460. CIM_SINT32,
  461. CIM_REAL64,
  462. CIM_SINT8,
  463. CIM_UINT8,
  464. CIM_SINT16,
  465. CIM_UINT16,
  466. CIM_UINT32,
  467. CIM_SINT64,
  468. CIM_UINT64,
  469. CIM_REAL32,
  470. CIM_DATETIME,
  471. CIM_REFERENCE,
  472. CIM_CHAR16,
  473. CIM_OBJECT,
  474. };
  475. CString strToSelect;
  476. CIMTYPE typeToSelect = m_prop.GetRawCIMType();
  477. int nItems = m_bIsQualifier ? 4 : sizeof(dwIDs) / sizeof(dwIDs[0]);
  478. for (int i = 0; i < nItems; i++)
  479. {
  480. CString strType;
  481. int iIndex;
  482. strType.LoadString(dwIDs[i]);
  483. iIndex = m_ctlTypes.AddString(strType);
  484. m_ctlTypes.SetItemData(iIndex, types[i]);
  485. if (types[i] == typeToSelect)
  486. strToSelect = strType;
  487. }
  488. // Select the type given in m_prop.
  489. if (m_ctlTypes.SelectString(-1, strToSelect) == -1)
  490. m_ctlTypes.SetCurSel(0);
  491. }
  492. void CPropUtil::ShowArrayControls(BOOL bVal)
  493. {
  494. const DWORD dwToEnable[] =
  495. {
  496. IDC_ARRAY_VALUES,
  497. IDC_ADD,
  498. IDC_EDIT,
  499. IDC_DELETE,
  500. IDC_UP,
  501. IDC_DOWN,
  502. };
  503. DWORD dwFlag = bVal ? SW_SHOW : SW_HIDE;
  504. for (int i = 0; i < sizeof(dwToEnable) / sizeof(DWORD); i++)
  505. m_pWnd->GetDlgItem(dwToEnable[i])->ShowWindow(dwFlag);
  506. if (bVal)
  507. UpdateArrayButtons();
  508. }
  509. void CPropUtil::OnArray()
  510. {
  511. BOOL bArray = m_pWnd->IsDlgButtonChecked(IDC_ARRAY);
  512. m_spropUtil.ShowControls(!bArray);
  513. ShowArrayControls(bArray);
  514. }
  515. BOOL CPropUtil::OnSetActive()
  516. {
  517. return TRUE;
  518. }
  519. BOOL CPropUtil::OnInitDialog()
  520. {
  521. // This is a total pain!!! I tried putting this in WM_INIT_DIALOG and
  522. // DoDataExchange but neither one worked.
  523. MoveArrayButtons();
  524. BOOL bRet = m_spropUtil.OnInitDialog();
  525. return bRet;
  526. }
  527. void CPropUtil::OnEditEmbedded()
  528. {
  529. m_spropUtil.OnEditEmbedded();
  530. }
  531. void CPropUtil::OnClearEmbedded()
  532. {
  533. m_spropUtil.OnClearEmbedded();
  534. }
  535. void CPropUtil::OnDblclkArrayValues()
  536. {
  537. OnEdit();
  538. }
  539. void CPropUtil::MoveArrayButtons()
  540. {
  541. RECT rectEdit,
  542. rectAdd;
  543. CWnd *pwndAdd = m_pWnd->GetDlgItem(IDC_ADD),
  544. *pwndEdit = m_pWnd->GetDlgItem(IDC_BITMASK_ARRAY),
  545. *pwndParent = pwndAdd->GetParent();
  546. int dx,
  547. dy;
  548. pwndEdit->GetClientRect(&rectEdit);
  549. pwndEdit->MapWindowPoints(pwndParent, &rectEdit);
  550. pwndAdd->GetClientRect(&rectAdd);
  551. pwndAdd->MapWindowPoints(pwndParent, &rectAdd);
  552. // Why this 2 business? Because it seems to make the movement more
  553. // accurate.
  554. dx = rectEdit.left - rectAdd.left - 2;
  555. dy = rectEdit.top - rectAdd.top - 2;
  556. const DWORD dwToMove[] =
  557. {
  558. IDC_ARRAY_VALUES,
  559. IDC_ADD,
  560. IDC_EDIT,
  561. IDC_DELETE,
  562. IDC_UP,
  563. IDC_DOWN,
  564. };
  565. for (int i = 0; i < sizeof(dwToMove) / sizeof(DWORD); i++)
  566. {
  567. CWnd *pWnd = m_pWnd->GetDlgItem(dwToMove[i]);
  568. CRect rect;
  569. pWnd->GetClientRect(&rect);
  570. pWnd->MapWindowPoints(pwndParent, &rect);
  571. rect.OffsetRect(dx, dy);
  572. // The array values controls seems to need this. Why? I don't know.
  573. if (i == 0)
  574. rect.OffsetRect(-2, -2);
  575. pWnd->MoveWindow(&rect);
  576. pWnd->GetClientRect(&rect);
  577. pWnd->MapWindowPoints(pwndParent, &rect);
  578. }
  579. // Now make the array listbox the same size as the bitmask listbox.
  580. CWnd *pBitValues = m_pWnd->GetDlgItem(IDC_BITMASK_ARRAY),
  581. *pArrayValues = m_pWnd->GetDlgItem(IDC_ARRAY_VALUES);
  582. RECT rectBitValues,
  583. rectArrayValues;
  584. pBitValues->GetClientRect(&rectBitValues);
  585. pArrayValues->GetClientRect(&rectArrayValues);
  586. pArrayValues->SetWindowPos(
  587. NULL,
  588. 0, 0,
  589. // More screwy values to make the sizing correct.
  590. rectBitValues.right + 4, rectBitValues.bottom + 4,
  591. SWP_NOMOVE | SWP_NOZORDER);
  592. // Move the up and down buttons since we grew the array listbox.
  593. dx = rectBitValues.right - rectArrayValues.right - 2;
  594. dy = (rectBitValues.bottom - rectArrayValues.bottom) / 2;
  595. for (i = 0; i < 2; i++)
  596. {
  597. CWnd *pWnd = m_pWnd->GetDlgItem(i == 0 ? IDC_UP : IDC_DOWN);
  598. CRect rect;
  599. pWnd->GetClientRect(&rect);
  600. pWnd->MapWindowPoints(m_pWnd, &rect);
  601. rect.OffsetRect(dx, dy);
  602. pWnd->MoveWindow(&rect);
  603. }
  604. }
  605. /////////////////////////////////////////////////////////////////////////////
  606. // CSinglePropUtil
  607. void CSinglePropUtil::DoDataExchange(CDataExchange* pDX)
  608. {
  609. DDX_Control(pDX, IDC_VALUE_LIST, m_ctlListValues);
  610. DDX_Control(pDX, IDC_BITMASK_ARRAY, m_ctlBitmaskValues);
  611. DDX_Control(pDX, IDC_VALUE, m_ctlScalar);
  612. DDX_Control(pDX, IDC_VALUE_TEXT, m_ctlText);
  613. if (!pDX->m_bSaveAndValidate)
  614. {
  615. // This will set our data.
  616. SetType(m_prop.GetRawCIMType());
  617. }
  618. else
  619. {
  620. if (m_prop.GetRawCIMType() != CIM_OBJECT)
  621. {
  622. switch(m_type)
  623. {
  624. case TYPE_CHECKLISTBOX:
  625. m_pVar->vt = m_prop.GetRawType();
  626. CheckListboxToBitmaskValue(m_ctlBitmaskValues,
  627. (DWORD*) &V_I4(m_pVar));
  628. break;
  629. default:
  630. {
  631. CString strValue;
  632. m_pWnd->GetDlgItemText(m_dwScalarID, strValue);
  633. m_prop.StringToVariant(strValue, m_pVar, m_bTranslate);
  634. break;
  635. }
  636. }
  637. }
  638. else
  639. {
  640. VariantClear(m_pVar);
  641. m_pVar->vt = VT_NULL;
  642. if (m_pObjValue != NULL)
  643. {
  644. m_pVar->vt = VT_UNKNOWN;
  645. m_pVar->punkVal = m_pObjValue;
  646. m_pVar->punkVal->AddRef();
  647. }
  648. }
  649. }
  650. }
  651. void CSinglePropUtil::ShowControls(BOOL bShow)
  652. {
  653. DWORD dwFlag = bShow ? SW_SHOW : SW_HIDE;
  654. switch(m_type)
  655. {
  656. case TYPE_EDIT_SCALAR:
  657. m_ctlScalar.ShowWindow(dwFlag);
  658. //m_ctlScalar.EnableWindow(TRUE);
  659. break;
  660. case TYPE_EDIT_TEXT:
  661. m_ctlText.ShowWindow(dwFlag);
  662. //m_ctlText.EnableWindow(TRUE);
  663. break;
  664. case TYPE_CHECKLISTBOX:
  665. m_ctlBitmaskValues.ShowWindow(dwFlag);
  666. break;
  667. case TYPE_EDIT_OBJ:
  668. m_ctlScalar.ShowWindow(dwFlag);
  669. m_ctlScalar.EnableWindow(FALSE);
  670. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(dwFlag);
  671. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(dwFlag);
  672. break;
  673. case TYPE_DROPDOWN:
  674. case TYPE_DROPDOWNLIST:
  675. m_ctlListValues.ShowWindow(dwFlag);
  676. break;
  677. }
  678. }
  679. void CSinglePropUtil::EnableControls(BOOL bEnable)
  680. {
  681. const DWORD dwIDs[] =
  682. {
  683. IDC_VALUE_LIST,
  684. IDC_BITMASK_ARRAY,
  685. IDC_EDIT_OBJ,
  686. IDC_CLEAR,
  687. IDC_VALUE_TEXT,
  688. };
  689. for (int i = 0; i < sizeof(dwIDs) / sizeof(dwIDs[0]); i++)
  690. m_pWnd->GetDlgItem(dwIDs[i])->EnableWindow(bEnable);
  691. m_pWnd->GetDlgItem(IDC_VALUE)->EnableWindow(bEnable && m_type !=
  692. TYPE_EDIT_OBJ);
  693. }
  694. void CSinglePropUtil::SetType(CIMTYPE type)
  695. {
  696. BOOL bIsBool,
  697. bNull,
  698. bArray;
  699. CString strValue;
  700. m_prop.SetType(type);
  701. bIsBool = m_prop.GetRawCIMType() == CIM_BOOLEAN;
  702. bNull = m_pVar->vt == VT_NULL;
  703. bArray = (m_pVar->vt & VT_ARRAY) != 0;
  704. // Set the value.
  705. if (!bNull)
  706. m_prop.VariantToString(m_pVar, strValue, m_bTranslate);
  707. if (!m_bControlsInited)
  708. InitControls();
  709. // Get the type of operation we're dealing with.
  710. if (m_prop.IsBitmask() && m_bTranslate)
  711. {
  712. m_type = TYPE_CHECKLISTBOX;
  713. m_ctlBitmaskValues.ShowWindow(SW_SHOW);
  714. m_ctlListValues.ShowWindow(SW_HIDE);
  715. m_ctlScalar.ShowWindow(SW_HIDE);
  716. m_ctlText.ShowWindow(SW_HIDE);
  717. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(SW_HIDE);
  718. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(SW_HIDE);
  719. BitmaskValuesToCheckListbox(
  720. m_ctlBitmaskValues,
  721. &m_prop,
  722. bNull ? 0 : m_pVar->iVal);
  723. }
  724. else if ((m_prop.HasValuemap() && m_bTranslate) || bIsBool)
  725. {
  726. m_type = TYPE_DROPDOWN;
  727. m_ctlListValues.ShowWindow(SW_SHOW);
  728. m_ctlBitmaskValues.ShowWindow(SW_HIDE);
  729. m_ctlScalar.ShowWindow(SW_HIDE);
  730. m_ctlText.ShowWindow(SW_HIDE);
  731. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(SW_HIDE);
  732. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(SW_HIDE);
  733. ValuemapValuesToCombo(m_ctlListValues.m_hWnd, &m_prop, strValue);
  734. m_dwScalarID = IDC_VALUE_LIST;
  735. }
  736. else
  737. {
  738. BOOL bMultiLine = type == CIM_STRING;
  739. CWnd *pwndValue = m_pWnd->GetDlgItem(IDC_VALUE);
  740. //pwndValue->ShowWindow(SW_SHOW);
  741. /*
  742. if (bMultiLine)
  743. {
  744. pwndValue->DestroyWindow();
  745. CreateWindowEx(
  746. 0x204, // From Spy++.
  747. _T("Edit"),
  748. NULL,
  749. ES_WANTRETURN | ES_MULTILINE | ES_LEFT |
  750. WS_VSCROLL | WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP,
  751. m_rectText.left,
  752. m_rectText.top,
  753. m_rectText.Width(),
  754. m_rectText.Height(),
  755. m_pWnd->m_hWnd,
  756. (HMENU) IDC_VALUE,
  757. NULL,
  758. NULL);
  759. //pwndValue->ModifyStyle(ES_AUTOHSCROLL, );
  760. //pwndValue->MoveWindow(&m_rectText, TRUE);
  761. }
  762. else
  763. {
  764. pwndValue->DestroyWindow();
  765. CreateWindowEx(
  766. 0x204, // From Spy++.
  767. _T("Edit"),
  768. NULL,
  769. ES_AUTOHSCROLL | ES_LEFT |
  770. WS_CHILDWINDOW | WS_VISIBLE | WS_TABSTOP,
  771. m_rectScalar.left,
  772. m_rectScalar.top,
  773. m_rectScalar.Width(),
  774. m_rectScalar.Height(),
  775. m_pWnd->m_hWnd,
  776. (HMENU) IDC_VALUE,
  777. NULL,
  778. NULL);
  779. //pwndValue->ModifyStyle(ES_WANTRETURN | ES_MULTILINE | WS_VSCROLL, ES_AUTOHSCROLL);
  780. //pwndValue->MoveWindow(&m_rectScalar);
  781. }
  782. pwndValue = m_pWnd->GetDlgItem(IDC_VALUE);
  783. pwndValue->UpdateWindow();
  784. pwndValue->ShowWindow(SW_SHOW);
  785. pwndValue->SetFont(m_pWnd->GetFont());
  786. */
  787. m_ctlListValues.ShowWindow(SW_HIDE);
  788. m_ctlBitmaskValues.ShowWindow(SW_HIDE);
  789. if (bMultiLine)
  790. {
  791. m_ctlScalar.ShowWindow(SW_HIDE);
  792. m_ctlText.ShowWindow(SW_SHOW);
  793. m_ctlText.EnableWindow(TRUE);
  794. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(SW_HIDE);
  795. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(SW_HIDE);
  796. m_dwScalarID = IDC_VALUE_TEXT;
  797. m_type = TYPE_EDIT_TEXT;
  798. }
  799. else
  800. {
  801. m_ctlText.ShowWindow(SW_HIDE);
  802. m_ctlScalar.ShowWindow(SW_SHOW);
  803. m_dwScalarID = IDC_VALUE;
  804. if (type == VT_UNKNOWN)
  805. {
  806. m_type = TYPE_EDIT_OBJ;
  807. m_pWnd->GetDlgItem(IDC_VALUE)->EnableWindow(FALSE);
  808. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(SW_SHOW);
  809. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(SW_SHOW);
  810. if (!bArray)
  811. {
  812. if (m_pVar->vt == VT_UNKNOWN)
  813. m_pObjValue = m_pVar->punkVal;
  814. else
  815. m_pObjValue = NULL;
  816. VariantClear(m_pVar);
  817. m_pVar->vt = VT_NULL;
  818. }
  819. }
  820. else
  821. {
  822. m_type = TYPE_EDIT_SCALAR;
  823. m_pWnd->GetDlgItem(IDC_VALUE)->EnableWindow(TRUE);
  824. m_pWnd->GetDlgItem(IDC_EDIT_OBJ)->ShowWindow(SW_HIDE);
  825. m_pWnd->GetDlgItem(IDC_CLEAR)->ShowWindow(SW_HIDE);
  826. }
  827. }
  828. m_pWnd->SetDlgItemText(m_dwScalarID, strValue);
  829. }
  830. }
  831. void CSinglePropUtil::InitControls()
  832. {
  833. if (m_bControlsInited)
  834. return;
  835. m_bControlsInited = TRUE;
  836. // Move the combo box into place.
  837. #define DROPDOWNLISTBOX_INCREASE 100
  838. // Get a bunch of vars the next group of code will use to
  839. // resize the dialog, create controls, etc.
  840. CWnd *pwndEdit = m_pWnd->GetDlgItem(IDC_VALUE),
  841. *pwndBitmask = m_pWnd->GetDlgItem(IDC_BITMASK_ARRAY);
  842. // Save this for single-line text editing.
  843. pwndEdit->GetClientRect(&m_rectScalar);
  844. pwndEdit->MapWindowPoints(m_pWnd, &m_rectScalar);
  845. // Save this for multi-line text editing.
  846. pwndBitmask->GetClientRect(&m_rectText);
  847. pwndBitmask->MapWindowPoints(m_pWnd, &m_rectText);
  848. m_rectScalar.InflateRect(2, 2);
  849. m_rectText.InflateRect(2, 2);
  850. m_ctlText.MoveWindow(&m_rectText);
  851. RECT rectDropdown = m_rectScalar;
  852. // Adjust the position of the translation since the edit control
  853. // doesn't seem to tell us exactly where it is.
  854. //rectDropdown.left -= 2;
  855. //rectDropdown.top -= 2;
  856. //rectDropdown.right += 2;
  857. // Make bigger for the dropdown list.
  858. rectDropdown.bottom += DROPDOWNLISTBOX_INCREASE;
  859. m_ctlListValues.MoveWindow(&rectDropdown);
  860. }
  861. /////////////////////////////////////////////////////////////////////////////
  862. // CSinglePropUtil message handlers
  863. BOOL CSinglePropUtil::GetNewObj(IUnknown **ppUnk)
  864. {
  865. CGetTextDlg dlg;
  866. BOOL bRet = FALSE;
  867. dlg.m_dwPromptID = IDS_CREATE_OBJ_PROMPT;
  868. dlg.m_dwTitleID = IDS_CREATE_OBJ_TITLE;
  869. dlg.m_bAllowClassBrowse = TRUE;
  870. dlg.m_pNamespace = g_pOpView->GetDocument()->m_pNamespace;
  871. dlg.LoadListViaReg(_T("GetClassHistory"));
  872. if (dlg.DoModal() == IDOK)
  873. {
  874. HRESULT hr;
  875. IWbemClassObjectPtr pClass;
  876. // Get the superclass.
  877. hr =
  878. dlg.m_pNamespace->GetObject(
  879. _bstr_t(dlg.m_strText),
  880. WBEM_FLAG_USE_AMENDED_QUALIFIERS,
  881. NULL,
  882. &pClass,
  883. NULL);
  884. if (SUCCEEDED(hr))
  885. {
  886. IWbemClassObjectPtr pObj;
  887. hr =
  888. pClass->SpawnInstance(
  889. 0,
  890. &pObj);
  891. if (SUCCEEDED(hr))
  892. {
  893. pObj->QueryInterface(
  894. IID_IUnknown,
  895. (LPVOID*) ppUnk);
  896. bRet = TRUE;
  897. }
  898. }
  899. if (FAILED(hr))
  900. CWMITestDoc::DisplayWMIErrorBox(hr);
  901. }
  902. return bRet;
  903. }
  904. void CSinglePropUtil::OnEditEmbedded()
  905. {
  906. if (m_pObjValue == NULL)
  907. {
  908. if (GetNewObj(&m_pObjValue))
  909. {
  910. // Call this again since now we're setup OK.
  911. OnEditEmbedded();
  912. CString strText;
  913. //strText.Format(IDS_EMBEDDED_OBJECT, (IUnknown*) m_pObjValue);
  914. strText = GetEmbeddedObjectText(m_pObjValue);
  915. m_ctlScalar.SetWindowText(strText);
  916. }
  917. }
  918. else
  919. {
  920. EditObj(m_pObjValue);
  921. }
  922. }
  923. void CSinglePropUtil::EditObj(IUnknown *pUnk)
  924. {
  925. HRESULT hr;
  926. IWbemClassObjectPtr pObj;
  927. hr =
  928. pUnk->QueryInterface(
  929. IID_IWbemClassObject,
  930. (LPVOID*) &pObj);
  931. if (SUCCEEDED(hr))
  932. CWMITestDoc::EditGenericObject(IDS_EDIT_EMBEDDED_OBJ, pObj);
  933. else
  934. CWMITestDoc::DisplayWMIErrorBox(hr);
  935. }
  936. void CSinglePropUtil::OnClearEmbedded()
  937. {
  938. m_pObjValue = NULL;
  939. CString strNull;
  940. strNull.LoadString(IDS_NULL);
  941. m_ctlScalar.SetWindowText(strNull);
  942. }
  943. BOOL CSinglePropUtil::OnInitDialog()
  944. {
  945. InitControls();
  946. return TRUE;
  947. }