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.

882 lines
23 KiB

  1. // SysInfo.cpp : Objects for the main OLE interface to the snap-in result pane.
  2. //
  3. // Copyright (c) 1998-1999 Microsoft Corporation
  4. #include "StdAfx.h"
  5. // This hack is required because we may be building in an environment
  6. // which doesn't have a late enough version of rpcndr.h
  7. #if __RPCNDR_H_VERSION__ < 440
  8. #define __RPCNDR_H_VERSION__ 440
  9. #define MIDL_INTERFACE(x) interface
  10. #endif
  11. #ifndef __mmc_h__
  12. #include <mmc.h> // ..\..\..\public\sdk\inc
  13. #endif
  14. #include "DataObj.h"
  15. #include "SysInfo.h"
  16. #include "ViewObj.h"
  17. #include "CompData.h"
  18. #include "Toolset.h"
  19. #ifndef IDS_TASK_TITLE
  20. #include "Resource.h"
  21. #endif
  22. /*
  23. * CSystemInfo - Constructor just NULLs all pointers.
  24. *
  25. * History: a-jsari 9/1/97 Initial version
  26. */
  27. CSystemInfo::CSystemInfo()
  28. :m_pComponentData(NULL), m_pConsole(NULL), m_pToolbar(NULL), m_pMenuButton(NULL),
  29. m_pControlbar(NULL), m_pHeader(NULL), m_pResult(NULL), m_pImageResult(NULL),
  30. m_pConsoleVerb(NULL), m_pfLast(NULL), m_plistTools(NULL), m_pDisplayHelp(NULL),
  31. m_pConsole2(NULL), m_pLastRefreshedFolder(NULL), lparamRefreshIndicator(0xFFFFFFFE), lparamNoOCXIndicator(0xFFFFFFFD)
  32. {
  33. }
  34. /*
  35. * ~CSystemInfo - Destructor just makes sure all the pointers have been
  36. * properly released.
  37. *
  38. * History: a-jsari 9/1/97 Initial version
  39. */
  40. CSystemInfo::~CSystemInfo()
  41. {
  42. ASSERT(m_pToolbar == NULL);
  43. ASSERT(m_pMenuButton == NULL);
  44. ASSERT(m_pConsole == NULL);
  45. ASSERT(m_pConsoleVerb == NULL);
  46. ASSERT(m_pComponentData == NULL);
  47. ASSERT(m_pControlbar == NULL);
  48. ASSERT(m_pResult == NULL);
  49. ASSERT(m_pImageResult == NULL);
  50. ASSERT(m_pHeader == NULL);
  51. ASSERT(m_pDisplayHelp == NULL);
  52. if (m_plistTools)
  53. {
  54. delete m_plistTools;
  55. m_plistTools = NULL;
  56. }
  57. }
  58. /*
  59. * Initialize - Get all the required Interface pointers from pConsole.
  60. *
  61. * History: a-jsari 9/1/97 Initial version
  62. */
  63. STDMETHODIMP CSystemInfo::Initialize(LPCONSOLE lpConsole)
  64. {
  65. TRACE(_T("CSystemInfo::Initialize\n"));
  66. ASSERT(lpConsole != NULL);
  67. #ifdef _DEBUG
  68. m_bInitializedC = true;
  69. #endif // _DEBUG
  70. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  71. m_pConsole = lpConsole;
  72. m_pConsole->AddRef();
  73. #if 0
  74. LoadResources();
  75. #endif
  76. m_strRefreshMessage.LoadString(IDS_REFRESHING_MSG);
  77. m_strNoOCXMessage = CString(_T("")); // if we could add a string, this would be "OCX not available"
  78. HRESULT hr = m_pConsole->QueryInterface(IID_IHeaderCtrl,
  79. reinterpret_cast<void **>(&m_pHeader));
  80. ASSERT(hr == S_OK);
  81. if (SUCCEEDED(hr)) {
  82. hr = m_pConsole->SetHeader(m_pHeader);
  83. ASSERT(hr == S_OK);
  84. }
  85. hr = m_pConsole->QueryInterface(IID_IResultData,
  86. reinterpret_cast<void **>(&m_pResult));
  87. ASSERT(hr == S_OK);
  88. hr = m_pConsole->QueryResultImageList(&m_pImageResult);
  89. ASSERT(hr == S_OK);
  90. hr = m_pConsole->QueryConsoleVerb(&m_pConsoleVerb);
  91. ASSERT(hr == S_OK);
  92. hr = m_pConsole->QueryInterface(IID_IDisplayHelp, reinterpret_cast<void **>(&m_pDisplayHelp));
  93. ASSERT(hr == S_OK);
  94. hr = m_pConsole->QueryInterface(IID_IConsole2, reinterpret_cast<void **>(&m_pConsole2));
  95. ASSERT(hr == S_OK);
  96. return S_OK;
  97. }
  98. /*
  99. * Destroy - Releases all QI'd pointers.
  100. *
  101. * History: a-jsari 9/1/97 Initial version
  102. */
  103. STDMETHODIMP CSystemInfo::Destroy(
  104. #ifdef _DEBUG
  105. MMC_COOKIE cookie
  106. #else
  107. MMC_COOKIE
  108. #endif
  109. )
  110. {
  111. #ifdef _DEBUG
  112. TRACE(_T("CSystemInfo::Destroy(%lx)\n"), cookie);
  113. ASSERT(m_bInitializedC);
  114. #endif // _DEBUG
  115. LPCONSOLE pMMC = pConsole();
  116. if (pMMC != NULL) {
  117. pMMC->SetHeader(NULL);
  118. SAFE_RELEASE(m_pHeader);
  119. SAFE_RELEASE(m_pResult);
  120. SAFE_RELEASE(m_pImageResult);
  121. SAFE_RELEASE(m_pConsole);
  122. SAFE_RELEASE(m_pConsole2);
  123. SAFE_RELEASE(m_pComponentData);
  124. SAFE_RELEASE(m_pConsoleVerb);
  125. SAFE_RELEASE(m_pDisplayHelp);
  126. IUnknown * pUnknown;
  127. CString strKey;
  128. for (POSITION pos = m_mapCLSIDToIUnknown.GetStartPosition(); pos != NULL;)
  129. {
  130. m_mapCLSIDToIUnknown.GetNextAssoc(pos, strKey, (void * &) pUnknown);
  131. if (pUnknown)
  132. pUnknown->Release();
  133. }
  134. m_mapCLSIDToIUnknown.RemoveAll();
  135. }
  136. return S_OK;
  137. }
  138. /*
  139. * Compare - Compares two result data items for the sorting.
  140. *
  141. * History: a-jsari 11/28/97 Initial version.
  142. */
  143. STDMETHODIMP CSystemInfo::Compare(LRESULT, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int *pnResult)
  144. {
  145. CDatumObject *pdoA = reinterpret_cast<CDatumObject *>(cookieA);
  146. CDatumObject *pdoB = reinterpret_cast<CDatumObject *>(cookieB);
  147. CFolder *pCategory = pdoA->Parent();
  148. MSIColumnSortType stColumn;
  149. ASSERT(pCategory == pdoB->Parent());
  150. ASSERT(pCategory->GetType());
  151. VERIFY(reinterpret_cast<CListViewFolder *>(pCategory)->GetSortType((DWORD)*pnResult, stColumn));
  152. switch (stColumn) {
  153. case NOSORT:
  154. *pnResult = 0;
  155. break;
  156. case LEXICAL:
  157. {
  158. LPCWSTR szTextA = pdoA->GetTextItem(*pnResult);
  159. LPCWSTR szTextB = pdoB->GetTextItem(*pnResult);
  160. *pnResult = ::_wcsicmp(szTextA, szTextB);
  161. }
  162. break;
  163. case BYVALUE:
  164. {
  165. DWORD iSortA = pdoA->GetSortIndex(*pnResult);
  166. DWORD iSortB = pdoB->GetSortIndex(*pnResult);
  167. if (iSortA < iSortB) *pnResult = -1;
  168. else if (iSortA > iSortB) *pnResult = 1;
  169. else *pnResult = 0;
  170. }
  171. break;
  172. default:
  173. ASSERT(FALSE);
  174. break;
  175. }
  176. return S_OK;
  177. }
  178. /*
  179. * CompareObjects - Compares two data objects to see if they are the same
  180. * object.
  181. *
  182. * Return Codes:
  183. * E_POINTER - One (or both) of the pointers is invalid.
  184. * S_OK - Both objects are the same.
  185. * S_FALSE - The objects don't match.
  186. *
  187. * History: a-jsari 9/1/97 Stub version
  188. */
  189. STDMETHODIMP CSystemInfo::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
  190. {
  191. TRACE(_T("CSystemInfo::CompareObjects\n"));
  192. return CDataObject::CompareObjects(lpDataObjectA, lpDataObjectB);
  193. }
  194. /*
  195. * GetDisplayInfo - Set the MMC_CALLBACK information (currently only the
  196. * Display string) for the result pane item pResult.
  197. *
  198. * History: a-jsari 9/1/97 Stub version
  199. */
  200. STDMETHODIMP CSystemInfo::GetDisplayInfo(LPRESULTDATAITEM pResult)
  201. {
  202. #if 0
  203. TRACE(_T("CSystemInfo::GetDisplayInfo(%lx)\n"), reinterpret_cast<long>(pResult));
  204. #endif
  205. ASSERT(pResult != NULL);
  206. ASSERT(pResult->mask & RDI_STR);
  207. USES_CONVERSION;
  208. // If the lParam indicates that the data is currently refreshing, show the
  209. // appropriate message. Although we have to cast away the const-ness of the
  210. // string, returning it as a result shouldn't be changing it.
  211. if (pResult->lParam == lparamRefreshIndicator)
  212. {
  213. pResult->str = T2OLE((LPTSTR)(LPCTSTR)m_strRefreshMessage);
  214. return S_OK;
  215. }
  216. else if (pResult->lParam == lparamNoOCXIndicator)
  217. {
  218. pResult->str = T2OLE((LPTSTR)(LPCTSTR)m_strNoOCXMessage);
  219. return S_OK;
  220. }
  221. if (pResult->mask & RDI_STR)
  222. {
  223. CViewObject * pDisplayItem = reinterpret_cast<CViewObject *>(pResult->lParam);
  224. if (CViewObject::DATUM == pDisplayItem->GetType())
  225. {
  226. CSystemInfoScope * pSysScope = dynamic_cast<CSystemInfoScope *>(pComponentData());
  227. if (pSysScope && pSysScope->InRefresh())
  228. {
  229. pResult->str = W2OLE(_T(" "));
  230. return S_OK;
  231. }
  232. }
  233. LPWSTR szName = (LPWSTR)pDisplayItem->GetTextItem(pResult->nCol);
  234. ASSERT(szName);
  235. pResult->str = W2OLE(szName);
  236. // In extension mode pResult is really a ScopeItem,
  237. // thus the nImage value is potentially garbage and needs to be filled in.
  238. if (pResult->bScopeItem && ( pResult->mask & SDI_IMAGE))
  239. {
  240. if (pDisplayItem->GetType() == CViewObject::EXTENSION_ROOT)
  241. {
  242. pResult->nImage = 2; // computer icon
  243. }
  244. else
  245. {
  246. pResult->nImage = 0; // folder icon
  247. }
  248. }
  249. }
  250. return S_OK;
  251. }
  252. #if 0
  253. /*
  254. * QueryMultiSelectDataObject -
  255. *
  256. * History: a-jsari 9/1/97 Stub version
  257. */
  258. HRESULT CSystemInfo::QueryMultiSelectDataObject(MMC_COOKIE /* cookie */, DATA_OBJECT_TYPES,
  259. LPDATAOBJECT *ppDataObject)
  260. {
  261. // FIX: Roll this into the DataObject pointer.
  262. ASSERT(ppDataObject != NULL);
  263. if (ppDataObject == NULL) return E_POINTER;
  264. return E_NOTIMPL;
  265. }
  266. #endif
  267. /*
  268. * QueryDataObject - return a pointer to the data object represented by
  269. * cookie and type in ppDataObject.
  270. *
  271. * Return Codes:
  272. * E_POINTER - ppDataObject is invalid
  273. * S_OK - Successful completion.
  274. *
  275. * History: a-jsari 9/1/97 Initial version
  276. */
  277. STDMETHODIMP CSystemInfo::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  278. LPDATAOBJECT *ppDataObject)
  279. {
  280. TRACE(_T("CSystemInfo::QueryDataObject(%lx, %lx, DataObject)\n"), cookie, type);
  281. ASSERT(ppDataObject != NULL);
  282. if (ppDataObject == NULL) return E_POINTER;
  283. #if 0
  284. if (cookie == MMC_MULTI_SELECT_COOKIE)
  285. return QueryMultiSelectDataObject(cookie, type, ppDataObject);
  286. #else
  287. if (cookie == MMC_MULTI_SELECT_COOKIE)
  288. return E_NOTIMPL;
  289. #endif
  290. ASSERT(type == CCT_RESULT);
  291. ASSERT(pComponentData() != NULL);
  292. CSystemInfoScope *pScope = dynamic_cast<CSystemInfoScope*>(pComponentData());
  293. ASSERT(pScope != NULL);
  294. return CDataObject::CreateDataObject(cookie, type, pScope, ppDataObject);
  295. }
  296. /*
  297. * Notify - Handle all Microsoft Management Console notification events.
  298. *
  299. * History: a-jsari 9/1/97 Initial version
  300. */
  301. STDMETHODIMP CSystemInfo::Notify(LPDATAOBJECT pDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  302. {
  303. HRESULT hr = S_OK;
  304. TRACE(_T("CSystemInfo::Notify(%lx, %lx, %p, %p)\n"), pDataObject, event, arg, param);
  305. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  306. switch(event)
  307. {
  308. case MMCN_BTN_CLICK:
  309. switch(param) {
  310. case MMC_VERB_REFRESH:
  311. hr = OnRefresh(pDataObject);
  312. break;
  313. case MMC_VERB_PROPERTIES:
  314. hr = OnProperties(pDataObject);
  315. break;
  316. default:
  317. ASSERT(FALSE); // Unknown parameter
  318. break;
  319. }
  320. break;
  321. case MMCN_DBLCLICK:
  322. hr = OnDoubleClick(pDataObject);
  323. break;
  324. case MMCN_INITOCX:
  325. {
  326. CDataObject * pObject = GetInternalFromDataObject(pDataObject);
  327. if (pObject)
  328. {
  329. CSystemInfoScope * pScope = pObject->pComponentData();
  330. if (pScope)
  331. {
  332. CDataSource * pSource = pScope->pSource();
  333. if (pSource && pSource->GetType() == CDataSource::V410FILE)
  334. {
  335. CFolder * pFolder = pObject->Category();
  336. if (pFolder && pFolder->GetType() == CDataSource::OCX)
  337. {
  338. LPOLESTR lpCLSID;
  339. if (FAILED(StringFromCLSID((reinterpret_cast<COCXFolder *>(pFolder))->m_clsid, &lpCLSID)))
  340. break;
  341. CString strCLSID(lpCLSID);
  342. ((IUnknown *)param)->AddRef();
  343. m_mapCLSIDToIUnknown.SetAt(strCLSID, (CObject *) (IUnknown *)param);
  344. CoTaskMemFree(lpCLSID);
  345. }
  346. }
  347. }
  348. }
  349. }
  350. break;
  351. case MMCN_PROPERTY_CHANGE:
  352. if (msiLog.IsLogging())
  353. msiLog.WriteLog(CMSInfoLog::MENU, _T("MENU \"Properties\"\r\n"));
  354. hr = OnPropertyChange(pDataObject);
  355. break;
  356. case MMCN_VIEW_CHANGE:
  357. hr = OnUpdateView(arg);
  358. break;
  359. case MMCN_DESELECT_ALL:
  360. // CHECK: Make this correct.
  361. hr = OnSelect(pDataObject, TRUE);
  362. break;
  363. case MMCN_COLUMN_CLICK:
  364. OutputDebugString(_T("CSnapin::Notify -> MMCN_COLUMN_CLICK"));
  365. break;
  366. case MMCN_CONTEXTHELP:
  367. case MMCN_SNAPINHELP:
  368. {
  369. if (msiLog.IsLogging())
  370. msiLog.WriteLog(CMSInfoLog::MENU, _T("MENU \"Help\"\r\n"));
  371. CString strHelpFile;
  372. CString strHelpTopic;
  373. strHelpFile.LoadString(IDS_MSINFO_HELP_FILE);
  374. strHelpTopic.LoadString(IDS_MSINFO_HELP_TOPIC);
  375. CString strHelp = strHelpFile + CString(_T("::")) + strHelpTopic;
  376. LPOLESTR pHelp = reinterpret_cast<LPOLESTR>(CoTaskMemAlloc((strHelp.GetLength() + 1) * sizeof(wchar_t)));
  377. if (pHelp && m_pDisplayHelp)
  378. {
  379. USES_CONVERSION;
  380. wcscpy(pHelp, T2OLE((LPTSTR)(LPCTSTR)strHelp));
  381. hr = m_pDisplayHelp->ShowTopic(pHelp);
  382. }
  383. break;
  384. }
  385. case MMCN_SELECT:
  386. hr = OnSelect(pDataObject, arg);
  387. break;
  388. case MMCN_ADD_IMAGES:
  389. hr = OnAddImages(pDataObject, reinterpret_cast<LPIMAGELIST>(arg), param);
  390. break;
  391. case MMCN_SHOW:
  392. hr = OnShow(pDataObject, arg, param);
  393. break;
  394. case MMCN_ACTIVATE:
  395. hr = OnActivate(pDataObject, arg);
  396. break;
  397. case MMCN_REFRESH:
  398. if (msiLog.IsLogging())
  399. msiLog.WriteLog(CMSInfoLog::MENU, _T("MENU \"Refresh\"\r\n"));
  400. hr = OnRefresh(pDataObject);
  401. break;
  402. case MMCN_QUERY_PASTE:
  403. hr = S_OK;
  404. break;
  405. case MMCN_PRINT:
  406. if (msiLog.IsLogging())
  407. msiLog.WriteLog(CMSInfoLog::MENU, _T("MENU \"Print\"\r\n"));
  408. hr = OnPrint();
  409. break;
  410. #if 0
  411. case MMCN_LISTPAD:
  412. hr = OnListPad();
  413. break;
  414. #endif
  415. default:
  416. ASSERT(FALSE);
  417. hr = S_OK;
  418. break;
  419. }
  420. return hr;
  421. }
  422. /*
  423. * AddMenuItems - Add our menu items to the right-click context menu.
  424. *
  425. * History: a-jsari 9/1/97 Initial version
  426. */
  427. STDMETHODIMP CSystemInfo::AddMenuItems(LPDATAOBJECT lpDataObject, LPCONTEXTMENUCALLBACK pCallback,
  428. long *pInsertionAllowed)
  429. {
  430. LPEXTENDCONTEXTMENU pContextMenu = pExtendContextMenu();
  431. TRACE(_T("CSystemInfo::AddMenuItems(%lx, Callback, InsertionAllowed)\n"), lpDataObject);
  432. ASSERT(pContextMenu != NULL);
  433. return pContextMenu->AddMenuItems(lpDataObject, pCallback, pInsertionAllowed);
  434. }
  435. /*
  436. * Command - Process the exact same menu commands we process in the scope
  437. * pane.
  438. *
  439. * History: a-jsari 9/22/97 Initial version
  440. */
  441. STDMETHODIMP CSystemInfo::Command(long lCommandID, LPDATAOBJECT pDataObject)
  442. {
  443. LPEXTENDCONTEXTMENU pContextMenu = pExtendContextMenu();
  444. TRACE(_T("CSystemInfo::Command(%lx, %lx)\n"), lCommandID, pDataObject);
  445. ASSERT(pContextMenu != NULL);
  446. return pContextMenu->Command(lCommandID, pDataObject);
  447. }
  448. /*
  449. * EnableToolbar - Set the toolbar enabled flag to fEnable
  450. *
  451. * History: a-jsari 9/24/97 Initial version
  452. *
  453. * Note: Depends on the order of enum ToolbarButtonID
  454. */
  455. HRESULT CSystemInfo::EnableToolbar(BOOL fEnable)
  456. {
  457. HRESULT hr;
  458. LPTOOLBAR pToolbar = ptbItems();
  459. ASSERT(pToolbar != NULL);
  460. if (fEnable) {
  461. hr = m_pControlbar->Attach(TOOLBAR, pToolbar);
  462. // These return S_FALSE (Undocumented)
  463. ASSERT(SUCCEEDED(hr));
  464. if (FAILED(hr)) return hr;
  465. for (int i = IDM_TBB_FIND ; i <= IDM_TBB_REPORT ; ++i) {
  466. hr = pToolbar->SetButtonState(i, ENABLED, fEnable);
  467. if (FAILED(hr)) return hr;
  468. }
  469. }
  470. return S_OK;
  471. }
  472. /*
  473. * EnableSupportTools - Set the MenuButton enabled flag to fEnable
  474. *
  475. * History: a-jsari 9/24/97 Initial version
  476. */
  477. HRESULT CSystemInfo::EnableSupportTools(BOOL fEnable)
  478. {
  479. HRESULT hr = S_FALSE;
  480. LPMENUBUTTON pTools = pmnbSupportTools();
  481. ASSERT(pTools != NULL);
  482. if (fEnable) {
  483. hr = pControlbar()->Attach(MENUBUTTON, pTools);
  484. ASSERT(SUCCEEDED(hr));
  485. if (FAILED(hr)) return hr;
  486. hr = pTools->SetButtonState(IDM_SUPPORT, ENABLED, TRUE);
  487. ASSERT(hr == S_OK);
  488. if (FAILED(hr)) return hr;
  489. hr = pTools->SetButtonState(IDM_SUPPORT, HIDDEN, FALSE);
  490. ASSERT(hr == S_OK);
  491. }
  492. return hr;
  493. }
  494. /*
  495. * ControlbarNotify - Handle events for the Toolbar
  496. *
  497. * History: a-jsari 9/16/97 Stub version
  498. */
  499. STDMETHODIMP CSystemInfo::ControlbarNotify(MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  500. {
  501. TRACE(_T("CSystemInfo::ControlbarNotify(%lx, %ld, %ld)\n"), event, arg, param);
  502. switch(event) {
  503. case MMCN_BTN_CLICK:
  504. return OnButtonClick(reinterpret_cast<LPDATAOBJECT>(arg), param);
  505. break;
  506. case MMCN_DESELECT_ALL:
  507. case MMCN_SELECT:
  508. return OnControlbarSelect((event == MMCN_DESELECT_ALL), arg,
  509. reinterpret_cast<LPDATAOBJECT>(param));
  510. break;
  511. case MMCN_MENU_BTNCLICK:
  512. return OnMenuButtonClick(reinterpret_cast<LPDATAOBJECT *>(arg),
  513. reinterpret_cast<LPMENUBUTTONDATA>(param));
  514. break;
  515. default:
  516. // Unhandled event.
  517. ASSERT(FALSE);
  518. }
  519. return E_NOTIMPL;
  520. }
  521. /*
  522. * AddToolbarButtons - Load the order-dependent list of toolbar buttons into
  523. * CSystemInfoScope's m_pToolbar item.
  524. *
  525. * History: a-jsari 9/18/97
  526. *
  527. * Note: The TBTTIP and TBTEXT string table elements are order dependent!
  528. * If the order of these items changes, the ToolbarButtonID enum order
  529. * MUST be changed to match. The order matches the bitmaps in IDB_TOOLBAR,
  530. * and the indices of the IDS_ORDERED_TBTEXT and IDS_ORDERED_TBTTIP items
  531. * in the String Table.
  532. *
  533. * This module would require AFX_MANAGE_STATE, but it knows that its calling
  534. * function has already called it.
  535. */
  536. HRESULT CSystemInfo::AddToolbarButtons(LPTOOLBAR pToolbar)
  537. {
  538. // The first two elements (nIndex and idCommand) and the last two
  539. // (Name and ToolTip) are order-dependent, changing by the loop.
  540. MMCBUTTON btnToolbar = { 0, 0, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 };
  541. USES_CONVERSION;
  542. ASSERT(pToolbar != NULL);
  543. // IDM_TBB_FIND is the last element in the enum, and also has a
  544. // value equal to the number of elements in the enum.
  545. for (int i = 0 ; i < IDM_TBB_FIND ; ++i) {
  546. CString szResourceName;
  547. CString szResourceTooltip;
  548. btnToolbar.nBitmap = i;
  549. // IDM_TBB_SAVE is the first element in the enum
  550. // This line requires the ToolbarButtonID values to be consecutive.
  551. btnToolbar.idCommand = i + IDM_TBB_SAVE;
  552. VERIFY(szResourceName.LoadString(IDS_ORDERED_TBTEXT0 + i));
  553. btnToolbar.lpButtonText = OLESTR_FROM_CSTRING(szResourceName);
  554. VERIFY(szResourceTooltip.LoadString(IDS_ORDERED_TBTTIP0 + i));
  555. btnToolbar.lpTooltipText = OLESTR_FROM_CSTRING(szResourceTooltip);
  556. HRESULT hr = pToolbar->InsertButton(i, &btnToolbar);
  557. ASSERT(hr == S_OK);
  558. if (FAILED(hr)) return hr;
  559. }
  560. return S_OK;
  561. }
  562. /*
  563. * SetControlbar - Set the exact same controlbar items we set in the scope
  564. * pane.
  565. *
  566. * History: a-jsari 9/22/97 Initial version
  567. */
  568. STDMETHODIMP CSystemInfo::SetControlbar(LPCONTROLBAR pControlbar)
  569. {
  570. const int nImages = 5;
  571. TRACE(_T("CSystemInfo::SetControlbar(%lx)\n"), pControlbar);
  572. if (pControlbar == NULL) {
  573. if (m_pControlbar) {
  574. m_pControlbar->Detach(m_pToolbar);
  575. SAFE_RELEASE(m_pToolbar);
  576. m_pControlbar->Detach(m_pMenuButton);
  577. SAFE_RELEASE(m_pMenuButton);
  578. SAFE_RELEASE(m_pControlbar);
  579. }
  580. return S_OK;
  581. }
  582. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  583. if (m_pControlbar == NULL) {
  584. m_pControlbar = pControlbar;
  585. m_pControlbar->AddRef();
  586. }
  587. HRESULT hr = S_FALSE;
  588. // If we haven't created the pull-down yet.
  589. if (ptbItems() == NULL) {
  590. hr = m_pControlbar->Create(TOOLBAR, this, reinterpret_cast<LPUNKNOWN *>(&m_pToolbar));
  591. ASSERT(hr == S_OK);
  592. if (FAILED(hr)) return hr;
  593. ::CBitmap pbmpToolbar;
  594. pbmpToolbar.LoadBitmap(IDB_TOOLS);
  595. hr = m_pToolbar->AddBitmap(nImages, pbmpToolbar, 16, 16, RGB(255,0,255));
  596. ASSERT(hr == S_OK);
  597. if (FAILED(hr)) return hr;
  598. hr = AddToolbarButtons(m_pToolbar);
  599. ASSERT(hr == S_OK);
  600. if (FAILED(hr)) return hr;
  601. // If we are acting as an extension snapin, remove the button for opening a file. Bug 400801.
  602. if (pComponentData() && !dynamic_cast<CSystemInfoScope *>(pComponentData())->IsPrimaryImpl())
  603. m_pToolbar->DeleteButton(IDM_TBB_OPEN - IDM_TBB_SAVE);
  604. }
  605. // If we haven't created the pull-down yet.
  606. if (pmnbSupportTools() == NULL) {
  607. USES_CONVERSION;
  608. // These should not need to be static: MMC bug.
  609. CString m_szSupportTools;
  610. CString m_szSupportTooltip;
  611. hr = m_pControlbar->Create(MENUBUTTON, this, reinterpret_cast<LPUNKNOWN *>(&m_pMenuButton));
  612. ASSERT(hr == S_OK);
  613. if (FAILED(hr)) return hr;
  614. VERIFY(m_szSupportTools.LoadString(IDS_SUPPORTTOOLS));
  615. VERIFY(m_szSupportTooltip.LoadString(IDS_SUPPORTITEM));
  616. hr = m_pMenuButton->AddButton(IDM_SUPPORT, OLESTR_FROM_CSTRING(m_szSupportTools),
  617. OLESTR_FROM_CSTRING(m_szSupportTooltip));
  618. ASSERT(hr == S_OK);
  619. if (FAILED(hr)) return hr;
  620. }
  621. return hr;
  622. }
  623. /*
  624. * SetIComponentData - Set the IComponentData pointer
  625. *
  626. * History: a-jsari 9/2/97
  627. */
  628. HRESULT CSystemInfo::SetIComponentData(CSystemInfoScope *pData)
  629. {
  630. ASSERT(pData);
  631. ASSERT(m_pComponentData == NULL);
  632. LPUNKNOWN pUnk = pData->GetUnknown();
  633. HRESULT hr = pUnk->QueryInterface(IID_IComponentData, reinterpret_cast<void **>(&m_pComponentData));
  634. m_plistTools = new CToolList(reinterpret_cast<CSystemInfoScope *>(m_pComponentData));
  635. VERIFY(m_mnuSupport.CreatePopupMenu());
  636. m_plistTools->AddToMenu(&m_mnuSupport);
  637. ASSERT(hr == S_OK);
  638. return hr;
  639. }
  640. /*
  641. * CreatePropertyPages - Call the Scope pane version of this function.
  642. *
  643. * History: a-jsari 12/9/97 Initial version
  644. */
  645. STDMETHODIMP CSystemInfo::CreatePropertyPages(LPPROPERTYSHEETCALLBACK pProvider,
  646. LONG_PTR handle, LPDATAOBJECT pDataObject)
  647. {
  648. return pExtendPropertySheet()->CreatePropertyPages(pProvider, handle, pDataObject);
  649. }
  650. /*
  651. * QueryPagesFor - Call the ScopePane version of this function.
  652. *
  653. * History: a-jsari 12/9/97 Initial version
  654. */
  655. STDMETHODIMP CSystemInfo::QueryPagesFor(LPDATAOBJECT lpDataObject)
  656. {
  657. return pExtendPropertySheet()->QueryPagesFor(lpDataObject);
  658. }
  659. //-----------------------------------------------------------------------------
  660. // Sets the text in the status bar on the main MMC window. There are three
  661. // panes, divided in the string by '|' characters. The middle one can be
  662. // used as a progress bar by using "%nn" in the string. See the MMC docs
  663. // for more information.
  664. //-----------------------------------------------------------------------------
  665. void CSystemInfo::SetStatusText(LPCTSTR szText)
  666. {
  667. if (m_pConsole2)
  668. m_pConsole2->SetStatusText((LPOLESTR) (szText ? szText : _T("||")));
  669. }
  670. void CSystemInfo::SetStatusText(UINT nResID)
  671. {
  672. CString strText(_T("||"));
  673. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  674. if (nResID)
  675. strText.LoadString(nResID);
  676. SetStatusText((LPCTSTR) strText);
  677. }
  678. //-----------------------------------------------------------------------------
  679. // We want to set the display to indicate that a refresh is being performed.
  680. // Delete all the items in the results pane and add an item with a specific
  681. // lValue indicating the refresh message.
  682. //
  683. // The LPARAM parameter has been added to allow this function to set different
  684. // messages in the results pane. It's value is examined in GetDisplayInfo.
  685. //-----------------------------------------------------------------------------
  686. void CSystemInfo::SetRefreshing(LPARAM lparamMessage)
  687. {
  688. if (pResult() == NULL || pHeaderCtrl() == NULL)
  689. return;
  690. CThreadingRefresh * pRefreshThread = NULL;
  691. CSystemInfoScope * pScope = reinterpret_cast<CSystemInfoScope *>(m_pComponentData);
  692. if (pScope)
  693. {
  694. CDataSource * pSource = pScope->pSource();
  695. if (pSource && pSource->GetType() == CDataSource::GATHERER)
  696. {
  697. CWBEMDataSource * pWBEMSource = reinterpret_cast<CWBEMDataSource *>(pSource);
  698. if (pWBEMSource)
  699. pRefreshThread = pWBEMSource->m_pThreadRefresh;
  700. }
  701. }
  702. if (pRefreshThread && pRefreshThread->ResultsPaneNotAvailable())
  703. return;
  704. // Updating the results pane is a critical section - we don't want the refresh
  705. // thread to update the list view while we're in the middle of it.
  706. if (pRefreshThread)
  707. pRefreshThread->EnterCriticalSection();
  708. // Delete current contents of results pane.
  709. pResult()->DeleteAllRsltItems();
  710. m_lstView.Clear();
  711. // Remove all of the current column headers, and add back a single column.
  712. for (HRESULT hr = S_OK; hr == S_OK; hr = pHeaderCtrl()->DeleteColumn(0));
  713. CString strHeading(_T(" "));
  714. strHeading.LoadString(IDS_DESCRIPTION);
  715. pHeaderCtrl()->InsertColumn(0, (LPCWSTR)strHeading, LVCFMT_LEFT, 446);
  716. // Add the single item with lParam indicating a refresh message, and refresh.
  717. RESULTDATAITEM rdiItem;
  718. rdiItem.mask = RDI_STR | RDI_PARAM | RDI_IMAGE | RDI_INDEX;
  719. rdiItem.str = MMC_CALLBACK;
  720. rdiItem.nCol = 0;
  721. rdiItem.nImage = 1;
  722. rdiItem.nIndex = 0;
  723. rdiItem.lParam = lparamMessage;
  724. pResult()->InsertItem(&rdiItem);
  725. if (pRefreshThread)
  726. pRefreshThread->LeaveCriticalSection();
  727. pResult()->UpdateItem(rdiItem.itemID);
  728. }
  729. //-----------------------------------------------------------------------------
  730. // Select the specified line on the results pane. (Used by find.)
  731. //-----------------------------------------------------------------------------
  732. void CSystemInfo::SelectLine(int iLine)
  733. {
  734. LPRESULTDATA pResultPane = pResult();
  735. if (!pResultPane)
  736. return;
  737. RESULTDATAITEM rdi;
  738. rdi.mask = RDI_STATE | RDI_INDEX;
  739. rdi.nIndex = iLine;
  740. rdi.nState = LVIS_FOCUSED | LVIS_SELECTED;
  741. pResultPane->ModifyViewStyle((MMC_RESULT_VIEW_STYLE ) 0x0008 /* = MMC_ENSUREFOCUSVISIBLE */, (MMC_RESULT_VIEW_STYLE ) 0);
  742. pResultPane->SetItem(&rdi);
  743. pResultPane->ModifyViewStyle((MMC_RESULT_VIEW_STYLE ) 0, (MMC_RESULT_VIEW_STYLE ) 0x0008 /* = MMC_ENSUREFOCUSVISIBLE */);
  744. }