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.

1305 lines
42 KiB

  1. #include "stdafx.h"
  2. #include "DfrgSnap.h"
  3. #include "DfrgSnapin.h"
  4. #include "resource.h"
  5. #include "GetDfrgRes.h"
  6. #include "Message.h"
  7. #include "ErrMacro.h"
  8. #include "vString.hpp"
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CDfrgSnapinComponentData
  11. //static const GUID CDfrgSnapinGUID_NODETYPE =
  12. //{ 0xcd83a794, 0x6f75, 0x11d2, { 0xa3, 0x85, 0x0, 0x60, 0x97, 0x72, 0x64, 0x2e } };
  13. static const GUID CDfrgSnapinGUID_NODETYPE =
  14. { 0x43668e22, 0x2636, 0x11d1, { 0xa1, 0xce, 0x0, 0x80, 0xc8, 0x85, 0x93, 0xa5 } };
  15. const GUID* CDfrgSnapinData::m_NODETYPE = &CDfrgSnapinGUID_NODETYPE;
  16. // original const OLECHAR* CDfrgSnapinData::m_SZNODETYPE = OLESTR("CD83A794-6F75-11D2-A385-00609772642E");
  17. const OLECHAR* CDfrgSnapinData::m_SZNODETYPE = OLESTR("43668E22-2636-11D1-A1CE-0080C88593A5");
  18. const OLECHAR* CDfrgSnapinData::m_SZDISPLAY_NAME = OLESTR("Disk Defragmenter");
  19. const CLSID* CDfrgSnapinData::m_SNAPIN_CLASSID = &CLSID_DfrgSnapin;
  20. //////////////////////////////////////
  21. // New Extension code
  22. static const GUID CDfrgSnapinExtGUID_NODETYPE =
  23. { 0x476e644a, 0xaaff, 0x11d0, { 0xb9, 0x44, 0x0, 0xc0, 0x4f, 0xd8, 0xd5, 0xb0 } };
  24. const GUID* CDfrgSnapinExtData::m_NODETYPE = &CDfrgSnapinExtGUID_NODETYPE;
  25. const OLECHAR* CDfrgSnapinExtData::m_SZNODETYPE = OLESTR("476e644a-aaff-11d0-b944-00c04fd8d5b0");
  26. //sks bug # 94863, storing text "disk Defragmenter" in the registry. took out the words
  27. //disk defragmenter, because it is loaded from the resources in the override method.
  28. const OLECHAR* CDfrgSnapinExtData::m_SZDISPLAY_NAME = OLESTR("");
  29. const CLSID* CDfrgSnapinExtData::m_SNAPIN_CLASSID = &CLSID_DfrgSnapin;
  30. // New Extension code end
  31. //////////////////////////////////////
  32. HRESULT CDfrgSnapinData::GetScopePaneInfo(SCOPEDATAITEM *pScopeDataItem)
  33. {
  34. //TCHAR szBuf[ 256 ];
  35. //wsprintf( szBuf, _T( "Mask is %d\n" ), pScopeDataItem->mask );
  36. //OutputDebugString( szBuf );
  37. if (pScopeDataItem->mask & SDI_STR)
  38. pScopeDataItem->displayname = m_bstrDisplayName;
  39. if (pScopeDataItem->mask & SDI_IMAGE)
  40. pScopeDataItem->nImage = m_scopeDataItem.nImage;
  41. if (pScopeDataItem->mask & SDI_OPENIMAGE)
  42. pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage;
  43. if (pScopeDataItem->mask & SDI_PARAM)
  44. pScopeDataItem->lParam = m_scopeDataItem.lParam;
  45. if (pScopeDataItem->mask & SDI_STATE )
  46. pScopeDataItem->nState = m_scopeDataItem.nState;
  47. // TODO : Add code for SDI_CHILDREN
  48. return S_OK;
  49. }
  50. HRESULT CDfrgSnapinData::GetResultPaneInfo(RESULTDATAITEM *pResultDataItem)
  51. {
  52. //TCHAR szBuf[ 256 ];
  53. //wsprintf( szBuf, _T( "Mask is %d\n" ), pResultDataItem->mask );
  54. //OutputDebugString( szBuf );
  55. if (pResultDataItem->bScopeItem)
  56. {
  57. if (pResultDataItem->mask & RDI_STR)
  58. {
  59. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  60. }
  61. if (pResultDataItem->mask & RDI_IMAGE)
  62. {
  63. pResultDataItem->nImage = m_scopeDataItem.nImage;
  64. }
  65. if (pResultDataItem->mask & RDI_PARAM)
  66. {
  67. pResultDataItem->lParam = m_scopeDataItem.lParam;
  68. }
  69. return S_OK;
  70. }
  71. if (pResultDataItem->mask & RDI_STR)
  72. {
  73. pResultDataItem->str = GetResultPaneColInfo(pResultDataItem->nCol);
  74. }
  75. if (pResultDataItem->mask & RDI_IMAGE)
  76. {
  77. pResultDataItem->nImage = m_resultDataItem.nImage;
  78. }
  79. if (pResultDataItem->mask & RDI_PARAM)
  80. {
  81. pResultDataItem->lParam = m_resultDataItem.lParam;
  82. }
  83. if (pResultDataItem->mask & RDI_INDEX)
  84. {
  85. pResultDataItem->nIndex = m_resultDataItem.nIndex;
  86. }
  87. return S_OK;
  88. }
  89. HRESULT CDfrgSnapinData::Notify(
  90. MMC_NOTIFY_TYPE event,
  91. LPARAM arg,
  92. LPARAM param,
  93. IComponentData* pComponentData,
  94. IComponent* pComponent,
  95. DATA_OBJECT_TYPES type)
  96. {
  97. // Add code to handle the different notifications.
  98. // Handle MMCN_SHOW and MMCN_EXPAND to enumerate children items.
  99. // In response to MMCN_SHOW you have to enumerate both the scope
  100. // and result pane items.
  101. // For MMCN_EXPAND you only need to enumerate the scope items
  102. // Use IConsoleNameSpace::InsertItem to insert scope pane items
  103. // Use IResultData::InsertItem to insert result pane item.
  104. HRESULT hr = E_NOTIMPL;
  105. _ASSERTE(pComponentData != NULL || pComponent != NULL);
  106. CComPtr<IConsole> spConsole;
  107. CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> spHeader;
  108. if (pComponentData != NULL)
  109. spConsole = ((CDfrgSnapin*)pComponentData)->m_spConsole;
  110. else
  111. {
  112. spConsole = ((CDfrgSnapinComponent*)pComponent)->m_spConsole;
  113. spHeader = spConsole;
  114. }
  115. switch (event)
  116. {
  117. case MMCN_SELECT:
  118. {
  119. //
  120. // Always track the last valid component.
  121. //
  122. if ( HIWORD( arg ) == TRUE && pComponent )
  123. m_pComponent = (CDfrgSnapinComponent*) pComponent;
  124. //
  125. // Always track whether or not we're a scope item.
  126. //
  127. m_fScopeItem = LOWORD( arg );
  128. hr = S_OK;
  129. }
  130. break;
  131. case MMCN_RESTORE_VIEW:
  132. {
  133. //
  134. // Determines whether or not the remoted or OCX is displayed.
  135. //
  136. *( (BOOL*)param ) = TRUE;
  137. hr = S_OK;
  138. }
  139. break;
  140. case MMCN_CONTEXTHELP:
  141. {
  142. CComQIPtr<IDisplayHelp,&IID_IDisplayHelp> spHelp = spConsole;
  143. spHelp->ShowTopic( CoTaskDupString( OLESTR( "defrag.chm::/defrag_overview.htm" ) ) );
  144. hr = S_OK;
  145. }
  146. break;
  147. case MMCN_DBLCLICK:
  148. {
  149. hr = S_FALSE;
  150. }
  151. break;
  152. case MMCN_INITOCX:
  153. {
  154. hr = S_OK;
  155. break;
  156. }
  157. case MMCN_SHOW:
  158. {
  159. CComQIPtr<IResultData, &IID_IResultData> spResultData(spConsole);
  160. if(arg == 0)
  161. {
  162. SetActiveControl(FALSE, pComponent );
  163. } else
  164. {
  165. SetActiveControl(TRUE, pComponent );
  166. }
  167. hr = OnShow( arg, spResultData );
  168. break;
  169. }
  170. case MMCN_EXPAND:
  171. {
  172. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  173. // TODO : Enumerate scope pane items
  174. hr = S_OK;
  175. break;
  176. }
  177. case MMCN_ADD_IMAGES:
  178. {
  179. // Add Images
  180. IImageList* pImageList = (IImageList*)arg;
  181. hr = E_FAIL;
  182. // Load bitmaps associated with the scope pane
  183. // and add them to the image list
  184. // Loads the default bitmaps generated by the wizard
  185. // Change as required
  186. HBITMAP hBitmap16 = (HBITMAP) LoadImage(
  187. GetDfrgResHandle(), // handle of the instance that contains the image
  188. MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_16), // name or identifier of image
  189. IMAGE_BITMAP, // type of image
  190. 0, // desired width
  191. 0, // desired height
  192. LR_DEFAULTCOLOR // load flags
  193. );
  194. if (hBitmap16 != NULL)
  195. {
  196. HBITMAP hBitmap32 = (HBITMAP ) LoadImage(
  197. GetDfrgResHandle(),
  198. MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_32), // name or identifier of image
  199. IMAGE_BITMAP, // type of image
  200. 0, // desired width
  201. 0, // desired height
  202. LR_DEFAULTCOLOR // load flags
  203. );
  204. if (hBitmap32 != NULL)
  205. {
  206. hr = pImageList->ImageListSetStrip((LONG_PTR *)hBitmap16,
  207. (LONG_PTR *)hBitmap32, 0, RGB(255, 255, 255));
  208. if (FAILED(hr))
  209. ATLTRACE(_T("IImageList::ImageListSetStrip failed\n"));
  210. ::DeleteObject(hBitmap32);
  211. hBitmap32 = NULL;
  212. }
  213. ::DeleteObject(hBitmap16);
  214. hBitmap16 = NULL;
  215. }
  216. break;
  217. }
  218. }
  219. return hr;
  220. }
  221. LPOLESTR CDfrgSnapinData::GetResultPaneColInfo(int nCol)
  222. {
  223. //
  224. // 12/13/99 This method is prototyped to return a pointer to an OLESTR which is
  225. // an OLECHAR array. Since this is a COM interface we should be using
  226. // CoTaskMemAlloc to allocate space for a copy and then copy it in.
  227. // The caller is then expected to free it. However per the MMC PM they are not
  228. // freeing it and probably cannot now or they would break too many snap-ins.
  229. //
  230. // So until they change which will probably be never, I will temporarily just
  231. // copy into a static and return a pointer to it. That way no one gets a
  232. // pointer internal to our snap-in object, and we don't leak either.
  233. //
  234. LPOLESTR pStr = NULL;
  235. static OLECHAR ColumnName[50 + 1];
  236. static OLECHAR ColumnType[50 + 1];
  237. static OLECHAR ColumnDesc[100 + 1];
  238. switch (nCol)
  239. {
  240. case 0:
  241. wcsncpy(ColumnName, m_wstrColumnName, 50);
  242. ColumnName[50] = 0;
  243. pStr = ColumnName;
  244. break;
  245. case 1:
  246. wcsncpy(ColumnType, m_wstrColumnType, 50);
  247. ColumnType[50] = 0;
  248. pStr = ColumnType;
  249. break;
  250. case 2:
  251. wcsncpy(ColumnDesc, m_wstrColumnDesc, 100);
  252. ColumnDesc[100] = 0;
  253. pStr = ColumnDesc;
  254. break;
  255. }
  256. return(pStr);
  257. }
  258. HRESULT CDfrgSnapin::Initialize(LPUNKNOWN pUnknown)
  259. {
  260. HRESULT hr = IComponentDataImpl<CDfrgSnapin, CDfrgSnapinComponent >::Initialize(pUnknown);
  261. if (FAILED(hr))
  262. return hr;
  263. CComPtr<IImageList> spImageList;
  264. if (m_spConsole->QueryScopeImageList(&spImageList) != S_OK)
  265. {
  266. ATLTRACE(_T("IConsole::QueryScopeImageList failed\n"));
  267. return E_UNEXPECTED;
  268. }
  269. // Load bitmaps associated with the scope pane
  270. // and add them to the image list
  271. // Loads the default bitmaps generated by the wizard
  272. // Change as required
  273. m_hBitmap16 = LoadBitmap( GetDfrgResHandle(), MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_16));
  274. if (m_hBitmap16 == NULL)
  275. return S_OK;
  276. m_hBitmap32 = LoadBitmap( GetDfrgResHandle(), MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_32));
  277. if (m_hBitmap32 == NULL) {
  278. ::DeleteObject(m_hBitmap16);
  279. m_hBitmap16 = NULL;
  280. return S_OK;
  281. }
  282. if (spImageList->ImageListSetStrip(
  283. (LONG_PTR *)m_hBitmap16,
  284. (LONG_PTR *)m_hBitmap32,
  285. 0, RGB(255, 255, 255)) != S_OK)
  286. {
  287. ATLTRACE(_T("IImageList::ImageListSetStrip failed\n"));
  288. ::DeleteObject(m_hBitmap16);
  289. m_hBitmap16 = NULL;
  290. ::DeleteObject(m_hBitmap32);
  291. m_hBitmap32 = NULL;
  292. return E_UNEXPECTED;
  293. }
  294. ::DeleteObject(m_hBitmap16);
  295. m_hBitmap16 = NULL;
  296. ::DeleteObject(m_hBitmap32);
  297. m_hBitmap32 = NULL;
  298. return S_OK;
  299. }
  300. ///////////////////////////////////////////////////////////////////////////////////////////////////
  301. // ESI Code Start
  302. ///////////////////////////////////
  303. // IExtendContextMenu::AddMenuItems()
  304. STDMETHODIMP CDfrgSnapinData::AddMenuItems(
  305. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  306. long *pInsertionAllowed,
  307. DATA_OBJECT_TYPES type)
  308. {
  309. Message(TEXT("CDfrgSnapinData::AddMenuItems"), -1, NULL);
  310. HRESULT hr = S_OK;
  311. // Note - snap-ins need to look at the data object and determine
  312. // in what context, menu items need to be added. They must also
  313. // observe the insertion allowed flags to see what items can be
  314. // added.
  315. /* handy comment:
  316. typedef struct _CONTEXTMENUITEM
  317. {
  318. LPWSTR strName;
  319. LPWSTR strStatusBarText;
  320. LONG lCommandID;
  321. LONG lInsertionPointID;
  322. LONG fFlags;
  323. LONG fSpecialFlags;
  324. } CONTEXTMENUITEM;
  325. */
  326. HINSTANCE hDfrgRes = GetDfrgResHandle();
  327. CONTEXTMENUITEM singleMenuItem;
  328. TCHAR menuText[200];
  329. TCHAR statusBarText[300];
  330. //
  331. // Retrieve the control from the current component.
  332. //
  333. assert( m_pComponent != NULL );
  334. CComPtr<IDispatch> spDispCtl = m_pComponent->GetControl();
  335. singleMenuItem.strName = menuText;
  336. singleMenuItem.strStatusBarText = statusBarText;
  337. singleMenuItem.fFlags = 0;
  338. singleMenuItem.fSpecialFlags = 0;
  339. // Add each of the items to the Action menu
  340. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) {
  341. // setting for the Action menu
  342. singleMenuItem.lInsertionPointID = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  343. // get the state of the current engine
  344. BOOL isOkToRun = GetSessionState( spDispCtl, IS_OK_TO_RUN);
  345. if (isOkToRun && m_fScopeItem){
  346. BOOL isEnginePaused = GetSessionState(spDispCtl, IS_ENGINE_PAUSED);
  347. BOOL isEngineRunning = GetSessionState(spDispCtl, IS_ENGINE_RUNNING);
  348. BOOL isVolListLocked = GetSessionState(spDispCtl, IS_VOLLIST_LOCKED);
  349. BOOL isDefragInProcess = GetSessionState(spDispCtl, IS_DEFRAG_IN_PROCESS);
  350. BOOL isReportAvailable = GetSessionState(spDispCtl, IS_REPORT_AVAILABLE);
  351. // get the proper button states
  352. LONG analyzeFlags=0;
  353. LONG defragFlags=0;
  354. LONG pauseFlags=0;
  355. LONG stopFlags=0;
  356. LONG seeReportFlags=0;
  357. if (isVolListLocked){ // turn off all buttons if this volume is locked
  358. analyzeFlags =
  359. defragFlags =
  360. pauseFlags =
  361. stopFlags =
  362. seeReportFlags = MF_DISABLED|MF_GRAYED;
  363. }
  364. else if (isEngineRunning){
  365. analyzeFlags = defragFlags = seeReportFlags = MF_DISABLED|MF_GRAYED;
  366. pauseFlags = stopFlags = MF_ENABLED;
  367. }
  368. else{ // neither defrag nor analyze are not running on any volumes
  369. analyzeFlags = defragFlags = MF_ENABLED;
  370. pauseFlags = stopFlags = MF_DISABLED|MF_GRAYED;
  371. // is the report available for the currently selected volume?
  372. seeReportFlags = isReportAvailable ? MF_ENABLED : MF_DISABLED|MF_GRAYED;
  373. }
  374. // analyze
  375. singleMenuItem.lCommandID = IDM_ANALYZE;
  376. singleMenuItem.fFlags = analyzeFlags;
  377. LoadString(hDfrgRes, IDS_ANALYZE, menuText, sizeof(menuText) / sizeof(TCHAR));
  378. LoadString(hDfrgRes, IDS_ANALYZE_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  379. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  380. if (FAILED(hr)) {
  381. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  382. return hr;
  383. }
  384. // defrag
  385. singleMenuItem.lCommandID = IDM_DEFRAG;
  386. singleMenuItem.fFlags = defragFlags;
  387. LoadString(hDfrgRes, IDS_DEFRAGMENT, menuText, sizeof(menuText) / sizeof(TCHAR));
  388. LoadString(hDfrgRes, IDS_DEFRAG_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  389. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  390. if (FAILED(hr)) {
  391. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  392. return hr;
  393. }
  394. // pause and resume button
  395. singleMenuItem.fFlags = pauseFlags;
  396. if (isEnginePaused) // resume
  397. {
  398. singleMenuItem.lCommandID = IDM_CONTINUE;
  399. LoadString(hDfrgRes, IDS_RESUME, menuText, sizeof(menuText) / sizeof(TCHAR));
  400. LoadString(hDfrgRes, IDS_RESUME_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  401. }
  402. else{ // pause button
  403. singleMenuItem.lCommandID = IDM_PAUSE;
  404. LoadString(hDfrgRes, IDS_PAUSE, menuText, sizeof(menuText) / sizeof(TCHAR));
  405. LoadString(hDfrgRes, IDS_PAUSE_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  406. }
  407. // add the pause/resume button
  408. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  409. if (FAILED(hr)) {
  410. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  411. return hr;
  412. }
  413. // stop
  414. singleMenuItem.lCommandID = IDM_STOP;
  415. singleMenuItem.fFlags = stopFlags;
  416. LoadString(hDfrgRes, IDS_STOP, menuText, sizeof(menuText) / sizeof(TCHAR));
  417. LoadString(hDfrgRes, IDS_STOP_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  418. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  419. if (FAILED(hr)) {
  420. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  421. return hr;
  422. }
  423. // See Report
  424. singleMenuItem.lCommandID = IDM_REPORT;
  425. singleMenuItem.fFlags = seeReportFlags;
  426. LoadString(hDfrgRes, IDS_REPORT, menuText, sizeof(menuText) / sizeof(TCHAR));
  427. LoadString(hDfrgRes, IDS_REPORT_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  428. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  429. if (FAILED(hr)) {
  430. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  431. return hr;
  432. }
  433. // spacer
  434. singleMenuItem.fFlags = MF_SEPARATOR;
  435. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  436. if (FAILED(hr)) {
  437. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  438. return hr;
  439. }
  440. // Refresh the list view
  441. singleMenuItem.lCommandID = IDM_REFRESH;
  442. singleMenuItem.fFlags = MF_ENABLED;
  443. LoadString(hDfrgRes, IDS_REFRESH, menuText, sizeof(menuText) / sizeof(TCHAR));
  444. LoadString(hDfrgRes, IDS_REFRESH_STATUS_BAR, statusBarText, sizeof(statusBarText) / sizeof(TCHAR));
  445. hr = pContextMenuCallback->AddItem(&singleMenuItem);
  446. if (FAILED(hr)) {
  447. Message(TEXT("CComponentDataImpl::AddMenuItems - pContextMenuCallback->AddItem"), hr, NULL);
  448. return hr;
  449. }
  450. }// end of IsOkToRun
  451. }
  452. // add the view items
  453. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW) {
  454. }
  455. return hr;
  456. }
  457. ///////////////////////////////////
  458. // IExtendContextMenu::Command()
  459. STDMETHODIMP CDfrgSnapinData::Command(long lCommandID,
  460. CSnapInObjectRootBase* pObj,
  461. DATA_OBJECT_TYPES type)
  462. {
  463. Message(TEXT("CDfrgSnapinData::Command"), -1, NULL);
  464. // Handle each of the commands.
  465. switch (lCommandID) {
  466. case IDM_ANALYZE:
  467. SendCommand(ID_ANALYZE);
  468. break;
  469. case IDM_DEFRAG:
  470. SendCommand(ID_DEFRAG);
  471. break;
  472. case IDM_CONTINUE:
  473. SendCommand(ID_CONTINUE);
  474. break;
  475. case IDM_PAUSE:
  476. SendCommand(ID_PAUSE);
  477. break;
  478. case IDM_STOP:
  479. SendCommand(ID_STOP);
  480. break;
  481. case IDM_REPORT:
  482. SendCommand(ID_REPORT);
  483. break;
  484. case IDM_REFRESH:
  485. SendCommand(ID_REFRESH);
  486. break;
  487. default:
  488. break;
  489. }
  490. return S_OK;
  491. }
  492. // contructor added by ESI
  493. CDfrgSnapinComponent::CDfrgSnapinComponent()
  494. {
  495. Message(TEXT("CSnapinApp::InitInstance"), -1, NULL);
  496. /*
  497. Message(TEXT("CDefragSnapinComponent::CDefragSnapinComponent"), -1, NULL);
  498. m_pHeader = NULL;
  499. m_pComponentData = NULL;
  500. //m_pToolbar1 = NULL;
  501. //m_pControlbar = NULL;
  502. //m_pbmpToolbar1 = NULL;
  503. m_pConsoleVerb = NULL;
  504. //m_pDfrgCtl = NULL;
  505. */
  506. m_dwAdvise = 0;
  507. }
  508. CDfrgSnapinComponent::~CDfrgSnapinComponent()
  509. {
  510. Message(TEXT("CSnapinApp::ExitInstance"), -1, NULL);
  511. }
  512. /*
  513. ///////////////////////////////////////////////////////////////////////////////////////////////////
  514. // Implementation of IComponent::Notify()
  515. STDMETHODIMP CDfrgSnapinComponent::Notify(
  516. LPDATAOBJECT lpDataObject,
  517. MMC_NOTIFY_TYPE event,
  518. long arg,
  519. long param)
  520. {
  521. long cookie = 0;
  522. HRESULT hr = S_OK;
  523. TCHAR cString[64];
  524. switch(event) {
  525. case MMCN_PROPERTY_CHANGE:
  526. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_PROPERTY_CHANGE"), -1, NULL);
  527. break;
  528. case MMCN_VIEW_CHANGE:
  529. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_VIEW_CHANGE"), -1, NULL);
  530. break;
  531. case MMCN_ACTIVATE:
  532. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_ACTIVATE"), -1, NULL);
  533. //hr = OnActivate(cookie, arg, param);
  534. break;
  535. case MMCN_CLICK:
  536. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_CLICK"), -1, NULL);
  537. break;
  538. case MMCN_DBLCLICK:
  539. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_DBLCLICK"), -1, NULL);
  540. hr = S_FALSE; // false indicates that this is not implemented
  541. break;
  542. case MMCN_ADD_IMAGES:
  543. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_ADD_IMAGES"), -1, NULL);
  544. break;
  545. case MMCN_SHOW:
  546. hr = OnShow(arg);
  547. break;
  548. case MMCN_MINIMIZED:
  549. //hr = OnMinimize(cookie, arg, param);
  550. break;
  551. case MMCN_SELECT:
  552. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_SELECT"), -1, NULL);
  553. // todo HandleStandardVerbs(arg, lpDataObject);
  554. break;
  555. case MMCN_BTN_CLICK:
  556. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_BTN_CLICK"), -1, NULL);
  557. //AfxMessageBox(_T("CDefragSnapinComponent::MMCN_BTN_CLICK"));
  558. break;
  559. case MMCN_INITOCX:
  560. Message(TEXT("CDefragSnapinComponent::Notify - MMCN_INITOCX"), -1, NULL);
  561. break;
  562. // Note - Future expansion of notify types possible
  563. default:
  564. wsprintf(cString, TEXT("event = 0x%x"), event);
  565. Message(TEXT("CDefragSnapinComponent::Notify"), E_UNEXPECTED, cString);
  566. hr = E_UNEXPECTED;
  567. break;
  568. }
  569. return hr;
  570. }
  571. */
  572. /////////////////////////////////////////////////////
  573. //
  574. // Dispatch interface to the OCX (DfrgCtl) to send commands
  575. //
  576. /////////////////////////////////////////////////////
  577. BOOL CDfrgSnapinData::SendCommand(LPARAM lparamCommand)
  578. {
  579. HRESULT hr;
  580. // Ensure that we have a pointer to the Defrag OCX
  581. if ( m_iDfrgCtlDispatch == NULL ){
  582. Message(TEXT("SendCommand - m_iDfrgCtlDispatch is NULL!"), -1, NULL);
  583. return( FALSE );
  584. }
  585. // get the defragger OCX dispatch interface
  586. CComPtr<IDispatch> pDfrgCtlDispatch = m_iDfrgCtlDispatch;
  587. // get the ID of the "Command" interface
  588. OLECHAR FAR* szMember = TEXT("Command"); // maps this to "put_Command()"
  589. DISPID dispid;
  590. hr = pDfrgCtlDispatch->GetIDsOfNames(
  591. IID_NULL, // Reserved for future use. Must be IID_NULL.
  592. &szMember, // Passed-in array of names to be mapped.
  593. 1, // Count of the names to be mapped.
  594. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  595. &dispid); // Caller-allocated array (see help for details)
  596. if (!SUCCEEDED(hr)) {
  597. Message(TEXT("SendCommand - pDfrgCtlDispatch->GetIDsOfNames"), hr, NULL);
  598. return FALSE;
  599. }
  600. DISPID mydispid = DISPID_PROPERTYPUT;
  601. VARIANTARG* pvars = new VARIANTARG;
  602. EF(pvars);
  603. VariantInit(&pvars[0]);
  604. pvars[0].vt = VT_I2;
  605. pvars[0].iVal = (short)lparamCommand;
  606. DISPPARAMS disp = { pvars, &mydispid, 1, 1 };
  607. hr = pDfrgCtlDispatch->Invoke(
  608. dispid, // unique number identifying the method to invoke
  609. IID_NULL, // Reserved. Must be IID_NULL
  610. LOCALE_USER_DEFAULT, // A locale ID
  611. DISPATCH_PROPERTYPUT, // flag indicating the context of the method to invoke
  612. &disp, // A structure with the parameters to pass to the method
  613. NULL, // The result from the calling method
  614. NULL, // returned exception information
  615. NULL); // index indicating the first argument that is in error
  616. delete pvars;
  617. if (!SUCCEEDED(hr)) {
  618. Message(TEXT("SendCommand - pDfrgCtlDispatch->Invoke"), hr, NULL);
  619. return FALSE;
  620. }
  621. return TRUE;
  622. }
  623. ///////////////////////////////////////////////////////////////////////////////////////////////////
  624. // gets one of the states of the OCX
  625. // see CSnapin.h for definition
  626. ///////////////////////////////////////////////////////////////////////////////////////////////////
  627. BOOL CDfrgSnapinData::GetSessionState(LPDISPATCH pdispControl, UINT sessionState)
  628. {
  629. DISPID dispid;
  630. HRESULT hr;
  631. // Ensure that we have a pointer to the Defrag OCX
  632. if ( pdispControl == NULL)
  633. return FALSE;
  634. // get the defragger OCX dispatch interface
  635. CComPtr<IDispatch> pDfrgCtlDispatch = pdispControl;
  636. // array of the interface names
  637. OLECHAR FAR* szMember[DFRG_INTERFACE_COUNT] = {
  638. OLESTR("IsEnginePaused"),
  639. OLESTR("IsEngineRunning"),
  640. OLESTR("IsDefragInProcess"),
  641. OLESTR("IsVolListLocked"),
  642. OLESTR("ReportStatus"),
  643. OLESTR("IsOkToRun")};
  644. hr = pDfrgCtlDispatch->GetIDsOfNames(
  645. IID_NULL, // Reserved for future use. Must be IID_NULL.
  646. &szMember[sessionState], // Passed-in array of names to be mapped.
  647. 1/*DFRG_INTERFACE_COUNT*/, // Count of the names to be mapped.
  648. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  649. &dispid); // Caller-allocated array (see help for details)
  650. if (!SUCCEEDED(hr)) {
  651. Message(TEXT("GetSessionState - pDfrgCtlDispatch->GetIDsOfNames"), hr, NULL);
  652. return FALSE;
  653. }
  654. VARIANT varResult;
  655. VariantInit(&varResult);
  656. V_VT(&varResult) = VT_I2;
  657. DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  658. hr = pDfrgCtlDispatch->Invoke(
  659. dispid, // unique number identifying the method to invoke
  660. IID_NULL, // Reserved. Must be IID_NULL
  661. LOCALE_USER_DEFAULT, // A locale ID
  662. DISPATCH_PROPERTYGET, // flag indicating the context of the method to invoke
  663. &dispparamsNoArgs, // A structure with the parameters to pass to the method
  664. &varResult, // The result from the calling method
  665. NULL, // returned exception information
  666. NULL); // index indicating the first argument that is in error
  667. if (!SUCCEEDED(hr)) {
  668. Message(TEXT("IsReportAvailable - pDfrgCtlDispatch->Invoke"), hr, NULL);
  669. return FALSE;
  670. }
  671. return V_BOOL(&varResult);
  672. }
  673. ///////////////////////////////////////////////////////////////////////////////////////////////////
  674. // gets the current engine state from the OCX
  675. ///////////////////////////////////////////////////////////////////////////////////////////////////
  676. short CDfrgSnapinData::GetEngineState(void)
  677. {
  678. // Ensure that we have a pointer to the Defrag OCX
  679. if( m_iDfrgCtlDispatch == NULL )
  680. return FALSE;
  681. // get the defragger OCX dispatch interface
  682. CComPtr<IDispatch> pDfrgCtlDispatch = m_iDfrgCtlDispatch;
  683. // get the ID of the "Command" interface
  684. OLECHAR FAR* szMember = TEXT("EngineState"); // maps this to "get_EngineState()"
  685. DISPID dispid;
  686. HRESULT hr = pDfrgCtlDispatch->GetIDsOfNames(
  687. IID_NULL, // Reserved for future use. Must be IID_NULL.
  688. &szMember, // Passed-in array of names to be mapped.
  689. 1, // Count of the names to be mapped.
  690. LOCALE_USER_DEFAULT,// The locale context in which to interpret the names.
  691. &dispid); // Caller-allocated array (see help for details)
  692. if (!SUCCEEDED(hr)) {
  693. Message(TEXT("GetEngineState - pDfrgCtlDispatch->GetIDsOfNames"), hr, NULL);
  694. return 0;
  695. }
  696. VARIANT varResult;
  697. VariantInit(&varResult);
  698. V_VT(&varResult) = VT_I2;
  699. DISPPARAMS dispparamsNoArgs = {NULL, NULL, 0, 0};
  700. hr = pDfrgCtlDispatch->Invoke(
  701. dispid, // unique number identifying the method to invoke
  702. IID_NULL, // Reserved. Must be IID_NULL
  703. LOCALE_USER_DEFAULT, // A locale ID
  704. DISPATCH_PROPERTYGET, // flag indicating the context of the method to invoke
  705. &dispparamsNoArgs, // A structure with the parameters to pass to the method
  706. &varResult, // The result from the calling method
  707. NULL, // returned exception information
  708. NULL); // index indicating the first argument that is in error
  709. if (!SUCCEEDED(hr)) {
  710. Message(TEXT("GetEngineState - pDfrgCtlDispatch->Invoke"), hr, NULL);
  711. return 0;
  712. }
  713. return V_I2(&varResult);
  714. }
  715. //
  716. // Determines if the enumeration is for a remoted machine or not.
  717. //
  718. #ifndef DNS_MAX_NAME_LENGTH
  719. #define DNS_MAX_NAME_LENGTH 255
  720. #endif
  721. bool CDfrgSnapin::IsDataObjectRemoted( IDataObject* pDataObject )
  722. {
  723. bool fRemoted = false;
  724. TCHAR szComputerName[ DNS_MAX_NAME_LENGTH + 1 ];
  725. DWORD dwNameLength = (DNS_MAX_NAME_LENGTH + 1);
  726. TCHAR szDataMachineName[ DNS_MAX_NAME_LENGTH + 1 ];
  727. //
  728. // Get local computer name.
  729. //
  730. GetComputerName(szComputerName, &dwNameLength);
  731. //
  732. // Get the machine name from the given data object.
  733. //
  734. if ( ExtractString( pDataObject, m_ccfRemotedFormat, szDataMachineName, DNS_MAX_NAME_LENGTH + 1 ) )
  735. {
  736. _toupper( szDataMachineName );
  737. //
  738. // Find the start of the server name.
  739. //
  740. LPTSTR pStr = szDataMachineName;
  741. while ( pStr && *pStr == L'\\' )
  742. pStr++;
  743. //
  744. // Compare the server name.
  745. //
  746. if ( pStr && *pStr && wcscmp( pStr, szComputerName ) != 0 )
  747. fRemoted = true;
  748. }
  749. return( fRemoted );
  750. }
  751. //
  752. // Retrieves the value of a given clipboard format from a given data object.
  753. //
  754. bool CDfrgSnapin::ExtractString( IDataObject* pDataObject, unsigned int cfClipFormat, LPTSTR pBuf, DWORD dwMaxLength)
  755. {
  756. USES_CONVERSION;
  757. bool fFound = false;
  758. FORMATETC formatetc = { (CLIPFORMAT) cfClipFormat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
  759. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  760. stgmedium.hGlobal = ::GlobalAlloc( GMEM_SHARE, dwMaxLength * sizeof(TCHAR));
  761. HRESULT hr;
  762. do
  763. {
  764. //
  765. // This is a memory error condition!
  766. //
  767. if ( NULL == stgmedium.hGlobal )
  768. break;
  769. hr = pDataObject->GetDataHere( &formatetc, &stgmedium );
  770. if ( FAILED(hr) )
  771. break;
  772. LPWSTR pszNewData = reinterpret_cast<LPWSTR>( ::GlobalLock( stgmedium.hGlobal ) );
  773. if ( NULL == pszNewData )
  774. break;
  775. pszNewData[ dwMaxLength - 1 ] = L'\0';
  776. _tcscpy( pBuf, OLE2T( pszNewData ) );
  777. fFound = true;
  778. }
  779. while( false );
  780. if ( NULL != stgmedium.hGlobal )
  781. {
  782. GlobalUnlock( stgmedium.hGlobal );
  783. GlobalFree( stgmedium.hGlobal );
  784. }
  785. return( fFound );
  786. }
  787. HRESULT CDfrgSnapinExtData::Notify( MMC_NOTIFY_TYPE event,
  788. LPARAM arg,
  789. LPARAM param,
  790. IComponentData* pComponentData,
  791. IComponent* pComponent,
  792. DATA_OBJECT_TYPES type)
  793. {
  794. // Add code to handle the different notifications.
  795. // Handle MMCN_SHOW and MMCN_EXPAND to enumerate children items.
  796. // In response to MMCN_SHOW you have to enumerate both the scope
  797. // and result pane items.
  798. // For MMCN_EXPAND you only need to enumerate the scope items
  799. // Use IConsoleNameSpace::InsertItem to insert scope pane items
  800. // Use IResultData::InsertItem to insert result pane item.
  801. HRESULT hr = E_NOTIMPL;
  802. bool fRemoted = false;
  803. _ASSERTE( pComponentData != NULL || pComponent != NULL );
  804. CComPtr<IConsole> spConsole;
  805. if ( pComponentData != NULL )
  806. {
  807. CDfrgSnapin* pExt = (CDfrgSnapin*) pComponentData;
  808. spConsole = pExt->m_spConsole;
  809. //
  810. // Determine if we're remoted.
  811. //
  812. fRemoted = pExt->IsRemoted();
  813. }
  814. else
  815. {
  816. spConsole = ( (CDfrgSnapinComponent*) pComponent )->m_spConsole;
  817. }
  818. switch ( event )
  819. {
  820. case MMCN_SHOW:
  821. arg = arg;
  822. hr = S_OK;
  823. break;
  824. case MMCN_EXPAND:
  825. {
  826. if ( arg == TRUE )
  827. {
  828. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(spConsole);
  829. SCOPEDATAITEM* pScopeData;
  830. //
  831. // Create the node based on whether we're remoted or
  832. // not.
  833. //
  834. m_pNode = new CDfrgSnapinData( fRemoted );
  835. EE(m_pNode);
  836. m_pNode->GetScopeData( &pScopeData );
  837. pScopeData->relativeID = param;
  838. spConsoleNameSpace->InsertItem( pScopeData );
  839. if ( pComponentData )
  840. ( (CDfrgSnapin*) pComponentData )->m_pNode = m_pNode;
  841. }
  842. hr = S_OK;
  843. break;
  844. }
  845. case MMCN_REMOVE_CHILDREN:
  846. {
  847. //
  848. // We are not deleting this node since this same pointer is
  849. // stashed in the pComponentData in response to the MMCN_EXPAND
  850. // notification. The destructor of pComponentData deletes the pointer
  851. // to this node.
  852. //
  853. //delete m_pNode;
  854. m_pNode = NULL;
  855. hr = S_OK;
  856. break;
  857. }
  858. case MMCN_ADD_IMAGES:
  859. {
  860. // Add Images
  861. IImageList* pImageList = (IImageList*)arg;
  862. hr = E_FAIL;
  863. // Load bitmaps associated with the scope pane
  864. // and add them to the image list
  865. // Loads the default bitmaps generated by the wizard
  866. // Change as required
  867. HBITMAP hBitmap16 = (HBITMAP) LoadImage(
  868. GetDfrgResHandle(), // handle of the instance that contains the image
  869. MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_16), // name or identifier of image
  870. IMAGE_BITMAP, // type of image
  871. 0, // desired width
  872. 0, // desired height
  873. LR_DEFAULTCOLOR // load flags
  874. );
  875. if (hBitmap16 != NULL)
  876. {
  877. BITMAP bm;
  878. GetObject( hBitmap16, sizeof( bm ), &bm );
  879. HBITMAP hBitmap32 = (HBITMAP ) LoadImage(
  880. GetDfrgResHandle(),
  881. MAKEINTRESOURCE(IDB_DEFRAGSNAPIN_32), // name or identifier of image
  882. IMAGE_BITMAP, // type of image
  883. 0, // desired width
  884. 0, // desired height
  885. LR_DEFAULTCOLOR // load flags
  886. );
  887. if (hBitmap32 != NULL)
  888. {
  889. GetObject( hBitmap32, sizeof( bm ), &bm );
  890. hr = pImageList->ImageListSetStrip((LONG_PTR *)hBitmap16,
  891. (LONG_PTR *)hBitmap32, 0, RGB(255, 255, 255));
  892. if (FAILED(hr))
  893. ATLTRACE(_T("IImageList::ImageListSetStrip failed\n"));
  894. ::DeleteObject(hBitmap32);
  895. hBitmap32 = NULL;
  896. }
  897. ::DeleteObject(hBitmap16);
  898. hBitmap16 = NULL;
  899. }
  900. break;
  901. }
  902. }
  903. return hr;
  904. }
  905. /////////////////////////////////////////////////////////////////////////////////////////////
  906. //
  907. // ESI function called when the snapin changes show state
  908. //
  909. HRESULT CDfrgSnapinData::OnShow(LPARAM isShowing, IResultData* pResults )
  910. {
  911. return S_OK;
  912. }
  913. /////////////////////////////////////////////////////////////////////////////////////////////
  914. //
  915. // instantiates the OCX
  916. //
  917. // implementation of IComponent::GetResultViewType()
  918. STDMETHODIMP CDfrgSnapinData::GetResultViewType(
  919. LPOLESTR* ppViewType,
  920. long* pViewOptions)
  921. {
  922. TCHAR szPath[ _MAX_PATH + 30 ];
  923. Message(TEXT("IComponent::GetResultViewType"), -1, NULL);
  924. *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS;
  925. // Make sure that we are displaying the OCX?
  926. if ( m_CustomViewID != VIEW_DEFRAG_OCX ) {
  927. return S_FALSE;
  928. }
  929. //
  930. // TLP: Return back a web page if we're remoted.
  931. //
  932. if ( m_fRemoted )
  933. {
  934. TCHAR szModulePath[ _MAX_PATH + 1 ];
  935. //
  936. // Get the HTML embedded in the res file.
  937. //
  938. GetModuleFileName( GetDfrgResHandle(), szModulePath, _MAX_PATH );
  939. //
  940. // Append the necessary decorations for correct access.
  941. //
  942. _tcscpy( szPath, _T( "res://" ) );
  943. _tcscat( szPath, szModulePath );
  944. _tcscat( szPath, _T( "/REMOTED.HTM" ) );
  945. }
  946. else
  947. {
  948. //
  949. // Display the normal OCX.
  950. //
  951. _tcscpy( szPath, szDefragGUID );
  952. }
  953. UINT uiByteLen = (lstrlen(szPath) + 1) * sizeof(OLECHAR);
  954. LPOLESTR psz = (LPOLESTR)::CoTaskMemAlloc(uiByteLen);
  955. if (psz == NULL) {
  956. return S_FALSE;
  957. }
  958. lstrcpy(psz, szPath);
  959. *ppViewType = psz;
  960. return S_OK;
  961. }
  962. void CDfrgSnapinComponent::Advise()
  963. {
  964. if ( m_dwAdvise == 0 )
  965. {
  966. HRESULT hr = AtlAdvise( m_spDisp, this->GetUnknown(), IID_IDfrgEvents, &m_dwAdvise );
  967. _ASSERTE( SUCCEEDED( hr ) );
  968. }
  969. }
  970. void CDfrgSnapinComponent::Unadvise()
  971. {
  972. if ( m_dwAdvise != 0 )
  973. {
  974. HRESULT hr = AtlUnadvise( m_spDisp, IID_IDfrgEvents, m_dwAdvise );
  975. _ASSERTE( SUCCEEDED( hr ) );
  976. m_dwAdvise = 0;
  977. }
  978. }
  979. //
  980. // Overrides the Filldata
  981. //
  982. STDMETHODIMP CDfrgSnapinData::FillData( CLIPFORMAT cf, LPSTREAM pStream )
  983. {
  984. HRESULT hr = DV_E_CLIPFORMAT;
  985. ULONG uWritten;
  986. //
  987. // We need to write out our own member since GetDisplayName() does
  988. // not give us an opportunity override its static implementation by
  989. // ATL.
  990. //
  991. if (cf == m_CCF_NODETYPE) // wants the guid for the node
  992. {
  993. hr = pStream->Write( GetNodeType(), sizeof(GUID), &uWritten);
  994. return hr;
  995. }
  996. if (cf == m_CCF_SZNODETYPE) // string that describes the node (not displayed, used for lookup of the node)
  997. {
  998. hr = pStream->Write( GetSZNodeType(), (lstrlen((LPCTSTR) GetSZNodeType()) + 1 )* sizeof(TCHAR), &uWritten);
  999. return hr;
  1000. }
  1001. if (cf == m_CCF_DISPLAY_NAME) // displayed in the scope pane to id the node (root only)
  1002. {
  1003. USES_CONVERSION;
  1004. VString vDisplayName(IDS_PRODUCT_NAME, GetDfrgResHandle());
  1005. hr = pStream->Write(vDisplayName.GetBuffer(), vDisplayName.GetLength() * sizeof( WCHAR ), &uWritten);
  1006. return hr;
  1007. }
  1008. if (cf == m_CCF_SNAPIN_CLASSID) // guid of the snapin (CLSID)
  1009. {
  1010. hr = pStream->Write( GetSnapInCLSID(), sizeof(GUID), &uWritten);
  1011. return hr;
  1012. }
  1013. return hr;
  1014. }
  1015. /*
  1016. STDMETHODIMP_(ULONG) CDfrgSnapinData::Release(void)
  1017. {
  1018. if (InterlockedDecrement(&m_cRef) == 0) {
  1019. delete this;
  1020. return 0;
  1021. }
  1022. return m_cRef;
  1023. }
  1024. STDMETHODIMP CDfrgSnapinData::QueryInterface(REFIID riid, void** ppv)
  1025. {
  1026. if (ppv == NULL)
  1027. return E_INVALIDARG;
  1028. // Make sure we are being asked for a DataObject interface.
  1029. if ( riid == IID_IUnknown || riid == IID_IDfrgEvents )
  1030. {
  1031. // If so return a pointer to this interface.
  1032. *ppv = (IUnknown *) this;
  1033. AddRef();
  1034. return S_OK;
  1035. }
  1036. // No interface.
  1037. *ppv = NULL;
  1038. return E_NOINTERFACE;
  1039. }
  1040. */
  1041. //
  1042. // Called from the OCX when the status has changed.
  1043. //
  1044. STDMETHODIMP CDfrgSnapinComponent::StatusChanged( BSTR bszStatus )
  1045. {
  1046. if (m_spConsole){
  1047. CComQIPtr<IConsole2,&IID_IConsole2> pConsole = m_spConsole;
  1048. pConsole->SetStatusText( bszStatus );
  1049. }
  1050. return( S_OK );
  1051. }
  1052. //
  1053. // Called from the OCX when the OK to run property has changed.
  1054. //
  1055. STDMETHODIMP CDfrgSnapinComponent::IsOKToRun( BOOL bOK )
  1056. {
  1057. ( (CDfrgSnapinData*) m_pComponentData->m_pNode )->SetActiveControl( TRUE, this );
  1058. return( S_OK );
  1059. }
  1060. void CDfrgSnapinData::SetActiveControl( BOOL bActive, IComponent* pComponent )
  1061. {
  1062. CComPtr<IConsole> spConsole;
  1063. spConsole = ((CDfrgSnapinComponent*)pComponent)->m_spConsole;
  1064. //
  1065. // Always get the ctl dispatch pointer.
  1066. //
  1067. CComPtr<IUnknown> pUnk;
  1068. spConsole->QueryResultView( &pUnk );
  1069. CComQIPtr<IDispatch,&IID_IDispatch> pCtl = pUnk;
  1070. //
  1071. // If this is the first one, then check if we're
  1072. // valid. If we are, then assign this conrol to
  1073. //
  1074. if ( GetSessionState( pCtl, IS_OK_TO_RUN ) == TRUE )
  1075. m_iDfrgCtlDispatch = pCtl;
  1076. //
  1077. // Always attach the control to the component.
  1078. //
  1079. ( (CDfrgSnapinComponent*) pComponent )->SetControl( bActive == TRUE ? (LPDISPATCH) pCtl : (LPDISPATCH) NULL );
  1080. }
  1081. STDMETHODIMP CDfrgSnapinComponent::AddMenuItems(LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK piCallback,long *pInsertionAllowed)
  1082. {
  1083. HRESULT hr;
  1084. if ( IS_SPECIAL_DATAOBJECT( pDataObject ) )
  1085. {
  1086. hr = m_pComponentData->m_pNode->AddMenuItems( piCallback, pInsertionAllowed, CCT_RESULT );
  1087. }
  1088. else
  1089. {
  1090. hr = IExtendContextMenuImpl<CDfrgSnapin>::AddMenuItems( pDataObject, piCallback, pInsertionAllowed );
  1091. }
  1092. return( hr );
  1093. }
  1094. STDMETHODIMP CDfrgSnapinComponent::Command(long lCommandID, LPDATAOBJECT pDataObject)
  1095. {
  1096. HRESULT hr;
  1097. if ( IS_SPECIAL_DATAOBJECT( pDataObject ) )
  1098. {
  1099. hr = m_pComponentData->m_pNode->Command( lCommandID, this, CCT_RESULT );
  1100. }
  1101. else
  1102. {
  1103. hr = IExtendContextMenuImpl<CDfrgSnapin>::Command( lCommandID, pDataObject );
  1104. }
  1105. return( hr );
  1106. }