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.

509 lines
14 KiB

  1. // toolbar.cpp : Implementation of toolbars for snapin
  2. #include "stdafx.h"
  3. #include "cookie.h"
  4. #include "cmponent.h"
  5. #include "compdata.h"
  6. #include <compuuid.h> // UUIDs for Computer Management
  7. #include "macros.h"
  8. USE_HANDLE_MACROS("FILEMGMT(toolbar.cpp)")
  9. #ifdef _DEBUG
  10. #define new DEBUG_NEW
  11. #undef THIS_FILE
  12. static char THIS_FILE[] = __FILE__;
  13. #endif
  14. #define ARRAYLEN(x) (sizeof(x) / sizeof((x)[0]))
  15. // We keep the strings in globals because multiple IComponents will all
  16. // have their own IToolbars. We do not keep the bitmaps in globals because
  17. // of difficulties with the global destruction mechanism, see compdata.h.
  18. // The MMCBUTTON structures contain resource IDs for the strings which will
  19. // be loaded into the CString array when the first instance of the toolbar
  20. // is loaded.
  21. //
  22. // CODEWORK We need a mechanism to free these strings.
  23. MMCBUTTON g_FileMgmtSnapinButtons[] =
  24. {
  25. { 0, IDS_BUTTON_NEWSHARE, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  26. };
  27. CString* g_astrFileMgmtButtonStrings = NULL; // dynamic array of CStrings
  28. BOOL g_bLoadedFileMgmtStrings = FALSE;
  29. MMCBUTTON g_SvcMgmtSnapinButtons[] =
  30. {
  31. // The first button will be either Start or Resume.
  32. // One of these two entries will be removed later.
  33. { 0, cmServiceResume, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  34. { 0, cmServiceStart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  35. { 1, cmServiceStop, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  36. { 2, cmServicePause, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  37. { 3, cmServiceRestart, !TBSTATE_ENABLED, TBSTYLE_BUTTON, 0, 0 },
  38. };
  39. CString* g_astrSvcMgmtButtonStrings = NULL; // dynamic array of CStrings
  40. BOOL g_bLoadedSvcMgmtStrings = FALSE;
  41. void LoadButtonArray(
  42. MMCBUTTON* pButtonArray,
  43. BOOL* pbLoadedStrings,
  44. CString** pastrStringArray,
  45. UINT cButtons
  46. )
  47. {
  48. ASSERT( NULL != pbLoadedStrings &&
  49. NULL != pButtonArray &&
  50. NULL != pastrStringArray);
  51. if ( !*pbLoadedStrings )
  52. {
  53. // load strings
  54. MMCBUTTON* pLoadButtonArray = pButtonArray;
  55. UINT cLoadButtons = cButtons;
  56. *pastrStringArray = new CString[2*cButtons];
  57. for (UINT i = 0; i < cButtons; i++)
  58. {
  59. UINT iButtonTextId = 0, iTooltipTextId = 0;
  60. switch (pButtonArray[i].idCommand)
  61. {
  62. case IDS_BUTTON_NEWSHARE:
  63. iButtonTextId = IDS_BUTTON_NEWSHARE;
  64. iTooltipTextId = IDS_TOOLTIP_NEWSHARE;
  65. break;
  66. case cmServiceResume:
  67. iButtonTextId = IDS_BUTTON_SERVICE_RESUME;
  68. iTooltipTextId = IDS_TOOLTIP_SERVICE_RESUME;
  69. break;
  70. case cmServiceStart:
  71. iButtonTextId = IDS_BUTTON_SERVICE_START;
  72. iTooltipTextId = IDS_TOOLTIP_SERVICE_START;
  73. break;
  74. case cmServiceStop:
  75. iButtonTextId = IDS_BUTTON_SERVICE_STOP;
  76. iTooltipTextId = IDS_TOOLTIP_SERVICE_STOP;
  77. break;
  78. case cmServicePause:
  79. iButtonTextId = IDS_BUTTON_SERVICE_PAUSE;
  80. iTooltipTextId = IDS_TOOLTIP_SERVICE_PAUSE;
  81. break;
  82. case cmServiceRestart:
  83. iButtonTextId = IDS_BUTTON_SERVICE_RESTART;
  84. iTooltipTextId = IDS_TOOLTIP_SERVICE_RESTART;
  85. break;
  86. default:
  87. ASSERT(FALSE);
  88. break;
  89. }
  90. VERIFY( (*pastrStringArray)[i*2].LoadString(iButtonTextId) );
  91. pButtonArray[i].lpButtonText =
  92. const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[i*2]));
  93. VERIFY( (*pastrStringArray)[(i*2)+1].LoadString(iTooltipTextId) );
  94. pButtonArray[i].lpTooltipText =
  95. const_cast<BSTR>((LPCTSTR)((*pastrStringArray)[(i*2)+1]));
  96. }
  97. *pbLoadedStrings = TRUE;
  98. }
  99. }
  100. HRESULT LoadToolbar(
  101. LPTOOLBAR pToolbar,
  102. CBitmap& refbitmap,
  103. MMCBUTTON* pButtonArray,
  104. UINT cButtons
  105. )
  106. {
  107. ASSERT( NULL != pToolbar &&
  108. NULL != pButtonArray );
  109. HRESULT hr = pToolbar->AddBitmap(cButtons, refbitmap, 16, 16, RGB(255,0,255) );
  110. if ( FAILED(hr) )
  111. {
  112. ASSERT(FALSE);
  113. return hr;
  114. }
  115. hr = pToolbar->AddButtons(cButtons, pButtonArray);
  116. if ( FAILED(hr) )
  117. {
  118. ASSERT(FALSE);
  119. return hr;
  120. }
  121. return hr;
  122. }
  123. STDMETHODIMP CFileMgmtComponent::SetControlbar(LPCONTROLBAR pControlbar)
  124. {
  125. MFC_TRY;
  126. SAFE_RELEASE(m_pControlbar); // just in case
  127. if (NULL != pControlbar)
  128. {
  129. m_pControlbar = pControlbar; // CODEWORK should use smartpointer
  130. m_pControlbar->AddRef();
  131. }
  132. return S_OK;
  133. MFC_CATCH;
  134. }
  135. STDMETHODIMP CFileMgmtComponent::ControlbarNotify(MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param)
  136. {
  137. MFC_TRY;
  138. #ifdef SNAPIN_PROTOTYPER
  139. return S_OK;
  140. #endif
  141. HRESULT hr=S_OK;
  142. switch (event)
  143. {
  144. case MMCN_BTN_CLICK:
  145. TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_BTN_CLICK\n"));
  146. {
  147. LPDATAOBJECT pDataObject = reinterpret_cast<LPDATAOBJECT>(arg);
  148. UINT idButton = (UINT)param;
  149. hr = OnToolbarButton( pDataObject, idButton );
  150. }
  151. break;
  152. case MMCN_SELECT:
  153. TRACE(_T("CFileMgmtComponent::ControlbarNotify - MMCN_SELECT\n"));
  154. {
  155. if (!(LOWORD(arg))) // bScope
  156. {
  157. // result pane
  158. hr = UpdateToolbar(
  159. reinterpret_cast<LPDATAOBJECT>(param),
  160. !!(HIWORD(arg)) );
  161. }
  162. else
  163. {
  164. // scope pane
  165. hr = AddToolbar( reinterpret_cast<LPDATAOBJECT>(param),
  166. !!(HIWORD(arg)) );
  167. }
  168. }
  169. break;
  170. default:
  171. ASSERT(FALSE); // Unhandled event
  172. }
  173. return hr;
  174. MFC_CATCH;
  175. }
  176. HRESULT CFileMgmtComponent::ServiceToolbarButtonState(
  177. LPDATAOBJECT pServiceDataObject,
  178. BOOL fSelected )
  179. {
  180. BOOL rgfMenuFlags[iServiceActionMax];
  181. for (INT i = 0; i < iServiceActionMax; i++)
  182. rgfMenuFlags[i] = FALSE;
  183. if ( fSelected )
  184. {
  185. CString strMachineName;
  186. CString strServiceName;
  187. if (!QueryComponentDataRef().Service_FGetServiceInfoFromIDataObject(
  188. pServiceDataObject,
  189. OUT &strMachineName,
  190. OUT &strServiceName,
  191. NULL))
  192. {
  193. ASSERT(FALSE);
  194. }
  195. else
  196. {
  197. if (strMachineName.IsEmpty())
  198. strMachineName = g_strLocalMachine;
  199. // Get the menu flags
  200. {
  201. ASSERT(NULL != QueryComponentDataRef().m_hScManager);
  202. CWaitCursor wait;
  203. if (!Service_FGetServiceButtonStatus( // this will report errors itself
  204. QueryComponentDataRef().m_hScManager,
  205. strServiceName,
  206. OUT rgfMenuFlags,
  207. NULL, // pdwCurrentState
  208. TRUE)) // fSilentError
  209. {
  210. // let's not do this m_hScManager = NULL;
  211. }
  212. }
  213. }
  214. }
  215. // update toolbar
  216. ASSERT( NULL != m_pSvcMgmtToolbar );
  217. //
  218. // JonN 5/2/00 106431:
  219. // Services snapin calls DeleteButton with an index but never called InsertButton
  220. //
  221. // HRESULT hr = m_pSvcMgmtToolbar->DeleteButton(0);
  222. // if ( FAILED(hr) )
  223. // return hr;
  224. HRESULT hr = S_OK;
  225. // JonN 3/15/01 210065
  226. // Services snapin: "Resume service" toolbar button stays enabled after it is first displayed
  227. BOOL fShowResumeButton = !rgfMenuFlags[iServiceActionStart] &&
  228. rgfMenuFlags[iServiceActionResume];
  229. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  230. cmServiceStart, HIDDEN, fShowResumeButton)));
  231. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  232. cmServiceResume, HIDDEN, !fShowResumeButton)));
  233. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  234. cmServiceStart, ENABLED, rgfMenuFlags[iServiceActionStart])));
  235. VERIFY( SUCCEEDED( m_pSvcMgmtToolbar->SetButtonState(
  236. cmServiceResume, ENABLED, rgfMenuFlags[iServiceActionResume])));
  237. hr = m_pSvcMgmtToolbar->SetButtonState(
  238. cmServiceStop, ENABLED, rgfMenuFlags[iServiceActionStop] );
  239. if ( FAILED(hr) )
  240. return hr;
  241. hr = m_pSvcMgmtToolbar->SetButtonState(
  242. cmServicePause, ENABLED, rgfMenuFlags[iServiceActionPause] );
  243. if ( FAILED(hr) )
  244. return hr;
  245. hr = m_pSvcMgmtToolbar->SetButtonState(
  246. cmServiceRestart, ENABLED, rgfMenuFlags[iServiceActionRestart] );
  247. return hr;
  248. }
  249. // CODEWORK The following algorithm is imperfect, but will do
  250. // for now. We ignore the old selection, and attach
  251. // our fixed toolbar iff the new selection is our type.
  252. HRESULT CFileMgmtComponent::AddToolbar(LPDATAOBJECT pdoScopeIsSelected,
  253. BOOL fSelected)
  254. {
  255. HRESULT hr = S_OK;
  256. int i = 0;
  257. GUID guidSelectedObject;
  258. do { // false loop
  259. if (NULL == pdoScopeIsSelected)
  260. {
  261. // toolbar will be automatically detached
  262. return S_OK;
  263. }
  264. if ( FAILED(ExtractObjectTypeGUID(pdoScopeIsSelected,
  265. &guidSelectedObject)) )
  266. {
  267. ASSERT(FALSE); // shouldn't have given me non-MMC data object
  268. return S_OK;
  269. }
  270. if (NULL == m_pControlbar)
  271. {
  272. ASSERT(FALSE);
  273. return S_OK;
  274. }
  275. #ifdef DEBUG
  276. if ( QueryComponentDataRef().IsExtendedNodetype(guidSelectedObject) )
  277. {
  278. ASSERT(FALSE && "shouldn't have given me extension parent nodetype");
  279. return S_OK;
  280. }
  281. #endif
  282. switch (CheckObjectTypeGUID( &guidSelectedObject ) )
  283. {
  284. case FILEMGMT_SHARES:
  285. if (QueryComponentDataRef().GetIsSimpleUI() || IsServiceSnapin())
  286. break;
  287. if (NULL == m_pFileMgmtToolbar)
  288. {
  289. hr = m_pControlbar->Create(
  290. TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pFileMgmtToolbar) );
  291. if ( FAILED(hr) )
  292. {
  293. ASSERT(FALSE);
  294. break;
  295. }
  296. ASSERT(NULL != m_pFileMgmtToolbar);
  297. if ( !QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap )
  298. {
  299. VERIFY( QueryComponentDataRef().m_bmpFileMgmtToolbar.LoadBitmap(
  300. IDB_FILEMGMT_TOOLBAR ) );
  301. QueryComponentDataRef().m_fLoadedFileMgmtToolbarBitmap = TRUE;
  302. }
  303. LoadButtonArray(
  304. g_FileMgmtSnapinButtons,
  305. &g_bLoadedFileMgmtStrings,
  306. &g_astrFileMgmtButtonStrings,
  307. ARRAYLEN(g_FileMgmtSnapinButtons)
  308. );
  309. hr = LoadToolbar(
  310. m_pFileMgmtToolbar,
  311. QueryComponentDataRef().m_bmpFileMgmtToolbar,
  312. g_FileMgmtSnapinButtons,
  313. ARRAYLEN(g_FileMgmtSnapinButtons)
  314. );
  315. }
  316. if (FAILED(hr))
  317. break;
  318. // New Share is always enabled
  319. VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pFileMgmtToolbar)) );
  320. for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
  321. m_pFileMgmtToolbar->SetButtonState(
  322. g_FileMgmtSnapinButtons[i].idCommand,
  323. ENABLED,
  324. fSelected);
  325. }
  326. break;
  327. case FILEMGMT_SERVICES:
  328. if ( !IsServiceSnapin() )
  329. break;
  330. if (NULL == m_pSvcMgmtToolbar)
  331. {
  332. hr = m_pControlbar->Create(
  333. TOOLBAR, this, reinterpret_cast<LPUNKNOWN*>(&m_pSvcMgmtToolbar) );
  334. if ( FAILED(hr) )
  335. {
  336. ASSERT(FALSE);
  337. break;
  338. }
  339. ASSERT(NULL != m_pSvcMgmtToolbar);
  340. if ( !QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap )
  341. {
  342. VERIFY( QueryComponentDataRef().m_bmpSvcMgmtToolbar.LoadBitmap(
  343. IDB_SVCMGMT_TOOLBAR ) );
  344. QueryComponentDataRef().m_fLoadedSvcMgmtToolbarBitmap = TRUE;
  345. }
  346. LoadButtonArray(
  347. g_SvcMgmtSnapinButtons,
  348. &g_bLoadedSvcMgmtStrings,
  349. &g_astrSvcMgmtButtonStrings,
  350. ARRAYLEN(g_SvcMgmtSnapinButtons)
  351. );
  352. // JonN 3/15/01 210065
  353. // "Resume service" toolbar button stays enabled after it is first displayed
  354. hr = LoadToolbar(
  355. m_pSvcMgmtToolbar,
  356. QueryComponentDataRef().m_bmpSvcMgmtToolbar,
  357. g_SvcMgmtSnapinButtons,
  358. ARRAYLEN(g_SvcMgmtSnapinButtons)
  359. );
  360. }
  361. if (FAILED(hr))
  362. break;
  363. VERIFY( SUCCEEDED(m_pControlbar->Attach(TOOLBAR, (LPUNKNOWN) m_pSvcMgmtToolbar)) );
  364. break;
  365. case FILEMGMT_ROOT:
  366. case FILEMGMT_SESSIONS:
  367. case FILEMGMT_RESOURCES:
  368. if (m_pControlbar && m_pFileMgmtToolbar)
  369. {
  370. m_pControlbar->Detach(m_pFileMgmtToolbar);
  371. }
  372. break;
  373. #ifdef SNAPIN_PROTOTYPER
  374. case FILEMGMT_PROTOTYPER:
  375. break; // no toolbar
  376. case FILEMGMT_PROTOTYPER_LEAF:
  377. break; // no toolbar
  378. #endif
  379. default:
  380. ASSERT(FALSE); // unknown type
  381. break;
  382. }
  383. } while (FALSE); // false loop
  384. return hr;
  385. }
  386. HRESULT CFileMgmtComponent::UpdateToolbar(
  387. LPDATAOBJECT pdoResultIsSelected,
  388. BOOL fSelected )
  389. {
  390. int i = 0;
  391. GUID guidSelectedObject;
  392. if ( FAILED(ExtractObjectTypeGUID(pdoResultIsSelected,
  393. &guidSelectedObject)) )
  394. {
  395. ASSERT(FALSE); // shouldn't have given me non-MMC data object
  396. return S_OK;
  397. }
  398. int objecttype = CheckObjectTypeGUID( &guidSelectedObject );
  399. switch (objecttype)
  400. {
  401. case FILEMGMT_SERVICE:
  402. ServiceToolbarButtonState( pdoResultIsSelected, fSelected );
  403. break;
  404. case FILEMGMT_SHARES:
  405. if (m_pControlbar && m_pFileMgmtToolbar && !QueryComponentDataRef().GetIsSimpleUI())
  406. {
  407. m_pControlbar->Attach(TOOLBAR, m_pFileMgmtToolbar);
  408. for (i = 0; i < ARRAYLEN(g_FileMgmtSnapinButtons); i++) {
  409. m_pFileMgmtToolbar->SetButtonState(
  410. g_FileMgmtSnapinButtons[i].idCommand,
  411. ENABLED,
  412. fSelected);
  413. }
  414. }
  415. break;
  416. case FILEMGMT_SHARE:
  417. case FILEMGMT_SESSIONS:
  418. case FILEMGMT_RESOURCES:
  419. if (m_pControlbar && m_pFileMgmtToolbar)
  420. {
  421. m_pControlbar->Detach(m_pFileMgmtToolbar);
  422. }
  423. case FILEMGMT_SESSION:
  424. case FILEMGMT_RESOURCE:
  425. break;
  426. default:
  427. break;
  428. }
  429. return S_OK;
  430. }
  431. HRESULT CFileMgmtComponent::OnToolbarButton(LPDATAOBJECT pDataObject, UINT idButton)
  432. {
  433. switch (idButton)
  434. {
  435. case IDS_BUTTON_NEWSHARE:
  436. {
  437. BOOL fRefresh = QueryComponentDataRef().NewShare( pDataObject );
  438. if (fRefresh)
  439. {
  440. // JonN 12/03/98 updated to use new method
  441. VERIFY(SUCCEEDED( RefreshAllViews(pDataObject) ));
  442. }
  443. }
  444. break;
  445. case cmServiceStart:
  446. case cmServiceStop:
  447. case cmServicePause:
  448. case cmServiceResume:
  449. case cmServiceRestart:
  450. VERIFY( SUCCEEDED(Command(idButton, pDataObject)) );
  451. break;
  452. default:
  453. ASSERT(FALSE);
  454. break;
  455. }
  456. return S_OK;
  457. }