Leaked source code of windows server 2003
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.

4468 lines
131 KiB

  1. /*--------------------------------------------------------------------------*
  2. *
  3. * Microsoft Windows
  4. * Copyright (C) Microsoft Corporation, 1992 - 1999
  5. *
  6. * File: taskui.cpp
  7. *
  8. * Contents: Implementation file for console taskpad UI classes.
  9. *
  10. * History: 29-Oct-98 jeffro Created
  11. *
  12. *--------------------------------------------------------------------------*/
  13. #include "stdafx.h"
  14. #include "tasks.h"
  15. #include "nodepath.h"
  16. #include "oncmenu.h"
  17. #include "scopndcb.h"
  18. #include "rsltitem.h"
  19. #include "conview.h"
  20. #include "conframe.h"
  21. #include "bitmap.h"
  22. #include "util.h"
  23. //############################################################################
  24. //############################################################################
  25. //
  26. // Implementation of class CTaskpadFrame
  27. //
  28. //############################################################################
  29. //############################################################################
  30. CTaskpadFrame::CTaskpadFrame(CNode *pNodeTarget, CConsoleTaskpad* pConsoleTaskpad, CViewData *pViewData,
  31. bool fCookieValid, LPARAM lCookie)
  32. {
  33. m_pNodeTarget = pNodeTarget;
  34. m_pConsoleTaskpad = pConsoleTaskpad;
  35. m_pViewData = pViewData;
  36. m_fCookieValid = fCookieValid;
  37. m_lCookie = lCookie;
  38. if(pConsoleTaskpad)
  39. m_pConsoleTaskpad = pConsoleTaskpad;
  40. else
  41. m_pConsoleTaskpad = new CConsoleTaskpad();
  42. m_fNew = (pConsoleTaskpad == NULL);
  43. m_bTargetNodeSelected = (pNodeTarget != NULL);
  44. }
  45. CTaskpadFrame::CTaskpadFrame(const CTaskpadFrame &rhs)
  46. {
  47. m_pNodeTarget = rhs.m_pNodeTarget;
  48. m_pConsoleTaskpad = rhs.m_pConsoleTaskpad;
  49. m_pViewData = rhs.m_pViewData;
  50. m_fCookieValid = rhs.m_fCookieValid;
  51. m_fNew = rhs.m_fNew;
  52. m_lCookie = rhs.m_lCookie;
  53. m_bTargetNodeSelected = rhs.m_bTargetNodeSelected;
  54. }
  55. //############################################################################
  56. //############################################################################
  57. //
  58. // Implementation of class CWizardPage
  59. //
  60. //############################################################################
  61. //############################################################################
  62. WTL::CFont CWizardPage::m_fontWelcome;
  63. void CWizardPage::OnWelcomeSetActive(HWND hWnd)
  64. {
  65. WTL::CPropertySheetWindow(::GetParent(hWnd)).SetWizardButtons (PSWIZB_NEXT);
  66. }
  67. void CWizardPage::OnWelcomeKillActive(HWND hWnd)
  68. {
  69. WTL::CPropertySheetWindow(::GetParent(hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT);
  70. }
  71. void CWizardPage::InitFonts(HWND hWnd)
  72. {
  73. if (m_fontWelcome.m_hFont != NULL)
  74. return;
  75. CWindow wnd = hWnd;
  76. WTL::CClientDC dc (wnd);
  77. if (dc.m_hDC == NULL)
  78. return;
  79. // set the correct font for the title.
  80. LOGFONT lf;
  81. WTL::CFont fontDefault = wnd.GetFont();
  82. fontDefault.GetLogFont(&lf);
  83. fontDefault.Detach();
  84. // set the correct font for the welcome line
  85. CStr strWelcomeFont;
  86. strWelcomeFont.LoadString(GetStringModule(), IDS_WizardTitleFont);
  87. CStr strWelcomeFontSize;
  88. strWelcomeFont.LoadString(GetStringModule(), IDS_WizardTitleFontSize);
  89. int nPointSize = _ttoi(strWelcomeFont);
  90. lf.lfWeight = FW_BOLD;
  91. lf.lfHeight = -MulDiv(nPointSize, dc.GetDeviceCaps(LOGPIXELSY), 72);
  92. lf.lfWidth = 0;
  93. SC sc = StringCchCopy(lf.lfFaceName, countof(lf.lfFaceName), strWelcomeFont);
  94. if(sc)
  95. sc.TraceAndClear();
  96. m_fontWelcome.CreateFontIndirect(&lf);
  97. }
  98. void CWizardPage::OnInitWelcomePage(HWND hDlg)
  99. {
  100. InitFonts(hDlg);
  101. CWindow wndTitle = ::GetDlgItem (hDlg, IDC_WELCOME);
  102. wndTitle.SetFont (m_fontWelcome);
  103. }
  104. void CWizardPage::OnInitFinishPage(HWND hDlg)
  105. {
  106. InitFonts(hDlg);
  107. CWindow wndTitle = ::GetDlgItem (hDlg, IDC_COMPLETING);
  108. wndTitle.SetFont (m_fontWelcome);
  109. WTL::CPropertySheetWindow(::GetParent(hDlg)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH);
  110. }
  111. //############################################################################
  112. //############################################################################
  113. //
  114. // Implementation of class CTaskpadPropertySheet
  115. //
  116. //############################################################################
  117. //############################################################################
  118. /* CTaskpadPropertySheet::CTaskpadPropertySheet
  119. *
  120. * PURPOSE: Constructor
  121. *
  122. * PARAMETERS: None
  123. *
  124. */
  125. CTaskpadPropertySheet::CTaskpadPropertySheet(CNode *pNodeTarget, CConsoleTaskpad & rConsoleTaskpad, bool fNew,
  126. LPARAM lparamSelectedNode, bool fLParamValid, CViewData *pViewData, eReason reason):
  127. BC(),
  128. CTaskpadFrame(pNodeTarget, &rConsoleTaskpad, pViewData, fLParamValid,
  129. lparamSelectedNode),
  130. m_proppTaskpadGeneral(this),
  131. m_proppTasks(this, (reason == eReason_NEWTASK)? true : false),
  132. m_fInsertNode(false),
  133. m_fNew(fNew),
  134. m_eReason(reason)
  135. {
  136. // Add the property pages
  137. AddPage( m_proppTaskpadGeneral );
  138. if(!fNew)
  139. AddPage( m_proppTasks );
  140. if(Reason()==eReason_NEWTASK)
  141. {
  142. ASSERT(!fNew);
  143. SetActivePage(1); // the tasks page
  144. }
  145. /*
  146. * give the property sheet a title (the string must be a member so
  147. * it lives until DoModal, where it will actually get used.
  148. */
  149. m_strTitle = rConsoleTaskpad.GetName();
  150. /*
  151. * HACK: We should be able to use
  152. *
  153. * SetTitle (m_strTitle.data(), PSH_PROPTITLE);
  154. *
  155. * but ATL21 has a bogus assert (it asserts (lpszText == NULL)
  156. * instead of (lpszText != NULL).
  157. */
  158. // SetTitle (m_strTitle.data(), PSH_PROPTITLE);
  159. m_psh.pszCaption = m_strTitle.data();
  160. m_psh.dwFlags |= PSH_PROPTITLE;
  161. // hide the Apply button
  162. m_psh.dwFlags |= PSH_NOAPPLYNOW;
  163. }
  164. /*+-------------------------------------------------------------------------*
  165. * CTaskpadPropertySheet::~CTaskpadPropertySheet
  166. *
  167. * PURPOSE:
  168. *
  169. * PARAMETERS:
  170. *
  171. * RETURNS:
  172. *
  173. /*+-------------------------------------------------------------------------*/
  174. CTaskpadPropertySheet::~CTaskpadPropertySheet()
  175. {
  176. }
  177. /*+-------------------------------------------------------------------------*
  178. * CTaskpadPropertySheet::DoModal
  179. *
  180. * PURPOSE:
  181. *
  182. * PARAMETERS:
  183. *
  184. * RETURNS:
  185. * int
  186. /*+-------------------------------------------------------------------------*/
  187. int
  188. CTaskpadPropertySheet::DoModal()
  189. {
  190. // save the current taskpad in case the user wants to cancel.
  191. CConsoleTaskpad*pConsoleTaskpad = PConsoleTaskpad();
  192. CConsoleTaskpad consoleTaskpad = *PConsoleTaskpad(); // make a copy
  193. CTaskpadFrame::m_pConsoleTaskpad = &consoleTaskpad; // make modifications on the copy.
  194. // call the base class method to make changes on the copy.
  195. int iResp = BC::DoModal();
  196. if(iResp == IDOK)
  197. {
  198. *pConsoleTaskpad = consoleTaskpad; // commit changes
  199. pConsoleTaskpad->SetDirty(true);
  200. }
  201. return iResp;
  202. }
  203. //############################################################################
  204. //############################################################################
  205. //
  206. // Implementation of class CTaskpadWizard
  207. //
  208. //############################################################################
  209. //############################################################################
  210. CTaskpadWizard::CTaskpadWizard(
  211. CNode* pNodeTarget,
  212. CConsoleTaskpad& rConsoleTaskPad,
  213. bool fNew,
  214. LPARAM lparamSelectedNode,
  215. bool fLParamValid,
  216. CViewData* pViewData)
  217. :
  218. BC(pNodeTarget, &rConsoleTaskPad, pViewData, fLParamValid, lparamSelectedNode)
  219. {
  220. BC::SetNew(fNew);
  221. };
  222. HRESULT
  223. CTaskpadWizard::Show(HWND hWndParent, bool *pfStartTaskWizard)
  224. {
  225. USES_CONVERSION;
  226. *pfStartTaskWizard = false;
  227. // save the current taskpad in case the user wants to cancel.
  228. CConsoleTaskpad*pConsoleTaskpad = PConsoleTaskpad();
  229. CConsoleTaskpad consoleTaskpad = *PConsoleTaskpad(); // make a copy
  230. CTaskpadFrame::m_pConsoleTaskpad = &consoleTaskpad; // make modifications on the copy.
  231. // create a property sheet
  232. IFramePrivatePtr spFrame;
  233. spFrame.CreateInstance(CLSID_NodeInit,
  234. #if _MSC_VER >= 1100
  235. NULL,
  236. #endif
  237. MMC_CLSCTX_INPROC);
  238. IPropertySheetProviderPtr pIPSP = spFrame;
  239. if (pIPSP == NULL)
  240. return S_FALSE;
  241. HRESULT hr = pIPSP->CreatePropertySheet (L"Cool :-)", FALSE, NULL, NULL,
  242. MMC_PSO_NEWWIZARDTYPE);
  243. CHECK_HRESULT(hr);
  244. RETURN_ON_FAIL(hr);
  245. // create property pages
  246. CTaskpadWizardWelcomePage welcomePage;
  247. CTaskpadStylePage stylePage(this);
  248. CTaskpadNodetypePage nodetypePage(this);
  249. CTaskpadNamePage namePage(this);
  250. CTaskpadWizardFinishPage finishPage(pfStartTaskWizard);
  251. // create the pages we'll add in IExtendPropertySheet::CreatePropertyPages
  252. CExtendPropSheet* peps;
  253. hr = CExtendPropSheet::CreateInstance (&peps);
  254. CHECK_HRESULT(hr);
  255. RETURN_ON_FAIL(hr);
  256. /*
  257. * destroying this object will take care of releasing our ref on peps
  258. */
  259. IUnknownPtr spUnk = peps;
  260. ASSERT (spUnk != NULL);
  261. peps->SetWatermarkID (IDB_TASKPAD_WIZARD_WELCOME);
  262. peps->SetHeaderID (IDB_TASKPAD_WIZARD_HEADER);
  263. peps->AddPage (welcomePage.Create());
  264. peps->AddPage (stylePage.Create());
  265. peps->AddPage (nodetypePage.Create());
  266. peps->AddPage (namePage.Create());
  267. peps->AddPage (finishPage.Create());
  268. hr = pIPSP->AddPrimaryPages(spUnk, FALSE, NULL, FALSE);
  269. CHECK_HRESULT(hr);
  270. hr = pIPSP->Show((LONG_PTR)hWndParent, 0);
  271. CHECK_HRESULT(hr);
  272. if(hr==S_OK)
  273. {
  274. // need to do this explicitly - wizards don't get an OnApply message. Bummer.
  275. nodetypePage.OnApply();
  276. *pConsoleTaskpad = consoleTaskpad; // commit changes
  277. pConsoleTaskpad->SetDirty(true);
  278. }
  279. return hr;
  280. }
  281. //############################################################################
  282. //############################################################################
  283. //
  284. // Implementation of class CExtendPropSheetImpl
  285. //
  286. //############################################################################
  287. //############################################################################
  288. /*+-------------------------------------------------------------------------*
  289. * CPropertySheetInserter
  290. *
  291. * Simple output iterator that will add pages to an MMC property sheet
  292. * by way of IPropertySheetCallback.
  293. *--------------------------------------------------------------------------*/
  294. class CPropertySheetInserter : std::iterator<std::output_iterator_tag, void, void>
  295. {
  296. public:
  297. CPropertySheetInserter (IPropertySheetCallback* pPropSheetCallback) :
  298. m_spPropSheetCallback (pPropSheetCallback)
  299. {}
  300. CPropertySheetInserter& operator=(HANDLE hPage)
  301. {
  302. m_spPropSheetCallback->AddPage ((HPROPSHEETPAGE) hPage);
  303. return (*this);
  304. }
  305. CPropertySheetInserter& operator*()
  306. { return (*this); }
  307. CPropertySheetInserter& operator++()
  308. { return (*this); }
  309. CPropertySheetInserter operator++(int)
  310. { return (*this); }
  311. protected:
  312. IPropertySheetCallbackPtr m_spPropSheetCallback;
  313. };
  314. /*+-------------------------------------------------------------------------*
  315. * CExtendPropSheetImpl::AddPage
  316. *
  317. *
  318. *--------------------------------------------------------------------------*/
  319. void CExtendPropSheetImpl::AddPage (HPROPSHEETPAGE hPage)
  320. {
  321. m_vPages.push_back ((HANDLE) hPage);
  322. }
  323. /*+-------------------------------------------------------------------------*
  324. * CExtendPropSheetImpl::SetHeaderID
  325. *
  326. *
  327. *--------------------------------------------------------------------------*/
  328. void CExtendPropSheetImpl::SetHeaderID (int nHeaderID)
  329. {
  330. m_nHeaderID = nHeaderID;
  331. }
  332. /*+-------------------------------------------------------------------------*
  333. * CExtendPropSheetImpl::SetWatermarkID
  334. *
  335. *
  336. *--------------------------------------------------------------------------*/
  337. void CExtendPropSheetImpl::SetWatermarkID (int nWatermarkID)
  338. {
  339. m_nWatermarkID = nWatermarkID;
  340. }
  341. /*+-------------------------------------------------------------------------*
  342. * CExtendPropSheetImpl::CreatePropertyPages
  343. *
  344. *
  345. *--------------------------------------------------------------------------*/
  346. STDMETHODIMP CExtendPropSheetImpl::CreatePropertyPages (IPropertySheetCallback* pPSC, LONG_PTR handle, IDataObject* pDO)
  347. {
  348. std::copy (m_vPages.begin(), m_vPages.end(), CPropertySheetInserter(pPSC));
  349. return (S_OK);
  350. }
  351. /*+-------------------------------------------------------------------------*
  352. * CExtendPropSheetImpl::QueryPagesFor
  353. *
  354. *
  355. *--------------------------------------------------------------------------*/
  356. STDMETHODIMP CExtendPropSheetImpl::QueryPagesFor (IDataObject* pDO)
  357. {
  358. return (S_OK);
  359. }
  360. /*+-------------------------------------------------------------------------*
  361. * CExtendPropSheetImpl::GetWatermarks
  362. *
  363. *
  364. *--------------------------------------------------------------------------*/
  365. STDMETHODIMP CExtendPropSheetImpl::GetWatermarks (IDataObject* pDO, HBITMAP* phbmWatermark, HBITMAP* phbmHeader, HPALETTE* phPal, BOOL* pbStretch)
  366. {
  367. *phbmWatermark = (m_nWatermarkID)
  368. ? LoadBitmap (_Module.GetResourceInstance(),
  369. MAKEINTRESOURCE (m_nWatermarkID))
  370. : NULL;
  371. ASSERT ((m_nWatermarkID == 0) || (*phbmWatermark != NULL));
  372. *phbmHeader = (m_nHeaderID)
  373. ? LoadBitmap (_Module.GetResourceInstance(),
  374. MAKEINTRESOURCE (m_nHeaderID))
  375. : NULL;
  376. ASSERT ((m_nHeaderID == 0) || (*phbmHeader != NULL));
  377. *phPal = NULL;
  378. *pbStretch = false;
  379. return (S_OK);
  380. }
  381. //############################################################################
  382. //############################################################################
  383. //
  384. // Implementation of class CTaskpadNamePage
  385. //
  386. //############################################################################
  387. //############################################################################
  388. CTaskpadNamePage::CTaskpadNamePage(CTaskpadFrame * pTaskpadFrame)
  389. : CTaskpadFramePtr(pTaskpadFrame)
  390. {
  391. }
  392. BOOL
  393. CTaskpadNamePage::OnSetActive()
  394. {
  395. // Set the correct wizard buttons.
  396. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT);
  397. m_strName. Initialize (this, IDC_TASKPAD_TITLE, -1, PConsoleTaskpad()->GetName().data());
  398. m_strDescription.Initialize (this, IDC_TASKPAD_DESCRIPTION,-1, PConsoleTaskpad()->GetDescription().data());
  399. return true;
  400. }
  401. int
  402. CTaskpadNamePage::OnWizardNext()
  403. {
  404. tstring strName = MMC::GetWindowText (m_strName);
  405. if (strName.empty())
  406. {
  407. CStr strTitle;
  408. strTitle.LoadString(GetStringModule(), IDS_TASKPAD_NAME_REQUIRED_ERROR);
  409. MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION);
  410. return -1;
  411. }
  412. tstring strDescription = MMC::GetWindowText (m_strDescription);
  413. CConsoleTaskpad* pTaskpad = PConsoleTaskpad();
  414. pTaskpad->SetName (strName);
  415. pTaskpad->SetDescription (strDescription);
  416. return 0;
  417. }
  418. int
  419. CTaskpadNamePage::OnWizardBack()
  420. {
  421. return 0;
  422. }
  423. //############################################################################
  424. //############################################################################
  425. //
  426. // Implementation of class CTaskpadWizardWelcomePage
  427. //
  428. //############################################################################
  429. //############################################################################
  430. LRESULT CTaskpadWizardWelcomePage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  431. {
  432. CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font
  433. return 0;
  434. }
  435. bool
  436. CTaskpadWizardWelcomePage::OnSetActive()
  437. {
  438. CWizardPage::OnWelcomeSetActive(m_hWnd);
  439. return true;
  440. }
  441. bool
  442. CTaskpadWizardWelcomePage::OnKillActive()
  443. {
  444. CWizardPage::OnWelcomeKillActive(m_hWnd);
  445. return true;
  446. }
  447. //############################################################################
  448. //############################################################################
  449. //
  450. // Implementation of class CTaskpadWizardFinishPage
  451. //
  452. //############################################################################
  453. //############################################################################
  454. LRESULT CTaskpadWizardFinishPage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  455. {
  456. CWizardPage::OnInitFinishPage(m_hWnd); // set up the correct title font
  457. CheckDlgButton(IDC_START_TASK_WIZARD, BST_CHECKED);
  458. return 0;
  459. }
  460. BOOL
  461. CTaskpadWizardFinishPage::OnSetActive()
  462. {
  463. // Set the correct wizard buttons.
  464. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH);
  465. return true;
  466. }
  467. BOOL
  468. CTaskpadWizardFinishPage::OnWizardFinish()
  469. {
  470. *m_pfStartTaskWizard = (IsDlgButtonChecked(IDC_START_TASK_WIZARD)==BST_CHECKED);
  471. return TRUE;
  472. }
  473. //############################################################################
  474. //############################################################################
  475. //
  476. // Implementation of class CTaskpadStyle
  477. //
  478. //############################################################################
  479. //############################################################################
  480. CTaskpadStyle::CTaskpadStyle (
  481. ListSize eSize,
  482. int idsDescription,
  483. int nPreviewBitmapID,
  484. DWORD dwOrientation)
  485. :
  486. m_eSize (eSize),
  487. m_idsDescription (idsDescription),
  488. m_nPreviewBitmapID (nPreviewBitmapID),
  489. m_dwOrientation (dwOrientation)
  490. {
  491. }
  492. CTaskpadStyle::CTaskpadStyle (
  493. ListSize eSize,
  494. DWORD dwOrientation)
  495. :
  496. m_eSize (eSize),
  497. m_idsDescription (0),
  498. m_nPreviewBitmapID (0),
  499. m_dwOrientation (dwOrientation)
  500. {
  501. }
  502. CTaskpadStyle::CTaskpadStyle (const CTaskpadStyle& other)
  503. {
  504. *this = other;
  505. }
  506. /*+-------------------------------------------------------------------------*
  507. * CTaskpadStyle::operator=
  508. *
  509. * Custom assignment operator for CTaskpadStyle that does a deep copy of
  510. * its contained WTL::CBitmap.
  511. *--------------------------------------------------------------------------*/
  512. CTaskpadStyle& CTaskpadStyle::operator= (const CTaskpadStyle& other)
  513. {
  514. if (this != &other)
  515. {
  516. m_eSize = other.m_eSize;
  517. m_idsDescription = other.m_idsDescription;
  518. m_nPreviewBitmapID = other.m_nPreviewBitmapID;
  519. m_dwOrientation = other.m_dwOrientation;
  520. m_strDescription = other.m_strDescription;
  521. /*
  522. * WTL::CBitmap does a shallow copy of the bitmap. We need to
  523. * do a deep copy here so (*this) and (other) don't both
  524. * DeleteObject the same bitmap.
  525. */
  526. if (!m_PreviewBitmap.IsNull())
  527. m_PreviewBitmap.DeleteObject();
  528. m_PreviewBitmap = CopyBitmap (other.m_PreviewBitmap);
  529. }
  530. return (*this);
  531. }
  532. //############################################################################
  533. //############################################################################
  534. //
  535. // Implementation of class CTaskpadStyleBase
  536. //
  537. //############################################################################
  538. //############################################################################
  539. // static variables
  540. CTaskpadStyle
  541. CTaskpadStyleBase::s_rgTaskpadStyle[] =
  542. {
  543. // Size Description Bitmap dwOrientation
  544. CTaskpadStyle (eSize_Small, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzSml, TVO_HORIZONTAL),
  545. CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzMed, TVO_HORIZONTAL),
  546. CTaskpadStyle (eSize_Large, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzLrg, TVO_HORIZONTAL),
  547. CTaskpadStyle (eSize_Small, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzSmlD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT),
  548. CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzMedD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT),
  549. CTaskpadStyle (eSize_Large, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzLrgD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT),
  550. CTaskpadStyle (eSize_Small, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertSml, TVO_VERTICAL ),
  551. CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertMed, TVO_VERTICAL ),
  552. CTaskpadStyle (eSize_Large, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertLrg, TVO_VERTICAL ),
  553. CTaskpadStyle (eSize_Small, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertSmlD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT),
  554. CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertMedD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT),
  555. CTaskpadStyle (eSize_Large, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertLrgD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT),
  556. CTaskpadStyle (eSize_None, IDS_TPSTYLE_NOLIST_DESCR, IDB_TPPreview_Tasks, TVO_NO_RESULTS),
  557. CTaskpadStyle (eSize_None, IDS_TPSTYLE_NOLIST_DESCR, IDB_TPPreview_TasksD, TVO_NO_RESULTS | TVO_DESCRIPTIONS_AS_TEXT),
  558. };
  559. CTaskpadStyleBase::CTaskpadStyleBase(CTaskpadFrame * pTaskpadFrame) :
  560. CTaskpadFramePtr(pTaskpadFrame)
  561. {
  562. }
  563. LRESULT
  564. CTaskpadStyleBase::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  565. {
  566. CWindow wndDlg = HWnd();
  567. m_wndPreview = wndDlg.GetDlgItem (IDC_TaskpadPreview);
  568. /*
  569. * make sure the taskpad's size is valid (bias to large list)
  570. */
  571. ListSize eSize = PConsoleTaskpad()->GetListSize();
  572. if ((eSize != eSize_Small) &&
  573. (eSize != eSize_Medium))
  574. eSize = eSize_Large;
  575. ASSERT ((eSize == eSize_Small) ||
  576. (eSize == eSize_Large) ||
  577. (eSize == eSize_Medium));
  578. /*
  579. * prime the combo box
  580. */
  581. m_wndSizeCombo = wndDlg.GetDlgItem (IDC_Style_SizeCombo);
  582. static const struct {
  583. ListSize eSize;
  584. int nTextID;
  585. } ComboData[] = {
  586. { eSize_Small, IDS_Small },
  587. { eSize_Medium, IDS_Medium },
  588. { eSize_Large, IDS_Large },
  589. };
  590. for (int i = 0; i < countof (ComboData); i++)
  591. {
  592. CStr str;
  593. VERIFY (str.LoadString(GetStringModule(), ComboData[i].nTextID));
  594. VERIFY (m_wndSizeCombo.InsertString (-1, str) == i);
  595. m_wndSizeCombo.SetItemData (i, ComboData[i].eSize);
  596. if (eSize == ComboData[i].eSize)
  597. m_wndSizeCombo.SetCurSel (i);
  598. }
  599. /*
  600. * make sure something is selected
  601. */
  602. ASSERT (m_wndSizeCombo.GetCurSel() != CB_ERR);
  603. /*
  604. * prime the radio buttons
  605. */
  606. int nID;
  607. DWORD dwOrientation = PConsoleTaskpad()->GetOrientation();
  608. nID = (dwOrientation & TVO_VERTICAL) ? IDC_Style_VerticalList :
  609. (dwOrientation & TVO_HORIZONTAL) ? IDC_Style_HorizontalList :
  610. IDC_Style_TasksOnly;
  611. CheckRadioButton (HWnd(), IDC_Style_VerticalList, IDC_Style_TasksOnly, nID);
  612. nID = (dwOrientation & TVO_DESCRIPTIONS_AS_TEXT) ? IDC_Style_TextDesc :
  613. IDC_Style_TooltipDesc;
  614. CheckRadioButton (HWnd(), IDC_Style_TooltipDesc, IDC_Style_TextDesc, nID);
  615. ASSERT (s_rgTaskpadStyle[FindStyle (dwOrientation, eSize)] ==
  616. CTaskpadStyle (eSize, dwOrientation));
  617. // prime the check box
  618. bool bReplacesDefaultView = PConsoleTaskpad()->FReplacesDefaultView();
  619. ::SendDlgItemMessage(HWnd(), IDC_Style_HideNormalTab, BM_SETCHECK, (WPARAM) bReplacesDefaultView ? BST_CHECKED : BST_UNCHECKED, 0);
  620. /*
  621. * update the preview and description
  622. */
  623. UpdateControls ();
  624. return 0;
  625. }
  626. LRESULT
  627. CTaskpadStyleBase::OnSettingChanged( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  628. {
  629. UpdateControls ();
  630. return 0;
  631. }
  632. /*+-------------------------------------------------------------------------*
  633. * CTaskpadStyleBase::UpdateControls
  634. *
  635. *
  636. *--------------------------------------------------------------------------*/
  637. void CTaskpadStyleBase::UpdateControls ()
  638. {
  639. DWORD dwOrientation;
  640. ListSize eSize;
  641. GetSettings (dwOrientation, eSize);
  642. /*
  643. * find the style entry that matches the dialog settings
  644. */
  645. int nStyle = FindStyle (dwOrientation, eSize);
  646. /*
  647. * update the preview bitmap
  648. */
  649. m_wndPreview.SetBitmap (s_rgTaskpadStyle[nStyle].GetPreviewBitmap());
  650. /*
  651. * update the description text
  652. */
  653. SetDlgItemText (HWnd(), IDC_STYLE_DESCRIPTION,
  654. s_rgTaskpadStyle[nStyle].GetDescription());
  655. /*
  656. * disable the size combo for "Tasks only" taskpads
  657. */
  658. m_wndSizeCombo.EnableWindow (!(dwOrientation & TVO_NO_RESULTS));
  659. }
  660. /*+-------------------------------------------------------------------------*
  661. * CTaskpadStyleBase::FindStyle
  662. *
  663. * Returns the index of the CTaskpadStyle entry matching the given size
  664. * and orientation.
  665. *--------------------------------------------------------------------------*/
  666. int CTaskpadStyleBase::FindStyle (DWORD dwOrientation, ListSize eSize)
  667. {
  668. CTaskpadStyle tps(eSize, dwOrientation);
  669. for (int i = 0; i < countof (s_rgTaskpadStyle); i++)
  670. {
  671. if (s_rgTaskpadStyle[i] == tps)
  672. break;
  673. }
  674. ASSERT (i < countof (s_rgTaskpadStyle));
  675. return (i);
  676. }
  677. /*+-------------------------------------------------------------------------*
  678. * CTaskpadStyleBase::Apply
  679. *
  680. *
  681. *--------------------------------------------------------------------------*/
  682. bool CTaskpadStyleBase::Apply()
  683. {
  684. DWORD dwOrientation;
  685. ListSize eSize;
  686. GetSettings (dwOrientation, eSize);
  687. // set the "replaces default view" flag.
  688. CWindow wnd = HWnd();
  689. bool bReplacesDefaultView = wnd.IsDlgButtonChecked (IDC_Style_HideNormalTab);
  690. PConsoleTaskpad()->SetReplacesDefaultView(bReplacesDefaultView);
  691. PConsoleTaskpad()->SetOrientation (dwOrientation);
  692. PConsoleTaskpad()->SetListSize(eSize);
  693. return true;
  694. }
  695. /*+-------------------------------------------------------------------------*
  696. * CTaskpadStyleBase::GetSettings
  697. *
  698. * Returns the orientation and size presently selected in the dialog.
  699. *--------------------------------------------------------------------------*/
  700. void CTaskpadStyleBase::GetSettings (DWORD& dwOrientation, ListSize& eSize)
  701. {
  702. CWindow wnd = HWnd();
  703. dwOrientation = wnd.IsDlgButtonChecked (IDC_Style_VerticalList) ? TVO_VERTICAL :
  704. wnd.IsDlgButtonChecked (IDC_Style_HorizontalList) ? TVO_HORIZONTAL :
  705. TVO_NO_RESULTS;
  706. if (wnd.IsDlgButtonChecked (IDC_Style_TextDesc))
  707. dwOrientation |= TVO_DESCRIPTIONS_AS_TEXT;
  708. eSize = (ListSize) m_wndSizeCombo.GetItemData (m_wndSizeCombo.GetCurSel ());
  709. }
  710. //############################################################################
  711. //############################################################################
  712. //
  713. // Implementation of class CTaskpadStylePage
  714. //
  715. //############################################################################
  716. //############################################################################
  717. CTaskpadStylePage::CTaskpadStylePage(CTaskpadFrame * pTaskpadFrame) :
  718. CTaskpadFramePtr(pTaskpadFrame),
  719. BC2(pTaskpadFrame)
  720. {
  721. }
  722. bool
  723. CTaskpadStylePage::OnSetActive()
  724. {
  725. UpdateControls();
  726. return true;
  727. }
  728. bool
  729. CTaskpadStylePage::OnKillActive()
  730. {
  731. return CTaskpadStyleBase::Apply();
  732. }
  733. //############################################################################
  734. //############################################################################
  735. //
  736. // Implementation of class CTaskpadStyle
  737. //
  738. //############################################################################
  739. //############################################################################
  740. const CStr&
  741. CTaskpadStyle::GetDescription () const
  742. {
  743. if (m_strDescription.IsEmpty())
  744. m_strDescription.LoadString(GetStringModule(), m_idsDescription);
  745. ASSERT (!m_strDescription.IsEmpty());
  746. return (m_strDescription);
  747. }
  748. HBITMAP CTaskpadStyle::GetPreviewBitmap() const
  749. {
  750. if (m_PreviewBitmap == NULL)
  751. m_PreviewBitmap = LoadSysColorBitmap (_Module.GetResourceInstance(),
  752. m_nPreviewBitmapID);
  753. ASSERT (m_PreviewBitmap != NULL);
  754. return (m_PreviewBitmap);
  755. }
  756. //############################################################################
  757. //############################################################################
  758. //
  759. // Implementation of class CTaskpadNodetypeBase
  760. //
  761. //############################################################################
  762. //############################################################################
  763. CTaskpadNodetypeBase::CTaskpadNodetypeBase(CTaskpadFrame *pTaskpadFrame)
  764. : CTaskpadFramePtr(pTaskpadFrame)
  765. {
  766. }
  767. LRESULT
  768. CTaskpadNodetypeBase::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  769. {
  770. m_bApplytoNodetype = !PConsoleTaskpad()->IsNodeSpecific();
  771. m_bSetDefaultForNodetype = true; //$CHANGE
  772. CDefaultTaskpadList *pDefaultTaskpadList = PTaskpadFrame()->PScopeTree()->GetDefaultTaskpadList();
  773. ASSERT(pDefaultTaskpadList != NULL);
  774. CDefaultTaskpadList::iterator iter = pDefaultTaskpadList->find(PConsoleTaskpad()->GetNodeType());
  775. if(iter != pDefaultTaskpadList->end())
  776. {
  777. if(iter->second == PConsoleTaskpad()->GetID())
  778. {
  779. m_bSetDefaultForNodetype = true;
  780. }
  781. }
  782. ::SendDlgItemMessage(HWnd(), IDC_UseForSimilarNodes, BM_SETCHECK, (WPARAM) m_bApplytoNodetype ? BST_CHECKED : BST_UNCHECKED, 0);
  783. ::SendDlgItemMessage(HWnd(), IDC_DontUseForSimilarNodes,BM_SETCHECK, (WPARAM) (!m_bApplytoNodetype) ? BST_CHECKED : BST_UNCHECKED, 0);
  784. ::SendDlgItemMessage(HWnd(), IDC_SetDefaultForNodetype, BM_SETCHECK, (WPARAM) m_bSetDefaultForNodetype ? BST_CHECKED : BST_UNCHECKED, 0);
  785. EnableControls();
  786. return 0;
  787. }
  788. LRESULT
  789. CTaskpadNodetypeBase::OnUseForNodetype(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  790. {
  791. m_bApplytoNodetype = true;
  792. EnableControls();
  793. return 0;
  794. }
  795. LRESULT
  796. CTaskpadNodetypeBase::OnDontUseForNodetype(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  797. {
  798. m_bApplytoNodetype = false;
  799. EnableControls();
  800. return 0;
  801. }
  802. LRESULT
  803. CTaskpadNodetypeBase::OnSetAsDefault (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  804. {
  805. m_bSetDefaultForNodetype = !m_bSetDefaultForNodetype;
  806. EnableControls();
  807. return 0;
  808. }
  809. void
  810. CTaskpadNodetypeBase::EnableControls()
  811. {
  812. // enable the set as default button only if the taskpad applies to all nodes of the same type.
  813. WTL::CButton wndSetAsDefault = ::GetDlgItem(HWnd(), IDC_SetDefaultForNodetype);
  814. wndSetAsDefault.EnableWindow (m_bApplytoNodetype);
  815. /*
  816. * check it if it's disabled
  817. */
  818. if (!m_bApplytoNodetype)
  819. wndSetAsDefault.SetCheck (BST_CHECKED);
  820. }
  821. bool
  822. CTaskpadNodetypeBase::OnApply()
  823. {
  824. PConsoleTaskpad()->SetNodeSpecific(!m_bApplytoNodetype);
  825. if(!m_bApplytoNodetype) // retarget the taskpad to this node only.
  826. {
  827. CNode *pNode = PTaskpadFrame()->PNodeTarget();
  828. ASSERT(pNode != NULL);
  829. PConsoleTaskpad()->Retarget(pNode);
  830. }
  831. CDefaultTaskpadList *pDefaultList = PTaskpadFrame()->PScopeTree()->GetDefaultTaskpadList();
  832. ASSERT(pDefaultList != NULL);
  833. CDefaultTaskpadList::iterator iter = pDefaultList->find(PConsoleTaskpad()->GetNodeType());
  834. if(m_bApplytoNodetype && m_bSetDefaultForNodetype)
  835. {
  836. (*pDefaultList)[PConsoleTaskpad()->GetNodeType()] = PConsoleTaskpad()->GetID();
  837. }
  838. else
  839. {
  840. if(iter != pDefaultList->end())
  841. {
  842. if(iter->second==PConsoleTaskpad()->GetID())
  843. pDefaultList->erase(iter);
  844. }
  845. }
  846. return true;
  847. }
  848. //############################################################################
  849. //############################################################################
  850. //
  851. // Implementation of class CTaskpadNodetypePage
  852. //
  853. //############################################################################
  854. //############################################################################
  855. CTaskpadNodetypePage::CTaskpadNodetypePage(CTaskpadFrame *pTaskpadFrame) :
  856. CTaskpadNodetypeBase(pTaskpadFrame), CTaskpadFramePtr(pTaskpadFrame)
  857. {
  858. }
  859. //############################################################################
  860. //############################################################################
  861. //
  862. // Implementation of class CTaskpadGeneralPage
  863. //
  864. //############################################################################
  865. //############################################################################
  866. /* CTaskpadGeneralPage::CTaskpadGeneralPage
  867. *
  868. * PURPOSE: Constructor
  869. *
  870. * PARAMETERS: None
  871. *
  872. */
  873. CTaskpadGeneralPage::CTaskpadGeneralPage(CTaskpadFrame * pTaskpadFrame):
  874. BC(),
  875. CTaskpadFramePtr(pTaskpadFrame),
  876. BC2(pTaskpadFrame)
  877. {
  878. }
  879. /*+-------------------------------------------------------------------------*
  880. * CTaskpadGeneralPage::OnInitDialog
  881. *
  882. * PURPOSE:
  883. *
  884. * PARAMETERS:
  885. * INT uMsg:
  886. * WPARAM wParam:
  887. * LPARAM lParam:
  888. * BOOL& bHandled:
  889. *
  890. * RETURNS:
  891. * LRESULT
  892. /*+-------------------------------------------------------------------------*/
  893. LRESULT
  894. CTaskpadGeneralPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  895. {
  896. m_strName. Initialize (this, IDC_TASKPAD_TITLE, -1, PConsoleTaskpad()->GetName().data());
  897. m_strDescription.Initialize (this, IDC_TASKPAD_DESCRIPTION,-1, PConsoleTaskpad()->GetDescription().data());
  898. return 0;
  899. }
  900. /*+-------------------------------------------------------------------------*
  901. * CTaskpadGeneralPage::OnOptions
  902. *
  903. *
  904. *--------------------------------------------------------------------------*/
  905. LRESULT CTaskpadGeneralPage::OnOptions( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  906. {
  907. CTaskpadOptionsDlg dlg (PTaskpadFrame());
  908. if (dlg.DoModal() == IDOK)
  909. {
  910. /*
  911. * apply the changes to the taskpad
  912. */
  913. CConsoleTaskpad* pTaskpad = PConsoleTaskpad();
  914. //pTaskpad->SetContextFormat (dlg.m_ctxt);
  915. UpdateControls();
  916. }
  917. return 0;
  918. }
  919. /*+-------------------------------------------------------------------------*
  920. * CTaskpadGeneralPage::OnApply
  921. *
  922. * PURPOSE:
  923. *
  924. * PARAMETERS:
  925. *
  926. * RETURNS:
  927. * BOOL
  928. /*+-------------------------------------------------------------------------*/
  929. bool
  930. CTaskpadGeneralPage::OnApply()
  931. {
  932. tstring strName = MMC::GetWindowText (m_strName);
  933. if (strName.empty())
  934. {
  935. CStr strTitle;
  936. strTitle.LoadString(GetStringModule(), IDS_TASKPAD_NAME_REQUIRED_ERROR);
  937. MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION);
  938. return false;
  939. }
  940. tstring strDescription = MMC::GetWindowText (m_strDescription);
  941. CConsoleTaskpad* pTaskpad = PConsoleTaskpad();
  942. pTaskpad->SetName (strName);
  943. pTaskpad->SetDescription (strDescription);
  944. return BC2::Apply();
  945. }
  946. //############################################################################
  947. //############################################################################
  948. //
  949. // Implementation of class CTaskpadOptionsDlg
  950. //
  951. //############################################################################
  952. //############################################################################
  953. /*+-------------------------------------------------------------------------*
  954. * CTaskpadOptionsDlg::CTaskpadOptionsDlg
  955. *
  956. * PURPOSE:
  957. *
  958. * PARAMETERS:
  959. * TaskpadFrame * pTaskpadFrame:
  960. * CConsoleTask & rConsoleTask:
  961. *
  962. * RETURNS:
  963. *
  964. /*+-------------------------------------------------------------------------*/
  965. CTaskpadOptionsDlg::CTaskpadOptionsDlg (CTaskpadFrame* pTaskpadFrame) :
  966. CTaskpadFramePtr (pTaskpadFrame),
  967. // BC3 (pTaskpadFrame),
  968. BC4 (pTaskpadFrame)
  969. {
  970. }
  971. /*+-------------------------------------------------------------------------*
  972. * CTaskpadOptionsDlg::~CTaskpadOptionsDlg
  973. *
  974. * PURPOSE:
  975. *
  976. * PARAMETERS:
  977. *
  978. * RETURNS:
  979. *
  980. /*+-------------------------------------------------------------------------*/
  981. CTaskpadOptionsDlg::~CTaskpadOptionsDlg()
  982. {
  983. }
  984. /*+-------------------------------------------------------------------------*
  985. * CTaskpadOptionsDlg::OnInitDialog
  986. *
  987. * PURPOSE:
  988. *
  989. * PARAMETERS:
  990. * INT uMsg:
  991. * WPARAM wParam:
  992. * LPARAM lParam:
  993. * BOOL& bHandled:
  994. *
  995. * RETURNS:
  996. * LRESULT
  997. /*+-------------------------------------------------------------------------*/
  998. LRESULT
  999. CTaskpadOptionsDlg::OnInitDialog (HWND hwndFocus, LPARAM lParam, BOOL& bHandled )
  1000. {
  1001. CConsoleTaskpad * pTaskpad = PConsoleTaskpad();
  1002. EnableControls();
  1003. return (true);
  1004. }
  1005. /*+-------------------------------------------------------------------------*
  1006. * CTaskpadOptionsDlg::EnableControls
  1007. *
  1008. *
  1009. *--------------------------------------------------------------------------*/
  1010. void CTaskpadOptionsDlg::EnableControls()
  1011. {
  1012. /*
  1013. bool fUseFixedFormat = IsDlgButtonChecked (IDC_UseFixedFormat);
  1014. bool fUseCustomFormat = IsDlgButtonChecked (IDC_UseCustomContextFormat);
  1015. /*
  1016. * If neither fixed or custom format, then we're displaying no
  1017. * caption. If there's no caption, there's no room for a change
  1018. * button, so we'll disable all of the retargetting-related controls
  1019. *
  1020. if (!fUseFixedFormat && !fUseCustomFormat && !m_fSavedWorkingSetting)
  1021. {
  1022. ASSERT (IsDlgButtonChecked (IDC_NoCaption));
  1023. m_fSavedWorkingSetting = true;
  1024. }
  1025. else if (m_fSavedWorkingSetting)
  1026. {
  1027. m_fSavedWorkingSetting = false;
  1028. }
  1029. //BC3::EnableControls(); */
  1030. }
  1031. /*+-------------------------------------------------------------------------*
  1032. * CTaskpadOptionsDlg::OnApply
  1033. *
  1034. *
  1035. *--------------------------------------------------------------------------*/
  1036. bool CTaskpadOptionsDlg::OnApply()
  1037. {
  1038. //if(!BC3::OnApply())
  1039. // return false;
  1040. if(!BC4::OnApply())
  1041. return false;
  1042. return (true);
  1043. }
  1044. //############################################################################
  1045. //############################################################################
  1046. //
  1047. // Implementation of class CDialogBase
  1048. //
  1049. //############################################################################
  1050. //############################################################################
  1051. /*+-------------------------------------------------------------------------*
  1052. * CDialogBase<T>::CDialogBase
  1053. *
  1054. *
  1055. *--------------------------------------------------------------------------*/
  1056. template<class T>
  1057. CDialogBase<T>::CDialogBase (bool fAutoCenter /* =false */) :
  1058. m_fAutoCenter (fAutoCenter)
  1059. {
  1060. }
  1061. /*+-------------------------------------------------------------------------*
  1062. * CDialogBase<T>::OnInitDialog
  1063. *
  1064. * WM_INITDIALOG handler for CDialogBase.
  1065. *--------------------------------------------------------------------------*/
  1066. template<class T>
  1067. LRESULT CDialogBase<T>::OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  1068. {
  1069. if (!m_fAutoCenter)
  1070. PreventMFCAutoCenter (this);
  1071. return (OnInitDialog ((HWND) wParam, lParam, bHandled));
  1072. }
  1073. template<class T>
  1074. LRESULT CDialogBase<T>::OnInitDialog (HWND hwndFocus, LPARAM lParam, BOOL& bHandled)
  1075. {
  1076. /*
  1077. * we didn't change the default focus
  1078. */
  1079. return (true);
  1080. }
  1081. /*+-------------------------------------------------------------------------*
  1082. * CDialogBase<T>::OnOK
  1083. *
  1084. * IDOK handler for CDialogBase.
  1085. *--------------------------------------------------------------------------*/
  1086. template<class T>
  1087. LRESULT CDialogBase<T>::OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1088. {
  1089. if (OnApply ())
  1090. EndDialog (IDOK);
  1091. return (0);
  1092. }
  1093. /*+-------------------------------------------------------------------------*
  1094. * CDialogBase<T>::OnCancel
  1095. *
  1096. * IDCANCEL handler for CDialogBase.
  1097. *--------------------------------------------------------------------------*/
  1098. template<class T>
  1099. LRESULT CDialogBase<T>::OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1100. {
  1101. EndDialog (IDCANCEL);
  1102. return (0);
  1103. }
  1104. /*+-------------------------------------------------------------------------*
  1105. * CDialogBase<T>::EnableDlgItem
  1106. *
  1107. *
  1108. *--------------------------------------------------------------------------*/
  1109. template<class T>
  1110. BOOL CDialogBase<T>::EnableDlgItem (int idControl, bool fEnable)
  1111. {
  1112. return (::EnableWindow (GetDlgItem (idControl), fEnable));
  1113. }
  1114. /*+-------------------------------------------------------------------------*
  1115. * CDialogBase<T>::CheckDlgItem
  1116. *
  1117. *
  1118. *--------------------------------------------------------------------------*/
  1119. template<class T>
  1120. void CDialogBase<T>::CheckDlgItem (int idControl, int nCheck)
  1121. {
  1122. MMC_ATL::CButton btn = GetDlgItem (idControl);
  1123. btn.SetCheck (nCheck);
  1124. }
  1125. /*+-------------------------------------------------------------------------*
  1126. * CDialogBase<T>::GetDlgItemText
  1127. *
  1128. * Returns the text for a given control in the form of a tstring
  1129. *--------------------------------------------------------------------------*/
  1130. template<class T>
  1131. tstring CDialogBase<T>::GetDlgItemText (int idControl)
  1132. {
  1133. return (MMC::GetWindowText (GetDlgItem (idControl)));
  1134. }
  1135. /*+-------------------------------------------------------------------------*
  1136. * CDialogBase<T>::SetDlgItemText
  1137. *
  1138. * Sets the text for a given control in the form of a tstring
  1139. *--------------------------------------------------------------------------*/
  1140. template<class T>
  1141. BOOL CDialogBase<T>::SetDlgItemText (int idControl, tstring str)
  1142. {
  1143. return (BaseClass::SetDlgItemText (idControl, str.data()));
  1144. }
  1145. //############################################################################
  1146. //############################################################################
  1147. //
  1148. // Implementation of class CTaskPropertiesBase
  1149. //
  1150. //############################################################################
  1151. //############################################################################
  1152. /*+-------------------------------------------------------------------------*
  1153. * CTaskPropertiesBase::CTaskPropertiesBase
  1154. *
  1155. *
  1156. *--------------------------------------------------------------------------*/
  1157. CTaskPropertiesBase::CTaskPropertiesBase (
  1158. CTaskpadFrame* pTaskpadFrame,
  1159. CConsoleTask & consoleTask,
  1160. bool fNew)
  1161. :
  1162. CTaskpadFramePtr(pTaskpadFrame),
  1163. m_pTask (&consoleTask),
  1164. m_fNew (fNew)
  1165. {
  1166. }
  1167. /*+-------------------------------------------------------------------------*
  1168. * CTaskPropertiesBase::ScOnVisitContextMenu
  1169. *
  1170. *
  1171. *--------------------------------------------------------------------------*/
  1172. // forward declaration of function
  1173. void RemoveAccelerators(tstring &str);
  1174. SC
  1175. CTaskPropertiesBase::ScOnVisitContextMenu(CMenuItem &menuItem)
  1176. {
  1177. DECLARE_SC(sc, TEXT("CTaskPropertiesBase::ScOnVisitContextMenu"));
  1178. WTL::CListBox& wndListBox = GetListBox();
  1179. IntToTaskMap& map = GetTaskMap();
  1180. // set up a CConsoleTask object
  1181. CConsoleTask task;
  1182. tstring strName = menuItem.GetMenuItemName();
  1183. RemoveAccelerators(strName); // friendly looking name.
  1184. task.SetName( strName);
  1185. task.SetDescription(menuItem.GetMenuItemStatusBarText());
  1186. task.SetCommand( menuItem.GetLanguageIndependentPath());
  1187. int i = wndListBox.AddString (menuItem.GetPath()); // the "ui-friendly" command path.
  1188. map[i] = task;
  1189. // if this task matches the current task, select it in the listbox
  1190. if (ConsoleTask() == menuItem)
  1191. wndListBox.SetCurSel (i);
  1192. return sc;
  1193. }
  1194. /*+-------------------------------------------------------------------------*
  1195. * CTaskPropertiesBase::OnCommandListSelChange
  1196. *
  1197. * LBN_SELCHANGE handler for CTaskPropertiesBase
  1198. /*+-------------------------------------------------------------------------*/
  1199. LRESULT CTaskPropertiesBase::OnCommandListSelChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  1200. {
  1201. int iSelected = WTL::CListBox(hWndCtl).GetCurSel();
  1202. IntToTaskMap& TaskMap = GetTaskMap();
  1203. CConsoleTask& task = TaskMap[iSelected];
  1204. ConsoleTask().SetName(task.GetName());
  1205. ConsoleTask().SetDescription(task.GetDescription());
  1206. ConsoleTask().SetCommand(task.GetCommand());
  1207. return (0);
  1208. }
  1209. //############################################################################
  1210. //############################################################################
  1211. //
  1212. // class CCommandLineArgumentsMenu
  1213. //
  1214. //############################################################################
  1215. //############################################################################
  1216. class CCommandLineArgumentsMenu
  1217. {
  1218. enum
  1219. {
  1220. TARGETNODE_ITEMS_BASE = 100,
  1221. LISTVIEW_ITEMS_BASE = 1000
  1222. };
  1223. typedef WTL::CMenu CMenu;
  1224. public:
  1225. CCommandLineArgumentsMenu(HWND hWndParent, int nIDButton, HWND hWndListCtrl);
  1226. bool Popup();
  1227. CStr GetResultString() {return m_strResult;}
  1228. private:
  1229. void AddMenuItemsForTargetNode(CMenu &menu);
  1230. void AddMenuItemsForListView(CMenu &menu);
  1231. private:
  1232. HWND m_hWndParent;
  1233. HWND m_hWndListCtrl;
  1234. int m_nIDButton;
  1235. CStr m_strResult; // the string which was created as a result of the selection
  1236. };
  1237. CCommandLineArgumentsMenu::CCommandLineArgumentsMenu(HWND hWndParent, int nIDButton, HWND hWndListCtrl) :
  1238. m_hWndParent(hWndParent),
  1239. m_nIDButton(nIDButton),
  1240. m_hWndListCtrl(hWndListCtrl)
  1241. {
  1242. }
  1243. void
  1244. CCommandLineArgumentsMenu::AddMenuItemsForTargetNode(CMenu &menu)
  1245. {
  1246. bool fSucceeded = menu.CreatePopupMenu();
  1247. ASSERT(fSucceeded);
  1248. CStr strTargetNodeName;
  1249. strTargetNodeName.LoadString(GetStringModule(), IDS_TargetNodeName);
  1250. fSucceeded = menu.AppendMenu(MF_STRING, TARGETNODE_ITEMS_BASE, (LPCTSTR)strTargetNodeName);
  1251. ASSERT(fSucceeded);
  1252. CStr strTargetNodeParentName;
  1253. strTargetNodeParentName.LoadString(GetStringModule(), IDS_TargetNodeParentName);
  1254. fSucceeded = menu.AppendMenu(MF_STRING, TARGETNODE_ITEMS_BASE + 1, (LPCTSTR)strTargetNodeParentName);
  1255. ASSERT(fSucceeded);
  1256. fSucceeded = menu.AppendMenu(MF_SEPARATOR, 0);
  1257. ASSERT(fSucceeded);
  1258. }
  1259. void
  1260. CCommandLineArgumentsMenu::AddMenuItemsForListView(CMenu &menu)
  1261. {
  1262. ASSERT(m_hWndListCtrl);
  1263. WTL::CHeaderCtrl headerCtrl(ListView_GetHeader(m_hWndListCtrl));
  1264. int cItems = headerCtrl.GetItemCount();
  1265. for (int i=0; i<cItems; i++)
  1266. {
  1267. HDITEM hdItem;
  1268. const int cchMaxHeader = 200;
  1269. TCHAR szBuffer[cchMaxHeader];
  1270. ZeroMemory(&hdItem, sizeof(hdItem));
  1271. hdItem.mask = HDI_TEXT;
  1272. hdItem.pszText = szBuffer;
  1273. hdItem.cchTextMax = cchMaxHeader;
  1274. if(headerCtrl.GetItem(i, &hdItem))
  1275. {
  1276. bool fSucceeded = menu.AppendMenu(MF_STRING, LISTVIEW_ITEMS_BASE + i, szBuffer);
  1277. ASSERT(fSucceeded);
  1278. }
  1279. }
  1280. }
  1281. bool
  1282. CCommandLineArgumentsMenu::Popup()
  1283. {
  1284. CMenu menu;
  1285. HWND hWndBrowseButton = ::GetDlgItem(m_hWndParent, m_nIDButton);
  1286. RECT rectBrowse;
  1287. ::GetWindowRect(hWndBrowseButton, &rectBrowse);
  1288. int x = rectBrowse.left + 18;
  1289. int y = rectBrowse.top;
  1290. // add all the items
  1291. AddMenuItemsForTargetNode(menu);
  1292. AddMenuItemsForListView(menu);
  1293. int iResp = menu.TrackPopupMenuEx(
  1294. TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RETURNCMD | TPM_NONOTIFY | TPM_LEFTBUTTON,
  1295. x, y, m_hWndParent);
  1296. if(iResp >= TARGETNODE_ITEMS_BASE && iResp < LISTVIEW_ITEMS_BASE)
  1297. {
  1298. TCHAR szBuffer[10];
  1299. _itot(iResp-TARGETNODE_ITEMS_BASE, szBuffer, 10);
  1300. m_strResult.Format(TEXT("$NAME<%s>"), szBuffer);
  1301. }
  1302. else // is a list view menu item. The return value is of the form $COL<number>
  1303. {
  1304. TCHAR szBuffer[10];
  1305. _itot(iResp-LISTVIEW_ITEMS_BASE, szBuffer, 10);
  1306. m_strResult.Format(TEXT("$COL<%s>"), szBuffer);
  1307. }
  1308. return (iResp != 0);
  1309. }
  1310. //############################################################################
  1311. //############################################################################
  1312. //
  1313. // Implementation of class CTasksListDialog
  1314. //
  1315. //############################################################################
  1316. //############################################################################
  1317. /* CTasksListDialog<T>::CTasksListDialog
  1318. *
  1319. * PURPOSE: Constructor
  1320. *
  1321. * PARAMETERS: None
  1322. */
  1323. template <class T>
  1324. CTasksListDialog<T>::CTasksListDialog(CTaskpadFrame* pTaskpadFrame, bool bNewTaskOnInit, bool bDisplayProperties) :
  1325. BC(),
  1326. m_bNewTaskOnInit(bNewTaskOnInit),
  1327. m_pTaskpadFrame(pTaskpadFrame),
  1328. m_bDisplayProperties(bDisplayProperties)
  1329. {
  1330. }
  1331. /*+-------------------------------------------------------------------------*
  1332. * CTasksListDialog<T>::OnInitDialog
  1333. *
  1334. * PURPOSE:
  1335. *
  1336. * PARAMETERS:
  1337. * INT uMsg:
  1338. * WPARAM wParam:
  1339. * LPARAM lParam:
  1340. * BOOL& bHandled:
  1341. *
  1342. * RETURNS:
  1343. * LRESULT
  1344. /*+-------------------------------------------------------------------------*/
  1345. template <class T>
  1346. LRESULT
  1347. CTasksListDialog<T>::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  1348. {
  1349. m_buttonNewTask.Attach(::GetDlgItem( m_hWnd, IDC_NEW_TASK_BT));
  1350. m_buttonRemoveTask.Attach(::GetDlgItem( m_hWnd, IDC_REMOVE_TASK));
  1351. m_buttonModifyTask.Attach(::GetDlgItem( m_hWnd, IDC_MODIFY));
  1352. m_buttonMoveUp.Attach(::GetDlgItem( m_hWnd, IDC_MOVE_UP));
  1353. m_buttonMoveDown.Attach(::GetDlgItem( m_hWnd, IDC_MOVE_DOWN));
  1354. m_listboxTasks.Attach(::GetDlgItem( m_hWnd, IDC_LIST_TASKS));
  1355. m_listboxTasks.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
  1356. // set up the image list
  1357. WTL::CImageList imageList; // the destructor will not call a destroy. This is by design - the listbox will do the destroy.
  1358. imageList.Create (16, 16, ILC_COLOR , 4 /*the minimum number of images*/, 10);
  1359. m_listboxTasks.SetImageList((HIMAGELIST) imageList, LVSIL_SMALL);
  1360. // insert the list columns
  1361. LV_COLUMN lvc;
  1362. lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
  1363. CStr temp;
  1364. temp.LoadString(GetStringModule(), IDS_COLUMN_TASK);
  1365. lvc.pszText = const_cast<LPTSTR>((LPCTSTR)temp);
  1366. lvc.cx = 100;
  1367. lvc.iSubItem = 0;
  1368. int iCol = m_listboxTasks.InsertColumn(0, &lvc);
  1369. ASSERT(iCol == 0);
  1370. temp.LoadString(GetStringModule(), IDS_COLUMN_TOOLTIP);
  1371. lvc.pszText = const_cast<LPTSTR>((LPCTSTR)temp);
  1372. lvc.cx = 140;
  1373. lvc.iSubItem = 1;
  1374. iCol = m_listboxTasks.InsertColumn(1, &lvc);
  1375. ASSERT(iCol == 1);
  1376. // insert all the items
  1377. UpdateTaskListbox(PConsoleTaskpad()->BeginTask());
  1378. if(FNewTaskOnInit()) // simulate the "New Task" button being clicked.
  1379. {
  1380. m_buttonNewTask.PostMessage (BM_CLICK);
  1381. }
  1382. return 0;
  1383. }
  1384. template <class T>
  1385. LRESULT
  1386. CTasksListDialog<T>::OnCustomDraw( int id, LPNMHDR pnmh, BOOL& bHandled )
  1387. {
  1388. NMLVCUSTOMDRAW * pnmlv = (NMLVCUSTOMDRAW *) pnmh; // the custom draw structure
  1389. NMCUSTOMDRAW & nmcd = pnmlv->nmcd;
  1390. int nItem = nmcd.dwItemSpec;
  1391. switch(nmcd.dwDrawStage & ~CDDS_SUBITEM)
  1392. {
  1393. case CDDS_PREPAINT: // the initial notification
  1394. return CDRF_NOTIFYITEMDRAW; // we want to know about each item's paint.
  1395. case CDDS_ITEMPREPAINT:
  1396. return DrawItem(&nmcd);
  1397. default:
  1398. return 0;
  1399. }
  1400. }
  1401. template <class T>
  1402. LRESULT
  1403. CTasksListDialog<T>::DrawItem(NMCUSTOMDRAW *pnmcd)
  1404. {
  1405. NMLVCUSTOMDRAW * pnmlv = (NMLVCUSTOMDRAW *) pnmcd;
  1406. HDC &hdc = pnmcd->hdc;
  1407. int nItem = pnmcd->dwItemSpec;
  1408. TaskIter itTask = PConsoleTaskpad()->BeginTask();
  1409. std::advance (itTask, nItem);
  1410. bool bWindowHasFocus = (GetFocus() == (HWND) m_listboxTasks);
  1411. bool bFocused = pnmcd->uItemState & CDIS_FOCUS;
  1412. bool bHot = pnmcd->uItemState & CDIS_HOT;
  1413. bool bShowSelAlways = m_listboxTasks.GetStyle() & LVS_SHOWSELALWAYS;
  1414. /*
  1415. * NOTE: There's a bug in the list view control that will
  1416. * set CDIS_SELECTED for *all* items (not just selected items)
  1417. * if LVS_SHOWSELALWAYS is specified. Interrogate the item
  1418. * directly to get the right setting.
  1419. */
  1420. // bool bSelected = pnmcd->uItemState & CDIS_SELECTED;
  1421. bool bSelected = m_listboxTasks.GetItemState (nItem, LVIS_SELECTED);
  1422. #if DBG
  1423. // bFocused should always be false if the window doesn't have the focus
  1424. if (!bWindowHasFocus)
  1425. ASSERT (!bFocused);
  1426. #endif
  1427. RECT rectBounds;
  1428. m_listboxTasks.GetItemRect (nItem, &rectBounds, LVIR_BOUNDS);
  1429. // figure out colors
  1430. int nTextColor, nBackColor;
  1431. if (bSelected && bWindowHasFocus)
  1432. {
  1433. nTextColor = COLOR_HIGHLIGHTTEXT;
  1434. nBackColor = COLOR_HIGHLIGHT;
  1435. }
  1436. else if (bSelected && bShowSelAlways)
  1437. {
  1438. nTextColor = COLOR_BTNTEXT;
  1439. nBackColor = COLOR_BTNFACE;
  1440. }
  1441. else
  1442. {
  1443. nTextColor = COLOR_WINDOWTEXT;
  1444. nBackColor = COLOR_WINDOW;
  1445. }
  1446. // empty (or fill) the region
  1447. FillRect (hdc, &rectBounds, ::GetSysColorBrush (nBackColor));
  1448. // draw the text.
  1449. COLORREF nTextColorOld = SetTextColor (hdc, ::GetSysColor (nTextColor));
  1450. COLORREF nBackColorOld = SetBkColor (hdc, ::GetSysColor (nBackColor));
  1451. RECT rectIcon;
  1452. m_listboxTasks.GetItemRect(nItem, &rectIcon, LVIR_ICON);
  1453. /*
  1454. * Preserve icon shape when BitBlitting it to a
  1455. * mirrored DC.
  1456. */
  1457. DWORD dwLayout=0L;
  1458. if ((dwLayout=GetLayout(hdc)) & LAYOUT_RTL)
  1459. {
  1460. SetLayout(hdc, dwLayout|LAYOUT_BITMAPORIENTATIONPRESERVED);
  1461. }
  1462. itTask->Draw(hdc, &rectIcon, true /*bSmall*/);
  1463. /*
  1464. * Restore the DC to its previous layout state.
  1465. */
  1466. if (dwLayout & LAYOUT_RTL)
  1467. {
  1468. SetLayout(hdc, dwLayout);
  1469. }
  1470. RECT rectLabel;
  1471. UINT uFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS;
  1472. m_listboxTasks.GetItemRect(nItem,&rectLabel, LVIR_LABEL); // get the label rectangle
  1473. DrawText(hdc, itTask->GetName().data(),-1,&rectLabel, uFormat);
  1474. RECT rectDescr;
  1475. m_listboxTasks.GetSubItemRect(nItem, 1 /*descr column*/, LVIR_LABEL, &rectDescr);
  1476. DrawText(hdc, itTask->GetDescription().data(),-1,&rectDescr, uFormat);
  1477. SetTextColor(hdc, nTextColorOld);
  1478. SetBkColor (hdc, nBackColorOld);
  1479. if (bFocused)
  1480. ::DrawFocusRect(hdc, &rectBounds);
  1481. return CDRF_SKIPDEFAULT; // we've drawn the whole item ourselves
  1482. }
  1483. template <class T>
  1484. void
  1485. CTasksListDialog<T>::OnTaskProperties()
  1486. {
  1487. if(!m_bDisplayProperties) // don't display any properties if not needed.
  1488. return;
  1489. int iSelected = GetCurSel();
  1490. if(iSelected == LB_ERR) // defensive
  1491. return;
  1492. TaskIter itTask = MapTaskIterators()[iSelected];
  1493. CTaskPropertySheet dlg(NULL, PTaskpadFrame(), *itTask, false);
  1494. if (dlg.DoModal() == IDOK)
  1495. {
  1496. *itTask = dlg.ConsoleTask();
  1497. UpdateTaskListbox (itTask);
  1498. }
  1499. }
  1500. template <class T>
  1501. int
  1502. CTasksListDialog<T>::GetCurSel()
  1503. {
  1504. int i = (int)PListBoxTasks()->SendMessage(LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0));
  1505. return (i==-1) ? LB_ERR : i;
  1506. }
  1507. /*+-------------------------------------------------------------------------*
  1508. * CTasksListDialog<T>::OnTaskChanged
  1509. *
  1510. * PURPOSE:
  1511. *
  1512. * PARAMETERS:
  1513. * ORD wNotifyCode:
  1514. * WORD wID:
  1515. * HWND hWndCtl:
  1516. * BOOL& bHandled:
  1517. *
  1518. * RETURNS:
  1519. * LRESULT
  1520. /*+-------------------------------------------------------------------------*/
  1521. template <class T>
  1522. LRESULT
  1523. CTasksListDialog<T>::OnTaskChanged( int id, LPNMHDR pnmh, BOOL& bHandled )
  1524. {
  1525. NMLISTVIEW *pnlv = (LPNMLISTVIEW) pnmh;
  1526. EnableButtons();
  1527. return 0;
  1528. }
  1529. /*+-------------------------------------------------------------------------*
  1530. * CTasksListDialog<T>::OnNewTask
  1531. *
  1532. * PURPOSE:
  1533. *
  1534. * PARAMETERS:
  1535. *
  1536. * RETURNS:
  1537. * LRESULT
  1538. /*+-------------------------------------------------------------------------*/
  1539. template <class T>
  1540. LRESULT
  1541. CTasksListDialog<T>::OnNewTask()
  1542. {
  1543. bool fRestartTaskWizard = true;
  1544. while(fRestartTaskWizard)
  1545. {
  1546. CTaskWizard taskWizard;
  1547. if (taskWizard.Show(m_hWnd, PTaskpadFrame(), true, &fRestartTaskWizard)==S_OK)
  1548. {
  1549. CConsoleTaskpad::TaskIter itTask;
  1550. CConsoleTaskpad * pTaskpad = PConsoleTaskpad();
  1551. // get the iterator of the selected task. The new task will be inserted just after this.
  1552. int iSelected = GetCurSel();
  1553. if (iSelected == LB_ERR)
  1554. itTask = pTaskpad->BeginTask();
  1555. else
  1556. {
  1557. /*
  1558. * InsertTask inserts before the given iterator. We need to
  1559. * bump itTask so it gets inserted after the selected task.
  1560. */
  1561. itTask = MapTaskIterators()[iSelected];
  1562. ASSERT (itTask != pTaskpad->EndTask());
  1563. ++itTask;
  1564. }
  1565. UpdateTaskListbox (pTaskpad->InsertTask (itTask, taskWizard.ConsoleTask()));
  1566. }
  1567. else
  1568. break;
  1569. }
  1570. return 0;
  1571. }
  1572. /*+-------------------------------------------------------------------------*
  1573. * CTasksListDialog<T>::OnRemoveTask
  1574. *
  1575. * PURPOSE:
  1576. *
  1577. * PARAMETERS:
  1578. * ORD wNotifyCode:
  1579. * WORD wID:
  1580. * HWND hWndCtl:
  1581. * BOOL& bHandled:
  1582. *
  1583. * RETURNS:
  1584. * LRESULT
  1585. /*+-------------------------------------------------------------------------*/
  1586. template <class T>
  1587. LRESULT
  1588. CTasksListDialog<T>::OnRemoveTask( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  1589. {
  1590. int iSelected = GetCurSel();
  1591. if(iSelected == LB_ERR)
  1592. return 0;
  1593. // get the current task
  1594. TaskIter taskIterator = MapTaskIterators()[iSelected];
  1595. UpdateTaskListbox(PConsoleTaskpad()->EraseTask(taskIterator));
  1596. return 0;
  1597. }
  1598. /*+-------------------------------------------------------------------------*
  1599. * CTasksListDialog<T>::OnMoveUp
  1600. *
  1601. * PURPOSE:
  1602. *
  1603. * PARAMETERS:
  1604. * ORD wNotifyCode:
  1605. * WORD wID:
  1606. * HWND hWndCtl:
  1607. * BOOL& bHandled:
  1608. *
  1609. * RETURNS:
  1610. * LRESULT
  1611. /*+-------------------------------------------------------------------------*/
  1612. template <class T>
  1613. LRESULT
  1614. CTasksListDialog<T>::OnMoveUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  1615. {
  1616. int iSelected = GetCurSel();
  1617. if(iSelected == LB_ERR)
  1618. return 0;
  1619. // get the current task
  1620. TaskIter itTask = MapTaskIterators()[iSelected];
  1621. // defensive coding
  1622. if(itTask==PConsoleTaskpad()->BeginTask())
  1623. return 0;
  1624. // point to the previous task
  1625. TaskIter itPreviousTask = itTask;
  1626. --itPreviousTask;
  1627. // swap the tasks
  1628. std::iter_swap (itTask, itPreviousTask);
  1629. UpdateTaskListbox(itPreviousTask);
  1630. return 0;
  1631. }
  1632. /*+-------------------------------------------------------------------------*
  1633. * CTasksListDialog<T>::OnMoveDown
  1634. *
  1635. * PURPOSE:
  1636. *
  1637. * PARAMETERS:
  1638. * ORD wNotifyCode:
  1639. * WORD wID:
  1640. * HWND hWndCtl:
  1641. * BOOL& bHandled:
  1642. *
  1643. * RETURNS:
  1644. * LRESULT
  1645. /*+-------------------------------------------------------------------------*/
  1646. template <class T>
  1647. LRESULT
  1648. CTasksListDialog<T>::OnMoveDown( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  1649. {
  1650. int iSelected = GetCurSel();
  1651. if(iSelected == LB_ERR)
  1652. return 0;
  1653. // get the current task
  1654. TaskIter itTask = MapTaskIterators()[iSelected];
  1655. ASSERT (itTask != PConsoleTaskpad()->EndTask());
  1656. // point to the next task
  1657. TaskIter itNextTask = itTask;
  1658. ++itNextTask;
  1659. // defensive coding
  1660. if(itNextTask==PConsoleTaskpad()->EndTask())
  1661. return 0;
  1662. // swap the tasks
  1663. std::iter_swap (itTask, itNextTask);
  1664. UpdateTaskListbox(itNextTask);
  1665. return 0;
  1666. }
  1667. /*+-------------------------------------------------------------------------*
  1668. * CTasksListDialog<T>::UpdateTaskListbox
  1669. *
  1670. * PURPOSE:
  1671. *
  1672. * PARAMETERS:
  1673. * TaskIter itSelectedTask:
  1674. *
  1675. * RETURNS:
  1676. * void
  1677. /*+-------------------------------------------------------------------------*/
  1678. template <class T>
  1679. void
  1680. CTasksListDialog<T>::UpdateTaskListbox(TaskIter itSelectedTask)
  1681. {
  1682. USES_CONVERSION;
  1683. TaskIter itTask;
  1684. int iSelect = 0;
  1685. int iInsert = 0;
  1686. // clear the listbox and the iterator map
  1687. PListBoxTasks()->DeleteAllItems();
  1688. MapTaskIterators().clear();
  1689. for (iInsert = 0, itTask = PConsoleTaskpad()->BeginTask();
  1690. itTask != PConsoleTaskpad()->EndTask();
  1691. ++itTask, ++iInsert)
  1692. {
  1693. LV_ITEM LVItem;
  1694. LVItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  1695. LVItem.iItem = iInsert;
  1696. LVItem.iImage = 0;
  1697. LVItem.iSubItem = 0;
  1698. LVItem.pszText = const_cast<TCHAR *>(itTask->GetName().data());
  1699. int i = PListBoxTasks()->InsertItem(&LVItem);
  1700. ASSERT(i==iInsert);
  1701. // LV_Item for setting tooltim column
  1702. LV_ITEM LVItem2;
  1703. LVItem2.iItem = iInsert;
  1704. LVItem2.mask = LVIF_TEXT;
  1705. LVItem2.iSubItem = 1;
  1706. LVItem2.pszText = const_cast<TCHAR *>(itTask->GetDescription().data());
  1707. BOOL bStat = PListBoxTasks()->SetItem(&LVItem2);
  1708. ASSERT(bStat);
  1709. MapTaskIterators()[i] = itTask;
  1710. if(itTask == itSelectedTask)
  1711. iSelect = i;
  1712. }
  1713. PListBoxTasks()->SetItemState(iSelect, LVIS_FOCUSED| LVIS_SELECTED , LVIS_FOCUSED| LVIS_SELECTED );
  1714. PListBoxTasks()->EnsureVisible(iSelect, false /*fPartialOK*/);
  1715. EnableButtons();
  1716. }
  1717. /*+-------------------------------------------------------------------------*
  1718. * CTasksListDialog<T>::EnableButtons
  1719. *
  1720. * PURPOSE:
  1721. *
  1722. * PARAMETERS:
  1723. *
  1724. * RETURNS:
  1725. * void
  1726. /*+-------------------------------------------------------------------------*/
  1727. template <class T>
  1728. void
  1729. CTasksListDialog<T>::EnableButtons()
  1730. {
  1731. bool bEnableDelete = true;
  1732. bool bEnableMoveUp = true;
  1733. bool bEnableMoveDown = true;
  1734. bool bEnableModify = true;
  1735. int iSelected = GetCurSel();
  1736. if(iSelected == LB_ERR)
  1737. {
  1738. bEnableDelete = false;
  1739. bEnableMoveUp = false;
  1740. bEnableMoveDown = false;
  1741. bEnableModify = false;
  1742. }
  1743. else
  1744. {
  1745. TaskIter taskIterator = MapTaskIterators()[iSelected];
  1746. TaskIter taskIteratorNext = taskIterator;
  1747. taskIteratorNext++;
  1748. if(taskIterator==PConsoleTaskpad()->BeginTask())
  1749. bEnableMoveUp = false;
  1750. if(taskIteratorNext==PConsoleTaskpad()->EndTask())
  1751. bEnableMoveDown = false;
  1752. }
  1753. EnableButtonAndCorrectFocus( m_buttonRemoveTask, bEnableDelete );
  1754. EnableButtonAndCorrectFocus( m_buttonModifyTask, bEnableModify );
  1755. EnableButtonAndCorrectFocus( m_buttonMoveUp, bEnableMoveUp );
  1756. EnableButtonAndCorrectFocus( m_buttonMoveDown, bEnableMoveDown );
  1757. }
  1758. /***************************************************************************\
  1759. *
  1760. * METHOD: CTasksListDialog<T>::EnableButtonAndCorrectFocus
  1761. *
  1762. * PURPOSE: Enables/disables button. Moves focus to OK, if it's on the button
  1763. * being disabled
  1764. *
  1765. * PARAMETERS:
  1766. * WTL::CButton& button
  1767. * BOOL bEnable
  1768. *
  1769. * RETURNS:
  1770. * void
  1771. *
  1772. \***************************************************************************/
  1773. template <class T>
  1774. void CTasksListDialog<T>::EnableButtonAndCorrectFocus( WTL::CButton& button, BOOL bEnable )
  1775. {
  1776. // if the focus belongs to the window being disabled,
  1777. // set it to the OK button
  1778. if ( ( !bEnable ) && ( ::GetFocus() == button ) )
  1779. {
  1780. // need to do some funny stuff here. see KB article Q67655 for details
  1781. // Reset the current default push button to a regular button.
  1782. button.SendMessage( BM_SETSTYLE, BS_PUSHBUTTON, (LONG)TRUE );
  1783. // set focus to IDOK
  1784. ::SetFocus( ::GetDlgItem( GetParent(), IDOK ) );
  1785. // inform dialog about the new default button
  1786. ::SendMessage( GetParent(), DM_SETDEFID, IDOK, 0 );
  1787. }
  1788. button.EnableWindow( bEnable );
  1789. }
  1790. //############################################################################
  1791. //############################################################################
  1792. //
  1793. // Implementation of class CContextMenuVisitor
  1794. //
  1795. //############################################################################
  1796. //############################################################################
  1797. /*+-------------------------------------------------------------------------*
  1798. * CContextMenuVisitor::ScTraverseContextMenu
  1799. *
  1800. * PURPOSE: Creates and traverses the context menu tree for the selected item,
  1801. * whether scope or result.
  1802. *
  1803. * PARAMETERS:
  1804. * Node * pNodeTarget: The scope item whose menu is traversed (or NULL)
  1805. * CScopeTree * pCScopeTree: Points to a CScopeTree
  1806. * BOOL fScopeItem: TRUE if the selected item is a result item, else FALSE.
  1807. * CNode * pNodeScope: The scope item which has the focus.
  1808. * LPARAM resultItemParam: The result item whose menu is traversed (or NULL)
  1809. *
  1810. * RETURNS:
  1811. * SC
  1812. /*+-------------------------------------------------------------------------*/
  1813. SC
  1814. CContextMenuVisitor::ScTraverseContextMenu(CNode *pNodeTarget, CScopeTree *pCScopeTree,
  1815. BOOL fScopeItem, CNode *pNodeScope, LPARAM resultItemParam, bool bShowSaveList)
  1816. {
  1817. DECLARE_SC(sc, TEXT("CContextMenuVisitor::ScTraverseContextMenu"));
  1818. sc = ScCheckPointers(pNodeTarget);
  1819. if(sc)
  1820. return sc;
  1821. // set the context info structure.
  1822. // include flag to force Open verb on scope item menus, so that an open task
  1823. // will always be available and enabled.
  1824. CContextMenuInfo contextInfo;
  1825. contextInfo.Initialize();
  1826. contextInfo.m_dwFlags = CMINFO_USE_TEMP_VERB | CMINFO_SHOW_SCOPEITEM_OPEN;
  1827. // Validate parameters
  1828. if(fScopeItem)
  1829. {
  1830. sc = ScCheckPointers(pNodeScope);
  1831. if(sc)
  1832. return sc;
  1833. // show the view menu items only for the selected scope node
  1834. // NOTE: cannot compare the pNode's directly - they are from different views.
  1835. // must compare the MTNodes.
  1836. if(pNodeTarget->GetMTNode()==pNodeScope->GetMTNode())
  1837. contextInfo.m_dwFlags |= CMINFO_SHOW_VIEW_ITEMS;
  1838. resultItemParam = 0; // we don't need this
  1839. }
  1840. else
  1841. {
  1842. // Virtual list can have lparam of 0
  1843. // (this condition must have braces as long as the assert is the
  1844. // only conditional statement, to avoid C4390: empty controlled statement)
  1845. if (!(pNodeTarget && pNodeTarget->GetViewData()->IsVirtualList()) &&
  1846. !IS_SPECIAL_LVDATA (resultItemParam))
  1847. {
  1848. ASSERT(resultItemParam);
  1849. CResultItem* pri = CResultItem::FromHandle(resultItemParam);
  1850. if((pri != NULL) && pri->IsScopeItem()) // scope items in the result pane.
  1851. {
  1852. fScopeItem = true;
  1853. pNodeTarget = CNode::FromResultItem (pri);
  1854. resultItemParam = 0;
  1855. contextInfo.m_dwFlags |= CMINFO_SCOPEITEM_IN_RES_PANE;
  1856. }
  1857. }
  1858. pNodeScope = NULL; // we don't need this.
  1859. }
  1860. CNodeCallback* pNodeCallback =
  1861. dynamic_cast<CNodeCallback *>(pNodeTarget->GetViewData()->GetNodeCallback());
  1862. contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
  1863. contextInfo.m_eDataObjectType = fScopeItem ? CCT_SCOPE: CCT_RESULT;
  1864. contextInfo.m_bBackground = FALSE;
  1865. contextInfo.m_hSelectedScopeNode = CNode::ToHandle(pNodeScope);
  1866. contextInfo.m_resultItemParam = resultItemParam;
  1867. contextInfo.m_bMultiSelect = (resultItemParam == LVDATA_MULTISELECT);
  1868. contextInfo.m_bScopeAllowed = fScopeItem;
  1869. if (bShowSaveList)
  1870. contextInfo.m_dwFlags |= CMINFO_SHOW_SAVE_LIST;
  1871. contextInfo.m_hWnd = pNodeTarget->GetViewData()->GetView();
  1872. contextInfo.m_pConsoleView = pNodeTarget->GetViewData()->GetConsoleView();
  1873. // Create a CContextMenu and initialize it.
  1874. CContextMenu * pContextMenu = NULL;
  1875. ContextMenuPtr spContextMenu;
  1876. sc = CContextMenu::ScCreateInstance(&spContextMenu, &pContextMenu);
  1877. if(sc)
  1878. return sc;
  1879. sc = ScCheckPointers(pContextMenu, spContextMenu.GetInterfacePtr(), E_UNEXPECTED);
  1880. if(sc)
  1881. return sc;
  1882. pContextMenu->ScInitialize(pNodeTarget, pNodeCallback, pCScopeTree, contextInfo);
  1883. if(sc)
  1884. return sc;
  1885. // build and traverse the context menu.
  1886. sc = pContextMenu->ScBuildContextMenu();
  1887. if(sc)
  1888. return sc;
  1889. sc = ScTraverseContextMenu(pContextMenu);
  1890. if(sc)
  1891. return sc;
  1892. // the context menu is freed in the destructor of the smart pointer, so we need to set the pointer to NULL.
  1893. pContextMenu = NULL;
  1894. return sc;
  1895. }
  1896. /*+-------------------------------------------------------------------------*
  1897. *
  1898. * CContextMenuVisitor::ScTraverseContextMenu
  1899. *
  1900. * PURPOSE: Iterates thru the context menu.
  1901. *
  1902. * RETURNS:
  1903. * SC
  1904. *
  1905. *+-------------------------------------------------------------------------*/
  1906. SC
  1907. CContextMenuVisitor::ScTraverseContextMenu(CContextMenu *pContextMenu)
  1908. {
  1909. DECLARE_SC(sc, TEXT("CContextMenuVisitor::ScTraverseContextMenu"));
  1910. sc = ScCheckPointers(pContextMenu, E_UNEXPECTED);
  1911. if(sc)
  1912. return sc;
  1913. CMenuItem *pMenuItem = NULL;
  1914. int iIndex = 0;
  1915. do
  1916. {
  1917. sc = pContextMenu->ScGetItem(iIndex++, &pMenuItem);
  1918. if(sc)
  1919. return sc;
  1920. if(!pMenuItem)
  1921. return sc; // all done.
  1922. bool bVisitItem = false;
  1923. sc = ScShouldItemBeVisited(pMenuItem, pContextMenu->PContextInfo(), bVisitItem);
  1924. if(sc)
  1925. return sc;
  1926. if(bVisitItem)
  1927. {
  1928. // Call the vistor on this item.
  1929. SC sc = ScOnVisitContextMenu(*pMenuItem);
  1930. if(sc == SC(S_FALSE)) // S_FALSE is the code to not continue traversal.
  1931. {
  1932. return sc;
  1933. }
  1934. }
  1935. } while(pMenuItem != NULL);
  1936. return sc;
  1937. }
  1938. /*+-------------------------------------------------------------------------*
  1939. *
  1940. * CContextMenuVisitor::ScShouldItemBeVisited
  1941. *
  1942. * PURPOSE: Filters items in the traversed tree of menu items to determine whether
  1943. * the ScOnVisitContextMenu callback should be called.
  1944. *
  1945. * PARAMETERS:
  1946. * CMenuItem * pMenuItem : The menu item to filter
  1947. *
  1948. * bool &bVisitItem: [out]: Whether ScOnVisitContextMenu should be called.
  1949. *
  1950. * RETURNS:
  1951. * bool: true if ScOnVisitContextMenu should be called on this item.
  1952. *
  1953. *+-------------------------------------------------------------------------*/
  1954. SC
  1955. CContextMenuVisitor::ScShouldItemBeVisited(CMenuItem *pMenuItem, CContextMenuInfo *pContextInfo, /*out*/ bool &bVisitItem)
  1956. {
  1957. DECLARE_SC(sc, TEXT("CContextMenuInfo::FVisitItem"));
  1958. sc = ScCheckPointers(pMenuItem, pContextInfo);
  1959. if(sc)
  1960. return sc;
  1961. bVisitItem = false;
  1962. if(pMenuItem->IsSpecialSeparator() || pMenuItem->IsSpecialInsertionPoint()
  1963. || (pMenuItem->GetMenuItemFlags() & MF_SEPARATOR))
  1964. {
  1965. bVisitItem = false; // don't call ScOnVisitContextMenu for this item
  1966. return sc;
  1967. }
  1968. else if(IsSystemOwnerID(pMenuItem->GetMenuItemOwner())) // inserted by the MMC
  1969. {
  1970. long nCommandID = pMenuItem->GetCommandID();
  1971. // filter out unneeded verbs
  1972. // also check for scope items in the result pane - these are treated as result items.
  1973. if( (pContextInfo->m_eDataObjectType == CCT_SCOPE)
  1974. && (!(pContextInfo->m_dwFlags & CMINFO_SCOPEITEM_IN_RES_PANE)) )
  1975. {
  1976. // scope menu item
  1977. switch(nCommandID)
  1978. {
  1979. case MID_RENAME:
  1980. case MID_DELETE:
  1981. case MID_COPY:
  1982. case MID_CUT:
  1983. case MID_NEW_TASKPAD_FROM_HERE: // New taskpad from here
  1984. bVisitItem = false;
  1985. return sc;
  1986. break;
  1987. default:
  1988. bVisitItem = true;
  1989. return sc;
  1990. break;
  1991. }
  1992. }
  1993. else
  1994. {
  1995. if(pContextInfo->m_bMultiSelect) // result item, multi select
  1996. {
  1997. switch(nCommandID)
  1998. {
  1999. case MID_RENAME:
  2000. case MID_PASTE:
  2001. case MID_REFRESH:
  2002. case MID_OPEN:
  2003. bVisitItem = false;
  2004. return sc;
  2005. break;
  2006. default:
  2007. bVisitItem = true;
  2008. return sc;
  2009. break;
  2010. }
  2011. }
  2012. else // result item, single select
  2013. {
  2014. switch(nCommandID)
  2015. {
  2016. case MID_OPEN:
  2017. bVisitItem = false;
  2018. return sc;
  2019. break;
  2020. default:
  2021. bVisitItem = true;
  2022. return sc;
  2023. break;
  2024. }
  2025. }
  2026. }
  2027. }
  2028. else
  2029. {
  2030. bVisitItem = true;
  2031. return sc;
  2032. }
  2033. }
  2034. //############################################################################
  2035. //############################################################################
  2036. //
  2037. // Implementation of class CBrowserCookieList
  2038. //
  2039. //############################################################################
  2040. //############################################################################
  2041. CBrowserCookieList::~CBrowserCookieList()
  2042. {
  2043. iterator iter;
  2044. for (iter = begin(); iter != end(); iter++)
  2045. {
  2046. iter->DeleteNode();
  2047. }
  2048. }
  2049. //############################################################################
  2050. //############################################################################
  2051. //
  2052. // Implementation of class CMTBrowserCtrl
  2053. //
  2054. //############################################################################
  2055. //############################################################################
  2056. /*+-------------------------------------------------------------------------*
  2057. * CMTBrowserCtrl::CMTBrowserCtrl
  2058. *
  2059. * PURPOSE:
  2060. *
  2061. * PARAMETERS:
  2062. * WND hWnd:
  2063. * CScopeTree * pScopeTree:
  2064. *
  2065. * RETURNS:
  2066. *
  2067. /*+-------------------------------------------------------------------------*/
  2068. CMTBrowserCtrl::CMTBrowserCtrl() :
  2069. m_pScopeTree(NULL)
  2070. {
  2071. }
  2072. /*+-------------------------------------------------------------------------*
  2073. * CMTBrowserCtrl::~CMTBrowserCtrl
  2074. *
  2075. * PURPOSE:
  2076. *
  2077. * PARAMETERS:
  2078. *
  2079. * RETURNS:
  2080. *
  2081. /*+-------------------------------------------------------------------------*/
  2082. CMTBrowserCtrl::~CMTBrowserCtrl()
  2083. {
  2084. CBrowserCookieList::iterator iter;
  2085. for (iter = PBrowserCookieList()->begin(); iter != PBrowserCookieList()->end(); iter++)
  2086. iter->DeleteNode();
  2087. }
  2088. /*+-------------------------------------------------------------------------*
  2089. * CMTBrowserCtrl::Initialize
  2090. *
  2091. * PURPOSE:
  2092. *
  2093. * PARAMETERS:
  2094. *
  2095. * RETURNS:
  2096. * void
  2097. /*+-------------------------------------------------------------------------*/
  2098. void
  2099. CMTBrowserCtrl::Initialize(const InitData& init)
  2100. {
  2101. ASSERT (::IsWindow (init.hwnd));
  2102. ASSERT (init.pScopeTree != NULL);
  2103. SubclassWindow (init.hwnd);
  2104. m_pScopeTree = init.pScopeTree;
  2105. /*
  2106. * Copy the list of nodes to exclude. This list is likely to be very
  2107. * small. If we find that it can be large, we may want to sort it
  2108. * so that we can later do a binary search instead of a linear search.
  2109. */
  2110. m_vpmtnExclude = init.vpmtnExclude;
  2111. #if OptimizeExcludeList
  2112. std::sort (m_vpmtnExclude.begin(), m_vpmtnExclude.end());
  2113. #endif
  2114. /*
  2115. * set the image list of the tree view control
  2116. */
  2117. HIMAGELIST hImageList = m_pScopeTree->GetImageList ();
  2118. SetImageList (hImageList, TVSIL_NORMAL);
  2119. /*
  2120. * if no root was provided, default to the console root
  2121. */
  2122. CMTNode* pmtnRoot = init.pmtnRoot;
  2123. if (pmtnRoot == NULL)
  2124. pmtnRoot = m_pScopeTree->GetRoot();
  2125. ASSERT (pmtnRoot != NULL);
  2126. /*
  2127. * add the root item
  2128. */
  2129. CBrowserCookie browserCookie (pmtnRoot, NULL);
  2130. HTREEITEM htiRoot = InsertItem (browserCookie, TVI_ROOT, TVI_FIRST);
  2131. /*
  2132. * if no selection node was provided, default to the root
  2133. */
  2134. CMTNode* pmtnSelect = init.pmtnSelect;
  2135. if (pmtnSelect == NULL)
  2136. pmtnSelect = pmtnRoot;
  2137. ASSERT (pmtnSelect != NULL);
  2138. /*
  2139. * select the specified node
  2140. */
  2141. SelectNode (pmtnSelect);
  2142. /*
  2143. * insure that the root item is expanded
  2144. */
  2145. Expand (htiRoot, TVE_EXPAND);
  2146. }
  2147. /*+-------------------------------------------------------------------------*
  2148. * CMTBrowserCtrl::InsertItem
  2149. *
  2150. * PURPOSE:
  2151. *
  2152. * PARAMETERS:
  2153. * MTNode * pMTNode:
  2154. * HTREEITEM hParent:
  2155. * HTREEITEM hInsertAfter:
  2156. *
  2157. * RETURNS:
  2158. * HTREEITEM
  2159. /*+-------------------------------------------------------------------------*/
  2160. HTREEITEM
  2161. CMTBrowserCtrl::InsertItem(
  2162. const CBrowserCookie& browserCookie,
  2163. HTREEITEM hParent,
  2164. HTREEITEM hInsertAfter)
  2165. {
  2166. /*
  2167. * don't insert the item if it is in the exclude list
  2168. */
  2169. if (IsMTNodeExcluded (browserCookie.PMTNode()))
  2170. return (NULL);
  2171. UINT nMask = TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_CHILDREN;
  2172. PBrowserCookieList()->push_back(browserCookie);
  2173. CBrowserCookie *pBrowserCookie = & (PBrowserCookieList()->back());
  2174. CMTNode * pMTNode = pBrowserCookie->PMTNode();
  2175. tstring strName = pMTNode->GetDisplayName();
  2176. TV_INSERTSTRUCT tvis;
  2177. tvis.hParent = hParent;
  2178. tvis.hInsertAfter = hInsertAfter;
  2179. tvis.item.mask = nMask;
  2180. tvis.item.pszText = const_cast<LPTSTR>(strName.data());
  2181. tvis.item.iImage = pMTNode->GetImage();
  2182. tvis.item.iSelectedImage = pMTNode->GetOpenImage();
  2183. tvis.item.state = 0;
  2184. tvis.item.stateMask = 0;
  2185. tvis.item.lParam = reinterpret_cast<LPARAM>(pBrowserCookie);
  2186. tvis.item.cChildren = 1;
  2187. return BC::InsertItem(&tvis);
  2188. }
  2189. /*+-------------------------------------------------------------------------*
  2190. * CMTBrowserCtrl::IsMTNodeExcluded
  2191. *
  2192. * Returns true if the given MTNode is in the exclude list.
  2193. *--------------------------------------------------------------------------*/
  2194. bool CMTBrowserCtrl::IsMTNodeExcluded (CMTNode* pmtn) const
  2195. {
  2196. CMTNodeCollection::const_iterator itEnd = m_vpmtnExclude.end();
  2197. CMTNodeCollection::const_iterator itFound =
  2198. #if OptimizeExcludeList
  2199. std::lower_bound (m_vpmtnExclude.begin(), itEnd, pmtn);
  2200. #else
  2201. std::find (m_vpmtnExclude.begin(), itEnd, pmtn);
  2202. #endif
  2203. return (itFound != itEnd);
  2204. }
  2205. /*+-------------------------------------------------------------------------*
  2206. * CMTBrowserCtrl::OnItemExpanding
  2207. *
  2208. * Reflected TVN_ITEMEXPANDING handler for CMTBrowserCtrl. The class that
  2209. * uses a CMTBrowserCtrl must have REFLECT_NOTIFICATIONS as the last entry
  2210. * in its message map.
  2211. *--------------------------------------------------------------------------*/
  2212. LRESULT CMTBrowserCtrl::OnItemExpanding (int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2213. {
  2214. /*
  2215. * this should only handle messages that originated from itself
  2216. */
  2217. ASSERT (pnmh->hwndFrom == m_hWnd);
  2218. /*
  2219. * insert the children for this node, if we're expanding
  2220. */
  2221. LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
  2222. if (pnmtv->action == TVE_EXPAND)
  2223. ExpandItem (pnmtv->itemNew);
  2224. return (0);
  2225. }
  2226. /*+-------------------------------------------------------------------------*
  2227. * CMTBrowserCtrl::ExpandItem
  2228. *
  2229. *
  2230. *--------------------------------------------------------------------------*/
  2231. #define TVIF_REQUIRED (TVIF_PARAM | TVIF_HANDLE | TVIF_STATE)
  2232. bool CMTBrowserCtrl::ExpandItem (const TV_ITEM& itemExpand)
  2233. {
  2234. /*
  2235. * make sure all of the fields we require can be trusted
  2236. */
  2237. ASSERT ((itemExpand.mask & TVIF_REQUIRED) == TVIF_REQUIRED);
  2238. /*
  2239. * if we've already added children, bail
  2240. */
  2241. if (itemExpand.state & TVIS_EXPANDEDONCE)
  2242. return (true);
  2243. CMTNode *pmtnParent = MTNodeFromItem (&itemExpand);
  2244. ASSERT (pmtnParent != NULL);
  2245. /*
  2246. * make sure the master tree node has been expanded
  2247. */
  2248. if (!pmtnParent->WasExpandedAtLeastOnce() && FAILED (pmtnParent->Expand()))
  2249. return (false);
  2250. /*
  2251. * insert tree nodes for all (non-excluded) children of this MTNode
  2252. */
  2253. HTREEITEM hParent = itemExpand.hItem;
  2254. bool bHasChildren = false;
  2255. for (CMTNode* pmtn = pmtnParent->GetChild(); pmtn; pmtn = pmtn->GetNext())
  2256. {
  2257. if (InsertItem (CBrowserCookie(pmtn, NULL), hParent, TVI_LAST))
  2258. bHasChildren = true;
  2259. }
  2260. /*
  2261. * if the parent has no children - set its
  2262. * cChildren to zero to get rid of the "+"
  2263. */
  2264. if (!bHasChildren)
  2265. {
  2266. TV_ITEM item;
  2267. item.mask = TVIF_HANDLE | TVIF_CHILDREN;
  2268. item.hItem = hParent;
  2269. item.cChildren = 0;
  2270. SetItem(&item);
  2271. }
  2272. return (true);
  2273. }
  2274. /*+-------------------------------------------------------------------------*
  2275. * CBrowserCookie::DeleteNode
  2276. *
  2277. *
  2278. *--------------------------------------------------------------------------*/
  2279. void CBrowserCookie::DeleteNode()
  2280. {
  2281. delete m_pNode;
  2282. m_pMTNode = NULL;
  2283. m_pNode = NULL;
  2284. }
  2285. /*+-------------------------------------------------------------------------*
  2286. * CMTBrowserCtrl::FindMTNode
  2287. *
  2288. *
  2289. *--------------------------------------------------------------------------*/
  2290. bool CMTBrowserCtrl::SelectNode (CMTNode* pmtnSelect)
  2291. {
  2292. HTREEITEM htiRoot = GetRootItem();
  2293. CMTNode* pmtnRoot = MTNodeFromItem (htiRoot);
  2294. CMTNodeCollection vNodes;
  2295. /*
  2296. * walk up the tree to find the root
  2297. */
  2298. while (pmtnSelect != NULL)
  2299. {
  2300. vNodes.push_back (pmtnSelect);
  2301. if (pmtnSelect == pmtnRoot)
  2302. break;
  2303. pmtnSelect = pmtnSelect->Parent();
  2304. }
  2305. /*
  2306. * if we didn't find the root, fail
  2307. */
  2308. if (pmtnSelect == NULL)
  2309. return (false);
  2310. ASSERT (!vNodes.empty());
  2311. ASSERT (vNodes.back() == pmtnRoot);
  2312. HTREEITEM htiSelect = htiRoot;
  2313. HTREEITEM htiWatch;
  2314. /*
  2315. * expand the tree to the node we want to select
  2316. */
  2317. for (int i = vNodes.size()-1; (i > 0) && (htiSelect != NULL); i--)
  2318. {
  2319. if (!Expand (htiSelect, TVE_EXPAND))
  2320. break;
  2321. htiSelect = FindChildItemByMTNode (htiSelect, vNodes[i-1]);
  2322. }
  2323. /*
  2324. * select the node
  2325. */
  2326. SelectItem (htiSelect);
  2327. return (true);
  2328. }
  2329. /*+-------------------------------------------------------------------------*
  2330. * CMTBrowserCtrl::GetSelectedMTNode
  2331. *
  2332. * Returns the MTNode corresponding to the selected node in the tree
  2333. *--------------------------------------------------------------------------*/
  2334. CMTNode* CMTBrowserCtrl::GetSelectedMTNode () const
  2335. {
  2336. CMTBrowserCtrl* pMutableThis = const_cast<CMTBrowserCtrl*>(this);
  2337. return (MTNodeFromItem (pMutableThis->GetSelectedItem ()));
  2338. }
  2339. /*+-------------------------------------------------------------------------*
  2340. * CMTBrowserCtrl::CookieFromItem
  2341. *
  2342. *
  2343. *--------------------------------------------------------------------------*/
  2344. CBrowserCookie* CMTBrowserCtrl::CookieFromItem (HTREEITEM hti) const
  2345. {
  2346. return (CookieFromLParam (GetItemData (hti)));
  2347. }
  2348. CBrowserCookie* CMTBrowserCtrl::CookieFromItem (const TV_ITEM* ptvi) const
  2349. {
  2350. return (CookieFromLParam (ptvi->lParam));
  2351. }
  2352. /*+-------------------------------------------------------------------------*
  2353. * CMTBrowserCtrl::CookieFromLParam
  2354. *
  2355. *
  2356. *--------------------------------------------------------------------------*/
  2357. CBrowserCookie* CMTBrowserCtrl::CookieFromLParam (LPARAM lParam) const
  2358. {
  2359. return (reinterpret_cast<CBrowserCookie *>(lParam));
  2360. }
  2361. /*+-------------------------------------------------------------------------*
  2362. * CMTBrowserCtrl::MTNodeFromItem
  2363. *
  2364. *
  2365. *--------------------------------------------------------------------------*/
  2366. CMTNode* CMTBrowserCtrl::MTNodeFromItem (HTREEITEM hti) const
  2367. {
  2368. return (CookieFromItem(hti)->PMTNode());
  2369. }
  2370. CMTNode* CMTBrowserCtrl::MTNodeFromItem (const TV_ITEM* ptvi) const
  2371. {
  2372. return (CookieFromItem(ptvi)->PMTNode());
  2373. }
  2374. /*+-------------------------------------------------------------------------*
  2375. * CMTBrowserCtrl::FindChildItemByMTNode
  2376. *
  2377. * Returns the HTREEITEM for the child node of htiParent which refers
  2378. * to pmtnToFind, NULL if no match.
  2379. *--------------------------------------------------------------------------*/
  2380. HTREEITEM CMTBrowserCtrl::FindChildItemByMTNode (
  2381. HTREEITEM htiParent,
  2382. const CMTNode* pmtnToFind)
  2383. {
  2384. HTREEITEM htiChild;
  2385. for (htiChild = GetChildItem (htiParent);
  2386. htiChild != NULL;
  2387. htiChild = GetNextSiblingItem (htiChild))
  2388. {
  2389. if (MTNodeFromItem (htiChild) == pmtnToFind)
  2390. break;
  2391. }
  2392. return (htiChild);
  2393. }
  2394. //############################################################################
  2395. //############################################################################
  2396. //
  2397. // Implementation of class CMirrorListView
  2398. //
  2399. //############################################################################
  2400. //############################################################################
  2401. /*+-------------------------------------------------------------------------*
  2402. * HackDuplicate
  2403. *
  2404. * HACK: This is here for theming support. himlSource comes from the conui
  2405. * list control, which uses comctlv5 imagelists. A v6 list control cannot
  2406. * use v5 imagelists (images aren't drawn correctly), so we need to create
  2407. * a v6 imagelist for the v6 list control to use.
  2408. *
  2409. * ImageList_Duplicate would do the job for us, but it is not compatible
  2410. * with v5 imagelists. We'll write to and read from a v5-compatible stream
  2411. * to duplicate it instead.
  2412. *--------------------------------------------------------------------------*/
  2413. HIMAGELIST HackDuplicate (HIMAGELIST himlSource)
  2414. {
  2415. DECLARE_SC (sc, _T("HackDuplicate"));
  2416. HIMAGELIST himlDuplicate;
  2417. /*
  2418. * create a temporary stream for conversion
  2419. */
  2420. IStreamPtr spStream;
  2421. sc = CreateStreamOnHGlobal (NULL /*alloc for me*/, true /*fDeleteOnRelease*/, &spStream);
  2422. if (sc)
  2423. return (NULL);
  2424. /*
  2425. * write the source imagelist to the stream in a v5-compatible format
  2426. */
  2427. sc = WriteCompatibleImageList (himlSource, spStream);
  2428. if (sc)
  2429. return (NULL);
  2430. /*
  2431. * rewind the stream
  2432. */
  2433. LARGE_INTEGER origin = { 0, 0 };
  2434. sc = spStream->Seek (origin, STREAM_SEEK_SET, NULL);
  2435. if (sc)
  2436. return (NULL);
  2437. /*
  2438. * reconstitute the imagelist
  2439. */
  2440. sc = ReadCompatibleImageList (spStream, himlDuplicate);
  2441. if (sc)
  2442. return (NULL);
  2443. return (himlDuplicate);
  2444. }
  2445. CMirrorListView::CMirrorListView ()
  2446. : m_fVirtualSource (false)
  2447. {
  2448. }
  2449. void CMirrorListView::AttachSource (HWND hwndList, HWND hwndSourceList)
  2450. {
  2451. #ifdef DBG
  2452. /*
  2453. * the window we're attaching to should be a list view
  2454. */
  2455. TCHAR szClassName[countof (WC_LISTVIEW)];
  2456. ::GetClassName (hwndSourceList, szClassName, countof (szClassName));
  2457. ASSERT (lstrcmp (szClassName, WC_LISTVIEW) == 0);
  2458. #endif
  2459. SubclassWindow (hwndList);
  2460. m_wndSourceList = hwndSourceList;
  2461. m_fVirtualSource = (m_wndSourceList.GetStyle() & LVS_OWNERDATA) != 0;
  2462. /*
  2463. * Our listview will always be virtual, so we don't have to duplicate
  2464. * the data that may already be in the source listview. The list view
  2465. * control doesn't allow changing the LVS_OWNERDATA style bit, so we
  2466. * need to make sure that the control we're attaching to already has it
  2467. */
  2468. const DWORD dwForbiddenStyles = LVS_SHAREIMAGELISTS;
  2469. const DWORD dwRequiredImmutableStyles = LVS_OWNERDATA;
  2470. const DWORD dwRequiredMutableStyles = 0;
  2471. const DWORD dwRequiredStyles = dwRequiredImmutableStyles | dwRequiredMutableStyles;
  2472. ASSERT ((dwForbiddenStyles & dwRequiredStyles) == 0);
  2473. ASSERT ((dwRequiredImmutableStyles & dwRequiredMutableStyles) == 0);
  2474. ASSERT ((GetStyle() & dwRequiredImmutableStyles) == dwRequiredImmutableStyles);
  2475. DWORD dwStyle = GetStyle() | dwRequiredStyles & ~dwForbiddenStyles;
  2476. SetWindowLong (GWL_STYLE, dwStyle);
  2477. /*
  2478. * copy the image lists
  2479. */
  2480. SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_NORMAL)), LVSIL_NORMAL);
  2481. SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_SMALL)), LVSIL_SMALL);
  2482. SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_STATE)), LVSIL_STATE);
  2483. /*
  2484. * insert the columns
  2485. */
  2486. InsertColumns ();
  2487. /*
  2488. * copy the items (we're virtual, so copying the items only means we
  2489. * copy the item count)
  2490. */
  2491. SetItemCount (m_wndSourceList.GetItemCount());
  2492. }
  2493. /*+-------------------------------------------------------------------------*
  2494. * CMirrorListView::InsertColumns
  2495. *
  2496. *
  2497. *--------------------------------------------------------------------------*/
  2498. void CMirrorListView::InsertColumns ()
  2499. {
  2500. WTL::CRect rect;
  2501. GetClientRect (rect);
  2502. int cxColumn = rect.Width() - GetSystemMetrics (SM_CXVSCROLL);
  2503. InsertColumn (0, NULL, LVCFMT_LEFT, cxColumn, -1);
  2504. }
  2505. /*+-------------------------------------------------------------------------*
  2506. * CMirrorListView::OnGetDispInfo
  2507. *
  2508. * LVN_GETDISPINFO handler for CMirrorListView.
  2509. *--------------------------------------------------------------------------*/
  2510. LRESULT CMirrorListView::OnGetDispInfo (int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2511. {
  2512. LV_DISPINFO* plvdi = (LV_DISPINFO *) pnmh;
  2513. return (m_wndSourceList.GetItem (&plvdi->item));
  2514. }
  2515. /*+-------------------------------------------------------------------------*
  2516. * CMirrorListView::ForwardVirtualNotification
  2517. *
  2518. * Generic notification handler for CMirrorListView.
  2519. *--------------------------------------------------------------------------*/
  2520. LRESULT CMirrorListView::ForwardVirtualNotification (int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2521. {
  2522. /*
  2523. * if the source list is virtual, forward the notification
  2524. */
  2525. if (m_fVirtualSource)
  2526. return (ForwardNotification (idCtrl, pnmh, bHandled));
  2527. return (0);
  2528. }
  2529. /*+-------------------------------------------------------------------------*
  2530. * CMirrorListView::ForwardNotification
  2531. *
  2532. * Forwards list view notifications to the source list view's parent.
  2533. *--------------------------------------------------------------------------*/
  2534. LRESULT CMirrorListView::ForwardNotification (int idCtrl, LPNMHDR pnmh, BOOL& bHandled)
  2535. {
  2536. return (::SendMessage (m_wndSourceList.GetParent(),
  2537. WM_NOTIFY, idCtrl, (LPARAM) pnmh));
  2538. }
  2539. /*+-------------------------------------------------------------------------*
  2540. * CMirrorListView::ForwardMessage
  2541. *
  2542. * Forwards list view messages to the source list view.
  2543. *--------------------------------------------------------------------------*/
  2544. LRESULT CMirrorListView::ForwardMessage (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  2545. {
  2546. return (m_wndSourceList.SendMessage (uMsg, wParam, lParam));
  2547. }
  2548. /*+-------------------------------------------------------------------------*
  2549. * CMirrorListView::GetSelectedItemData
  2550. *
  2551. *
  2552. *--------------------------------------------------------------------------*/
  2553. LRESULT CMirrorListView::GetSelectedItemData ()
  2554. {
  2555. int nSelectedItem = GetSelectedIndex();
  2556. return ((m_fVirtualSource) ? nSelectedItem : GetItemData (nSelectedItem));
  2557. }
  2558. //############################################################################
  2559. //############################################################################
  2560. //
  2561. // Implementation of class CMyComboBox
  2562. //
  2563. //############################################################################
  2564. //############################################################################
  2565. /*+-------------------------------------------------------------------------*
  2566. * CMyComboBox::InsertStrings
  2567. *
  2568. *
  2569. *--------------------------------------------------------------------------*/
  2570. void CMyComboBox::InsertStrings (const int rgStringIDs[], int cStringIDs)
  2571. {
  2572. ASSERT (IsWindow ());
  2573. CStr str;
  2574. for (int i = 0; i < cStringIDs; ++i)
  2575. {
  2576. /*
  2577. * load the string and stick it in the combo
  2578. */
  2579. VERIFY (str.LoadString (GetStringModule(), rgStringIDs[i]));
  2580. int nIndex = AddString (str);
  2581. ASSERT (nIndex >= 0);
  2582. /*
  2583. * set the string ID as the combo item's data
  2584. */
  2585. SetItemData (nIndex, rgStringIDs[i]);
  2586. }
  2587. }
  2588. /*+-------------------------------------------------------------------------*
  2589. * CMyComboBox::GetSelectedItemData
  2590. *
  2591. *
  2592. *--------------------------------------------------------------------------*/
  2593. LPARAM CMyComboBox::GetSelectedItemData () const
  2594. {
  2595. return (GetItemData (GetCurSel ()));
  2596. }
  2597. /*+-------------------------------------------------------------------------*
  2598. * CMyComboBox::SelectItemByData
  2599. *
  2600. *
  2601. *--------------------------------------------------------------------------*/
  2602. void CMyComboBox::SelectItemByData (LPARAM lParam)
  2603. {
  2604. int nIndex = FindItemByData(lParam);
  2605. if (nIndex != -1)
  2606. SetCurSel (nIndex);
  2607. }
  2608. /*+-------------------------------------------------------------------------*
  2609. * CMyComboBox::FindItemByData
  2610. *
  2611. *
  2612. *--------------------------------------------------------------------------*/
  2613. int CMyComboBox::FindItemByData (LPARAM lParam) const
  2614. {
  2615. int cItems = GetCount ();
  2616. for (int i = 0; i < cItems; i++)
  2617. {
  2618. if (GetItemData (i) == lParam)
  2619. break;
  2620. }
  2621. ASSERT (i <= cItems);
  2622. if (i >= cItems)
  2623. i = -1;
  2624. return (i);
  2625. }
  2626. //############################################################################
  2627. //############################################################################
  2628. //
  2629. // Utility functions
  2630. //
  2631. //############################################################################
  2632. //############################################################################
  2633. namespace MMC
  2634. {
  2635. /*+-------------------------------------------------------------------------*
  2636. * GetWindowText
  2637. *
  2638. * Returns the text for a given window in the form of a tstring
  2639. *--------------------------------------------------------------------------*/
  2640. tstring GetWindowText (HWND hwnd)
  2641. {
  2642. int cchText = GetWindowTextLength (hwnd) + 1;
  2643. if(0==cchText)
  2644. return TEXT("");
  2645. LPTSTR pszText = NULL;
  2646. try
  2647. {
  2648. pszText = (LPTSTR) _alloca (cchText * sizeof (TCHAR));
  2649. }
  2650. // catch(...) is needed (and safe) here because _alloca does not document the exception class used.
  2651. // in addition, the only function called in the try block is _alloca, so we're not masking any othercatch(...)
  2652. // errors
  2653. catch(...)
  2654. {
  2655. return TEXT("");
  2656. }
  2657. ::GetWindowText (hwnd, pszText, cchText);
  2658. return (pszText);
  2659. }
  2660. }; // namespace MMC
  2661. /*+-------------------------------------------------------------------------*
  2662. * PreventMFCAutoCenter
  2663. *
  2664. * MFC applications set a CBT hook which will subclass all non-MFC windows
  2665. * with an MFC subclass proc. That subclass proc will auto-magically center
  2666. * dialogs on their parents.
  2667. *
  2668. * We can prevent this auto-centering, by slightly adjusting the position of
  2669. * the window during WM_INITDIALOG.
  2670. *--------------------------------------------------------------------------*/
  2671. void PreventMFCAutoCenter (MMC_ATL::CWindow* pwnd)
  2672. {
  2673. RECT rect;
  2674. pwnd->GetWindowRect (&rect);
  2675. OffsetRect (&rect, 0, 1);
  2676. pwnd->MoveWindow (&rect, false);
  2677. }
  2678. /*+-------------------------------------------------------------------------*
  2679. * LoadSysColorBitmap
  2680. *
  2681. * Loads a bitmap resource and converts gray scale colors to the 3-D colors
  2682. * of the current color scheme.
  2683. *--------------------------------------------------------------------------*/
  2684. HBITMAP LoadSysColorBitmap (HINSTANCE hInst, UINT id, bool bMono)
  2685. {
  2686. return ((HBITMAP) LoadImage (hInst, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0,
  2687. LR_LOADMAP3DCOLORS));
  2688. }
  2689. //############################################################################
  2690. //############################################################################
  2691. //
  2692. // Implementation of class CTaskPropertySheet
  2693. //
  2694. //############################################################################
  2695. //############################################################################
  2696. CTaskPropertySheet::CTaskPropertySheet(HWND hWndParent, CTaskpadFrame * pTaskpadFrame,
  2697. CConsoleTask &consoleTask, bool fNew) :
  2698. m_consoleTask(consoleTask),
  2699. m_namePage(pTaskpadFrame, ConsoleTask(), fNew),
  2700. m_cmdLinePage(pTaskpadFrame, ConsoleTask(), fNew),
  2701. m_taskSymbolDialog(ConsoleTask())
  2702. {
  2703. // Add property pages
  2704. AddPage(m_namePage);
  2705. AddPage(m_taskSymbolDialog);
  2706. if(consoleTask.GetTaskType()==eTask_CommandLine)
  2707. AddPage(m_cmdLinePage);
  2708. static CStr strModifyTitle;
  2709. strModifyTitle.LoadString(GetStringModule(),
  2710. IDS_TaskProps_ModifyTitle);
  2711. // set internal state - not using ATL's SetTitle because of bogus assert.
  2712. m_psh.pszCaption = (LPCTSTR) strModifyTitle;
  2713. m_psh.dwFlags &= ~PSH_PROPTITLE;
  2714. }
  2715. //############################################################################
  2716. //############################################################################
  2717. //
  2718. // Implementation of class CTaskWizard
  2719. //
  2720. //############################################################################
  2721. //############################################################################
  2722. HRESULT
  2723. CTaskWizard::Show(HWND hWndParent, CTaskpadFrame * pTaskpadFrame, bool fNew, bool *pfRestartTaskWizard)
  2724. {
  2725. USES_CONVERSION;
  2726. *pfRestartTaskWizard = false;
  2727. IFramePrivatePtr spFrame;
  2728. spFrame.CreateInstance(CLSID_NodeInit,
  2729. #if _MSC_VER >= 1100
  2730. NULL,
  2731. #endif
  2732. MMC_CLSCTX_INPROC);
  2733. IPropertySheetProviderPtr pIPSP = spFrame;
  2734. if (pIPSP == NULL)
  2735. return S_FALSE;
  2736. HRESULT hr = pIPSP->CreatePropertySheet (L"Cool :-)", FALSE, NULL, NULL,
  2737. MMC_PSO_NEWWIZARDTYPE);
  2738. CHECK_HRESULT(hr);
  2739. if (FAILED(hr))
  2740. return hr;
  2741. // create property pages
  2742. CTaskWizardWelcomePage welcomePage (pTaskpadFrame, ConsoleTask(), fNew);
  2743. CTaskWizardTypePage typePage (pTaskpadFrame, ConsoleTask(), fNew);
  2744. CTaskCmdLineWizardPage cmdLinePage (pTaskpadFrame, ConsoleTask(), fNew);
  2745. CTaskWizardFavoritePage favoritePage(pTaskpadFrame, ConsoleTask(), fNew);
  2746. CTaskWizardMenuPage menuPage (pTaskpadFrame, ConsoleTask(), fNew);
  2747. CTaskNameWizardPage namePage (pTaskpadFrame, ConsoleTask(), fNew);
  2748. CTaskSymbolWizardPage symbolPage (ConsoleTask());
  2749. CTaskWizardFinishPage finishPage (pTaskpadFrame, ConsoleTask(), pfRestartTaskWizard);
  2750. // create the pages we'll add in IExtendPropertySheet::CreatePropertyPages
  2751. CExtendPropSheet* peps;
  2752. hr = CExtendPropSheet::CreateInstance (&peps);
  2753. CHECK_HRESULT(hr);
  2754. RETURN_ON_FAIL(hr);
  2755. /*
  2756. * destroying this object will take care of releasing our ref on peps
  2757. */
  2758. IUnknownPtr spUnk = peps;
  2759. ASSERT (spUnk != NULL);
  2760. peps->SetWatermarkID (IDB_TASKPAD_WIZARD_WELCOME);
  2761. peps->SetHeaderID (IDB_TASKPAD_WIZARD_HEADER);
  2762. peps->AddPage (welcomePage.Create());
  2763. peps->AddPage (typePage.Create());
  2764. peps->AddPage (menuPage.Create());
  2765. peps->AddPage (favoritePage.Create());
  2766. peps->AddPage (cmdLinePage.Create());
  2767. peps->AddPage (namePage.Create());
  2768. peps->AddPage (symbolPage.Create());
  2769. peps->AddPage (finishPage.Create());
  2770. hr = pIPSP->AddPrimaryPages(spUnk, FALSE, NULL, FALSE);
  2771. CHECK_HRESULT(hr);
  2772. hr = pIPSP->Show((LONG_PTR)hWndParent, 0);
  2773. CHECK_HRESULT(hr);
  2774. return hr;
  2775. }
  2776. //############################################################################
  2777. //############################################################################
  2778. //
  2779. // Implementation of class CTaskWizardWelcomePage
  2780. //
  2781. //############################################################################
  2782. //############################################################################
  2783. LRESULT CTaskWizardWelcomePage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  2784. {
  2785. CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font
  2786. return 0;
  2787. }
  2788. bool
  2789. CTaskWizardWelcomePage::OnSetActive()
  2790. {
  2791. CWizardPage::OnWelcomeSetActive(m_hWnd);
  2792. return true;
  2793. }
  2794. bool
  2795. CTaskWizardWelcomePage::OnKillActive()
  2796. {
  2797. CWizardPage::OnWelcomeKillActive(m_hWnd);
  2798. return true;
  2799. }
  2800. //############################################################################
  2801. //############################################################################
  2802. //
  2803. // Implementation of class CTaskWizardFinishPage
  2804. //
  2805. //############################################################################
  2806. //############################################################################
  2807. CTaskWizardFinishPage::CTaskWizardFinishPage(CTaskpadFrame * pTaskpadFrame,
  2808. CConsoleTask & consoleTask, bool *pfRestartTaskWizard)
  2809. : m_pConsoleTask(&consoleTask),
  2810. m_taskpadFrameTemp(*pTaskpadFrame),
  2811. m_consoleTaskpadTemp(*(pTaskpadFrame->PConsoleTaskpad())),
  2812. BaseClass(&m_taskpadFrameTemp, false, false), CTaskpadFramePtr(pTaskpadFrame)
  2813. {
  2814. m_taskpadFrameTemp.SetConsoleTaskpad(&m_consoleTaskpadTemp);
  2815. m_pfRestartTaskWizard = pfRestartTaskWizard;
  2816. /*
  2817. * welcome and finish pages in Wizard97-style wizards don't have headers
  2818. */
  2819. m_psp.dwFlags |= PSP_HIDEHEADER;
  2820. }
  2821. LRESULT CTaskWizardFinishPage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  2822. {
  2823. BaseClass::OnInitDialog(uMsg, wParam, lParam, bHandled); // call the base class -required here.
  2824. CWizardPage::OnInitFinishPage(m_hWnd); // set up the correct title font
  2825. CheckDlgButton(IDB_RESTART_TASK_WIZARD, BST_UNCHECKED);
  2826. return 0;
  2827. }
  2828. BOOL
  2829. CTaskWizardFinishPage::OnSetActive()
  2830. {
  2831. // Set the correct wizard buttons.
  2832. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH);
  2833. CConsoleTaskpad* pTaskpad = m_taskpadFrameTemp.PConsoleTaskpad();
  2834. *pTaskpad = *(CTaskpadFramePtr::PTaskpadFrame()->PConsoleTaskpad()); // reset the taskpad
  2835. CConsoleTaskpad::TaskIter itTask = pTaskpad->EndTask();
  2836. // add the task to the list.
  2837. UpdateTaskListbox (pTaskpad->InsertTask (itTask, ConsoleTask()));
  2838. return TRUE;
  2839. }
  2840. BOOL
  2841. CTaskWizardFinishPage::OnWizardFinish()
  2842. {
  2843. *m_pfRestartTaskWizard = (IsDlgButtonChecked(IDB_RESTART_TASK_WIZARD)==BST_CHECKED);
  2844. return TRUE;
  2845. }
  2846. int
  2847. CTaskWizardFinishPage::OnWizardBack()
  2848. {
  2849. // Set the correct wizard buttons.
  2850. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  2851. return 0;
  2852. }
  2853. //############################################################################
  2854. //############################################################################
  2855. //
  2856. // Implementation of class CTaskWizardTypePage
  2857. //
  2858. //############################################################################
  2859. //############################################################################
  2860. CTaskWizardTypePage::CTaskWizardTypePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew)
  2861. :
  2862. CTaskpadFramePtr(pTaskpadFrame)
  2863. {
  2864. m_pConsoleTask = &consoleTask;
  2865. }
  2866. int
  2867. CTaskWizardTypePage::OnWizardNext()
  2868. {
  2869. int ID = 0;
  2870. // go to the appropriate page.
  2871. switch(ConsoleTask().GetTaskType())
  2872. {
  2873. case eTask_Result:
  2874. case eTask_Scope:
  2875. case eTask_Target:
  2876. ID = IDD_TASK_WIZARD_MENU_PAGE;
  2877. break;
  2878. case eTask_CommandLine:
  2879. ID = IDD_TASK_WIZARD_CMDLINE_PAGE;
  2880. break;
  2881. case eTask_Favorite:
  2882. ID = IDD_TASK_WIZARD_FAVORITE_PAGE;
  2883. break;
  2884. default:
  2885. ASSERT(0 && "Should not come here.");
  2886. break;
  2887. }
  2888. return ID;
  2889. }
  2890. LRESULT
  2891. CTaskWizardTypePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  2892. {
  2893. int ID = 0;
  2894. switch (ConsoleTask().GetTaskType())
  2895. {
  2896. case eTask_Result:
  2897. case eTask_Target: // all these types have identical handlers in this page.
  2898. case eTask_Scope:
  2899. ID = IDC_MENU_TASK;
  2900. break;
  2901. case eTask_CommandLine:
  2902. ID = IDC_CMDLINE_TASK;
  2903. break;
  2904. case eTask_Favorite:
  2905. ID = IDC_NAVIGATION_TASK;
  2906. break;
  2907. default:
  2908. ASSERT(0 && "Should not come here.");
  2909. break;
  2910. }
  2911. ::SendDlgItemMessage(m_hWnd, ID, BM_SETCHECK, (WPARAM) true, 0);
  2912. return 0;
  2913. }
  2914. LRESULT
  2915. CTaskWizardTypePage::OnMenuTask ( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  2916. {
  2917. if( (ConsoleTask().GetTaskType() != eTask_Scope) ||
  2918. (ConsoleTask().GetTaskType() != eTask_Result) ) // if changing task types
  2919. {
  2920. ConsoleTask() = CConsoleTask(); // clear out the task info.
  2921. ConsoleTask().SetTaskType(eTask_Scope);
  2922. }
  2923. return 0;
  2924. }
  2925. LRESULT
  2926. CTaskWizardTypePage::OnCmdLineTask( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  2927. {
  2928. if(ConsoleTask().GetTaskType() != eTask_CommandLine) // if changing task types
  2929. {
  2930. ConsoleTask() = CConsoleTask(); // clear out the task info.
  2931. ConsoleTask().SetTaskType(eTask_CommandLine);
  2932. }
  2933. return 0;
  2934. }
  2935. LRESULT
  2936. CTaskWizardTypePage::OnFavoriteTask(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  2937. {
  2938. if(ConsoleTask().GetTaskType() != eTask_Favorite) // if changing task types
  2939. {
  2940. ConsoleTask() = CConsoleTask(); // clear out the task info.
  2941. ConsoleTask().SetTaskType(eTask_Favorite);
  2942. }
  2943. return 0;
  2944. }
  2945. //############################################################################
  2946. //############################################################################
  2947. //
  2948. // Implementation of class CTaskNamePage
  2949. //
  2950. //############################################################################
  2951. //############################################################################
  2952. CTaskNamePage::CTaskNamePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew)
  2953. :
  2954. CTaskpadFramePtr(pTaskpadFrame)
  2955. {
  2956. m_pConsoleTask = &consoleTask;
  2957. /*
  2958. * if this page is for a new task, we'll be running in a wizard (not
  2959. * a property sheet)
  2960. */
  2961. m_fRunAsWizard = fNew;
  2962. }
  2963. BOOL
  2964. CTaskNamePage::SetTaskName(bool fCheckIfOK)
  2965. {
  2966. /*
  2967. * get the task name
  2968. */
  2969. CWindow wndTaskName = GetDlgItem (IDC_TaskName);
  2970. tstring strName = MMC::GetWindowText (wndTaskName);
  2971. /*
  2972. * a name is required (usually)
  2973. */
  2974. if (fCheckIfOK && strName.empty())
  2975. {
  2976. CStr strError;
  2977. strError.LoadString(GetStringModule(),
  2978. IDS_TaskProps_ErrorNoTaskName);
  2979. MessageBox (strError);
  2980. wndTaskName.SetFocus ();
  2981. return (false); // don't allow the change.
  2982. }
  2983. /*
  2984. * get the description
  2985. */
  2986. tstring strDescription = MMC::GetWindowText (GetDlgItem (IDC_TaskDescription));
  2987. /*
  2988. * update the task
  2989. */
  2990. ConsoleTask().SetName (strName);
  2991. ConsoleTask().SetDescription (strDescription);
  2992. return (true);
  2993. }
  2994. int
  2995. CTaskNamePage::OnWizardNext()
  2996. {
  2997. if(!SetTaskName(true))
  2998. return -1;
  2999. return IDD_TASK_WIZARD_SYMBOL_PAGE;
  3000. }
  3001. int
  3002. CTaskNamePage::OnWizardBack()
  3003. {
  3004. int ID = 0;
  3005. // go to the appropriate page.
  3006. switch(ConsoleTask().GetTaskType())
  3007. {
  3008. case eTask_Result:
  3009. case eTask_Scope:
  3010. case eTask_Target:
  3011. ID = IDD_TASK_WIZARD_MENU_PAGE;
  3012. break;
  3013. case eTask_CommandLine:
  3014. ID = IDD_TASK_WIZARD_CMDLINE_PAGE;
  3015. break;
  3016. case eTask_Favorite:
  3017. ID = IDD_TASK_WIZARD_FAVORITE_PAGE;
  3018. break;
  3019. default:
  3020. ASSERT(0 && "Should not come here.");
  3021. break;
  3022. }
  3023. return ID;
  3024. }
  3025. BOOL
  3026. CTaskNamePage::OnSetActive()
  3027. {
  3028. // Set the correct wizard buttons (only if we're running as a wizard)
  3029. if (m_fRunAsWizard)
  3030. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT);
  3031. ::SetDlgItemText (m_hWnd, IDC_TaskName, ConsoleTask().GetName().data());
  3032. ::SetDlgItemText (m_hWnd, IDC_TaskDescription, ConsoleTask().GetDescription().data());
  3033. return TRUE;
  3034. }
  3035. BOOL
  3036. CTaskNamePage::OnKillActive()
  3037. {
  3038. SetTaskName(false); // don't care if it is blank (eg if user pressed "Back" button.)
  3039. return TRUE;
  3040. }
  3041. //############################################################################
  3042. //############################################################################
  3043. //
  3044. // Implementation of class CTaskWizardMenuPage
  3045. //
  3046. //############################################################################
  3047. //############################################################################
  3048. CTaskWizardMenuPage::CTaskWizardMenuPage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) :
  3049. CTaskpadFramePtr(pTaskpadFrame),
  3050. BC2(pTaskpadFrame, consoleTask, fNew)
  3051. {
  3052. m_pMirrorTargetNode = NULL;
  3053. }
  3054. BOOL
  3055. CTaskWizardMenuPage::OnSetActive()
  3056. {
  3057. return TRUE;
  3058. }
  3059. BOOL
  3060. CTaskWizardMenuPage::OnKillActive()
  3061. {
  3062. return TRUE;
  3063. }
  3064. int
  3065. CTaskWizardMenuPage::OnWizardNext()
  3066. {
  3067. if(m_wndCommandListbox.GetCurSel() == LB_ERR) // no selection, display error
  3068. {
  3069. CStr strTitle;
  3070. strTitle.LoadString(GetStringModule(), IDS_TASK_MENU_COMMAND_REQUIRED);
  3071. MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION);
  3072. return -1;
  3073. }
  3074. return IDD_TASK_WIZARD_NAME_PAGE;
  3075. }
  3076. CTaskWizardMenuPage::_TaskSource
  3077. CTaskWizardMenuPage::s_rgTaskSource[] =
  3078. {
  3079. {IDS_TASKSOURCE_RESULT, eTask_Result},
  3080. {IDS_TASKSOURCE_SCOPE, eTask_Scope},
  3081. };
  3082. LRESULT
  3083. CTaskWizardMenuPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  3084. {
  3085. //attach HWNDs to CWindows
  3086. m_wndCommandListbox = GetDlgItem (IDC_CommandList);
  3087. CNode* pTargetNode = NULL;
  3088. if(PTaskpadFrame()->PConsoleTaskpad()->HasTarget())
  3089. pTargetNode = PNodeTarget();
  3090. // populate the drop down
  3091. m_wndSourceCombo = GetDlgItem (IDC_TASK_SOURCE_COMBO);
  3092. for (int i = 0; i < countof (s_rgTaskSource); i++)
  3093. {
  3094. CStr str;
  3095. VERIFY (str.LoadString(GetStringModule(), s_rgTaskSource[i].idsName));
  3096. VERIFY (m_wndSourceCombo.InsertString (-1, str) == i);
  3097. }
  3098. /*
  3099. * attach the scope browser to the scope tree
  3100. */
  3101. CMTBrowserCtrl::InitData init;
  3102. init.hwnd = GetDlgItem (IDC_ScopeTree);
  3103. init.pScopeTree = PScopeTree();
  3104. init.pmtnSelect = (pTargetNode != NULL) ? pTargetNode->GetMTNode() : NULL;
  3105. // remember the task type...
  3106. eConsoleTaskType type = ConsoleTask().GetTaskType();
  3107. m_wndScopeTree.Initialize (init);
  3108. // populate the result menu item list.
  3109. if (pTargetNode /*&& bResultTask*/)
  3110. {
  3111. InitResultView (pTargetNode);
  3112. }
  3113. // reset the task type from above...
  3114. ConsoleTask().SetTaskType(type);
  3115. EnableWindows();
  3116. OnSettingsChanged();
  3117. return 0;
  3118. }
  3119. void CTaskWizardMenuPage::ShowWindow(HWND hWnd, bool bShowWindow)
  3120. {
  3121. if (!::IsWindow(hWnd))
  3122. return;
  3123. ::ShowWindow (hWnd, bShowWindow ? SW_SHOW : SW_HIDE);
  3124. ::EnableWindow(hWnd, bShowWindow);
  3125. }
  3126. void
  3127. CTaskWizardMenuPage::EnableWindows()
  3128. {
  3129. eConsoleTaskType type = ConsoleTask().GetTaskType();
  3130. if(type == eTask_Target)
  3131. type = eTask_Scope; // for the purposes of the UI these are identical.
  3132. // display the correct task type.
  3133. for(int i = 0; i< countof (s_rgTaskSource); i++)
  3134. {
  3135. if(s_rgTaskSource[i].type == type)
  3136. break;
  3137. }
  3138. ASSERT(i<countof(s_rgTaskSource));
  3139. bool bResultTask = ConsoleTask().GetTaskType() == eTask_Result;
  3140. m_wndSourceCombo.SetCurSel(i);
  3141. /*
  3142. // Enable ResultTask choice only if there are result items
  3143. bool bResultItems = (m_wndResultView.GetItemCount() > 0);
  3144. ASSERT(bResultItems || !bResultTask);
  3145. ::EnableWindow(GetDlgItem(IDC_RESULT_TASK), bResultItems);
  3146. */
  3147. ShowWindow(GetDlgItem(IDC_RESULT_TASK_DESCR), bResultTask);
  3148. ShowWindow(GetDlgItem(IDC_CONSOLE_TREE_CAPTION), !bResultTask);
  3149. ShowWindow(GetDlgItem(IDC_ScopeTree), !bResultTask);
  3150. ShowWindow(GetDlgItem(IDC_ResultList), bResultTask);
  3151. }
  3152. LRESULT
  3153. CTaskWizardMenuPage::OnSettingChanged( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled )
  3154. {
  3155. OnSettingsChanged();
  3156. return 0;
  3157. }
  3158. void
  3159. CTaskWizardMenuPage::OnSettingsChanged()
  3160. {
  3161. eConsoleTaskType type = s_rgTaskSource[m_wndSourceCombo.GetCurSel()].type;
  3162. ConsoleTask().SetTaskType(type);
  3163. EnableWindows();
  3164. if(type == eTask_Scope)
  3165. {
  3166. HTREEITEM hti = m_wndScopeTree.GetSelectedItem();
  3167. m_wndScopeTree.SelectItem(NULL); // remove the selection
  3168. m_wndScopeTree.SelectItem(hti); // reselect it.
  3169. }
  3170. else
  3171. {
  3172. // empty the list box
  3173. m_wndCommandListbox.ResetContent();
  3174. SelectFirstResultItem(false);
  3175. SelectFirstResultItem(true);
  3176. }
  3177. }
  3178. /*+-------------------------------------------------------------------------*
  3179. * CTaskWizardMenuPage::OnScopeItemChanged
  3180. *
  3181. *
  3182. /*+-------------------------------------------------------------------------*/
  3183. LRESULT CTaskWizardMenuPage::OnScopeItemChanged(int id, LPNMHDR pnmh, BOOL& bHandled)
  3184. {
  3185. // empty the list box
  3186. m_wndCommandListbox.ResetContent();
  3187. LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh;
  3188. CBrowserCookie *pBrowserCookie = m_wndScopeTree.CookieFromItem (&pnmtv->itemNew);
  3189. if(!pBrowserCookie) // no item selected
  3190. return 0;
  3191. CNode* pNode = pBrowserCookie->PNode();
  3192. CMTNode * pMTNode = pBrowserCookie->PMTNode();
  3193. // validate parameters
  3194. ASSERT(pMTNode);
  3195. ASSERT(PTaskpadFrame()->PViewData());
  3196. if(!pNode)
  3197. {
  3198. pNode = pMTNode->GetNode(PTaskpadFrame()->PViewData());
  3199. if(!pNode)
  3200. return 0;
  3201. pBrowserCookie->SetNode(pNode);
  3202. HRESULT hr = pNode->InitComponents();
  3203. if (FAILED(hr))
  3204. return 0;
  3205. }
  3206. bool bNodeIsTarget = PTaskpadFrame()->PConsoleTaskpad()->HasTarget() &&
  3207. (PNodeTarget()->GetMTNode() == pNode->GetMTNode());
  3208. // set the correct task type.
  3209. ConsoleTask().SetTaskType(bNodeIsTarget ? eTask_Target : eTask_Scope);
  3210. // retarget the scope node bookmark
  3211. if(!bNodeIsTarget)
  3212. ConsoleTask().RetargetScopeNode(pNode);
  3213. int cResultItemCount = ListView_GetItemCount(m_MirroredView.GetListCtrl());
  3214. SC sc = ScTraverseContextMenu(pNode, PScopeTree(), TRUE, PTaskpadFrame()->PNodeTarget(),
  3215. 0, bNodeIsTarget && (cResultItemCount > 0)/*bShowSaveList*/);
  3216. return (0);
  3217. }
  3218. void CTaskWizardMenuPage::InitResultView (CNode* pRootNode)
  3219. {
  3220. /*
  3221. * create the temporary view whose contents we'll mirror
  3222. */
  3223. ASSERT (pRootNode != NULL);
  3224. m_pMirrorTargetNode = m_MirroredView.Create (PScopeTree()->GetConsoleFrame(), pRootNode);
  3225. ASSERT (m_pMirrorTargetNode != NULL);
  3226. /*
  3227. * force the snap-in into a standard list view
  3228. */
  3229. HRESULT hr;
  3230. hr = m_pMirrorTargetNode->InitComponents ();
  3231. hr = m_pMirrorTargetNode->ShowStandardListView ();
  3232. if (FAILED (hr))
  3233. {
  3234. // TODO(jeffro): handle snap-ins that don't support a standard list view
  3235. }
  3236. /*
  3237. * attach the temporary view's list view to our mirror list view
  3238. */
  3239. m_wndResultView.AttachSource (GetDlgItem (IDC_ResultList),
  3240. m_MirroredView.GetListCtrl());
  3241. //SelectFirstResultItem();
  3242. }
  3243. void CTaskWizardMenuPage::SelectFirstResultItem(bool bSelect)
  3244. {
  3245. /*
  3246. * Select the first item. Note that one would think we'd be able to use:
  3247. *
  3248. * m_wndResultView.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED);
  3249. *
  3250. * to select the item. We can't though because that overload of
  3251. * SetItemState sends LVM_SETITEM, which fails for virtual listviews.
  3252. *
  3253. * If we instead use:
  3254. *
  3255. * m_wndResultView.SetItemState (nItem, LV_ITEM* pItem)
  3256. *
  3257. * then LVM_SETITEMSTATE will be sent, which works for virtual listviews.
  3258. */
  3259. int i = m_wndResultView.GetItemCount();
  3260. if(i == 0)
  3261. return;
  3262. LV_ITEM lvi;
  3263. lvi.mask = LVIF_STATE;
  3264. lvi.iItem = 0;
  3265. lvi.state = bSelect ? LVIS_SELECTED : 0;
  3266. lvi.stateMask = LVIS_SELECTED;
  3267. m_wndResultView.SetItemState (0, &lvi);
  3268. }
  3269. /*+-------------------------------------------------------------------------*
  3270. * CTaskWizardMenuPage::OnResultItemChanged
  3271. *
  3272. *
  3273. *--------------------------------------------------------------------------*/
  3274. LRESULT CTaskWizardMenuPage::OnResultItemChanged(int id, LPNMHDR pnmh, BOOL& bHandled)
  3275. {
  3276. NM_LISTVIEW* pnmlv = (NM_LISTVIEW*) pnmh;
  3277. /*
  3278. * if a new item is being selected, populate the result menu item list
  3279. */
  3280. if ((pnmlv->uNewState & LVIS_SELECTED) && !(pnmlv->uOldState & LVIS_SELECTED))
  3281. {
  3282. ASSERT (m_pMirrorTargetNode != NULL);
  3283. m_wndCommandListbox.ResetContent();
  3284. SC sc = ScTraverseContextMenu (m_pMirrorTargetNode,
  3285. PScopeTree(), FALSE, NULL,
  3286. m_wndResultView.GetSelectedItemData ());
  3287. }
  3288. // set the correct task type.
  3289. ConsoleTask().SetTaskType(eTask_Result);
  3290. return (0);
  3291. }
  3292. //############################################################################
  3293. //############################################################################
  3294. //
  3295. // Implementation of class CTaskWizardFavoritePage
  3296. //
  3297. //############################################################################
  3298. //############################################################################
  3299. CTaskWizardFavoritePage::CTaskWizardFavoritePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew)
  3300. : CTaskpadFramePtr(pTaskpadFrame), m_bItemSelected(false)
  3301. {
  3302. m_pConsoleTask = &consoleTask;
  3303. }
  3304. CTaskWizardFavoritePage::~CTaskWizardFavoritePage()
  3305. {
  3306. }
  3307. BOOL
  3308. CTaskWizardFavoritePage::OnSetActive()
  3309. {
  3310. SetItemSelected(m_bItemSelected); // restore the state.
  3311. return true;
  3312. }
  3313. BOOL
  3314. CTaskWizardFavoritePage::OnKillActive()
  3315. {
  3316. return true;
  3317. }
  3318. int
  3319. CTaskWizardFavoritePage::OnWizardBack()
  3320. {
  3321. // Set the correct wizard buttons.
  3322. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
  3323. return IDD_TASK_WIZARD_TYPE_PAGE;
  3324. }
  3325. int
  3326. CTaskWizardFavoritePage::OnWizardNext()
  3327. {
  3328. return IDD_TASK_WIZARD_NAME_PAGE;
  3329. }
  3330. void
  3331. CTaskWizardFavoritePage::SetItemSelected(bool bItemSelected)
  3332. {
  3333. m_bItemSelected = bItemSelected;
  3334. // Set the correct wizard buttons.
  3335. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (bItemSelected ? (PSWIZB_BACK | PSWIZB_NEXT)
  3336. : (PSWIZB_BACK));
  3337. }
  3338. LRESULT
  3339. CTaskWizardFavoritePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  3340. {
  3341. CConsoleView* pConsoleView = PTaskpadFrame()->PViewData()->GetConsoleView();
  3342. if (pConsoleView != NULL)
  3343. {
  3344. HWND hwndCtrl = pConsoleView->CreateFavoriteObserver (m_hWnd, IDC_FavoritesTree);
  3345. ASSERT(hwndCtrl != NULL);
  3346. HWND hWndStatic = GetDlgItem(IDC_FAVORITE_STATIC);
  3347. ASSERT(hWndStatic != NULL);
  3348. RECT rectStatic;
  3349. ::GetWindowRect(hWndStatic, &rectStatic);
  3350. WTL::CPoint pointTopLeft;
  3351. pointTopLeft.y = rectStatic.top;
  3352. pointTopLeft.x = rectStatic.left;
  3353. ::ScreenToClient(m_hWnd, &pointTopLeft);
  3354. ::SetWindowPos(hwndCtrl, NULL,
  3355. pointTopLeft.x, pointTopLeft.y,
  3356. rectStatic.right -rectStatic.left,
  3357. rectStatic.bottom - rectStatic.top,
  3358. SWP_NOZORDER);
  3359. }
  3360. return 0;
  3361. }
  3362. LRESULT
  3363. CTaskWizardFavoritePage::OnItemChanged (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  3364. {
  3365. CMemento *pMemento = (CMemento *)wParam;
  3366. if(pMemento != NULL)
  3367. {
  3368. ConsoleTask().SetMemento(*pMemento);
  3369. }
  3370. else
  3371. {
  3372. // Set the correct wizard buttons.
  3373. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK);
  3374. }
  3375. SetItemSelected(pMemento!=NULL);
  3376. return 0;
  3377. }
  3378. //############################################################################
  3379. //############################################################################
  3380. //
  3381. // Implementation of class CTaskCmdLinePage
  3382. //
  3383. //############################################################################
  3384. //############################################################################
  3385. // contents of the "Run:" combo box
  3386. const int const CTaskCmdLinePage::s_rgidWindowStates[] =
  3387. {
  3388. IDS_TaskProps_Restored,
  3389. IDS_TaskProps_Minimized,
  3390. IDS_TaskProps_Maximized,
  3391. };
  3392. CTaskCmdLinePage::CTaskCmdLinePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew)
  3393. : m_hBitmapRightArrow(NULL), CTaskpadFramePtr(pTaskpadFrame)
  3394. {
  3395. m_pConsoleTask = &consoleTask;
  3396. }
  3397. CTaskCmdLinePage::~CTaskCmdLinePage()
  3398. {
  3399. if(m_hBitmapRightArrow)
  3400. ::DeleteObject(m_hBitmapRightArrow);
  3401. }
  3402. BOOL
  3403. CTaskCmdLinePage::OnSetActive()
  3404. {
  3405. return TRUE;
  3406. }
  3407. BOOL
  3408. CTaskCmdLinePage::OnKillActive()
  3409. {
  3410. switch (m_wndWindowStateCombo.GetSelectedItemData())
  3411. {
  3412. case IDS_TaskProps_Restored:
  3413. ConsoleTask().SetWindowState (eState_Restored);
  3414. break;
  3415. case IDS_TaskProps_Maximized:
  3416. ConsoleTask().SetWindowState (eState_Maximized);
  3417. break;
  3418. case IDS_TaskProps_Minimized:
  3419. ConsoleTask().SetWindowState (eState_Minimized);
  3420. break;
  3421. }
  3422. ConsoleTask().SetCommand (MMC::GetWindowText (GetDlgItem (IDC_Command)));
  3423. ConsoleTask().SetParameters(MMC::GetWindowText (GetDlgItem (IDC_CommandArgs)));
  3424. ConsoleTask().SetDirectory (MMC::GetWindowText (GetDlgItem (IDC_CommandWorkingDir)));
  3425. return TRUE;
  3426. }
  3427. int
  3428. CTaskCmdLinePage::OnWizardNext()
  3429. {
  3430. // make sure we have a command
  3431. tstring strCommand = MMC::GetWindowText (GetDlgItem (IDC_Command));
  3432. if (strCommand.empty())
  3433. {
  3434. CStr strError;
  3435. strError.LoadString(GetStringModule(),
  3436. IDS_TaskProps_ErrorNoCommand);
  3437. MessageBox (strError);
  3438. ::SetFocus (GetDlgItem (IDC_Command));
  3439. return (-1);
  3440. }
  3441. return IDD_TASK_WIZARD_NAME_PAGE;
  3442. }
  3443. LRESULT
  3444. CTaskCmdLinePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled )
  3445. {
  3446. // Attach HWNDs to CWindows
  3447. m_wndRightArrowButton = GetDlgItem (IDC_BrowseForArguments);
  3448. m_wndWindowStateCombo = GetDlgItem (IDC_CommandWindowStateCombo);
  3449. // the menu arrow (OBM_NARROW) is defined by the system.
  3450. m_hBitmapRightArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW));
  3451. m_wndRightArrowButton.SetBitmap(m_hBitmapRightArrow);
  3452. // populate the combo boxes
  3453. m_wndWindowStateCombo. InsertStrings (s_rgidWindowStates, countof (s_rgidWindowStates));
  3454. // select the appropriate items in the combo boxes
  3455. switch (ConsoleTask().GetWindowState())
  3456. {
  3457. case eState_Restored:
  3458. m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Restored);
  3459. break;
  3460. case eState_Minimized:
  3461. m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Minimized);
  3462. break;
  3463. case eState_Maximized:
  3464. m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Maximized);
  3465. break;
  3466. }
  3467. ::SetDlgItemText (m_hWnd, IDC_Command, ConsoleTask().GetCommand().data());
  3468. ::SetDlgItemText (m_hWnd, IDC_CommandArgs, ConsoleTask().GetParameters().data());
  3469. ::SetDlgItemText (m_hWnd, IDC_CommandWorkingDir, ConsoleTask().GetDirectory().data());
  3470. return 0;
  3471. }
  3472. LRESULT
  3473. CTaskCmdLinePage::OnBrowseForArguments(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  3474. {
  3475. CCommandLineArgumentsMenu commandLineArgumentsMenu(m_hWnd, IDC_BrowseForArguments,
  3476. PTaskpadFrame()->PViewData()->GetListCtrl());
  3477. if(commandLineArgumentsMenu.Popup())
  3478. {
  3479. HWND hWndCommandArgs = ::GetDlgItem(m_hWnd, IDC_CommandArgs);
  3480. // replace the selection appropriately.
  3481. ::SendMessage(hWndCommandArgs, EM_REPLACESEL, (WPARAM)(BOOL) true /*fCanUndo*/,
  3482. (LPARAM)(LPCTSTR)commandLineArgumentsMenu.GetResultString());
  3483. ::SetFocus(hWndCommandArgs);
  3484. }
  3485. return 0;
  3486. }
  3487. /*+-------------------------------------------------------------------------*
  3488. * CTaskCmdLinePage::OnBrowseForCommand
  3489. *
  3490. *
  3491. *--------------------------------------------------------------------------*/
  3492. LRESULT
  3493. CTaskCmdLinePage::OnBrowseForCommand (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  3494. {
  3495. tstring strCommand = MMC::GetWindowText (GetDlgItem (IDC_Command));
  3496. CStr strFilter;
  3497. strFilter.LoadString(GetStringModule(), IDS_TaskProps_ProgramFilter);
  3498. /*
  3499. * The file dialog expects embedded \0's in the string, but those
  3500. * don't load well. The string in the resource file has \\ where
  3501. * the \0 should be, so let's make the substitution now.
  3502. */
  3503. for (LPTSTR pch = strFilter.GetBuffer (0); *pch != _T('\0'); pch++)
  3504. {
  3505. if (*pch == _T('\\'))
  3506. *pch = _T('\0');
  3507. }
  3508. // don't call ReleaseBuffer, since the string now contains \0 chars
  3509. WTL::CFileDialog dlg (true, NULL, strCommand.data(),
  3510. OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
  3511. strFilter, m_hWnd);
  3512. if (dlg.DoModal() == IDOK)
  3513. SetDlgItemText (IDC_Command, dlg.m_szFileName);
  3514. return (0);
  3515. }
  3516. /*+-------------------------------------------------------------------------*
  3517. * BrowseForWorkingDirCallback
  3518. *
  3519. * Helper function for CTaskPropertiesBase::OnBrowseForWorkingDir. It is
  3520. * used to select the current working directory when the "Pick a Directory"
  3521. * dialog is displayed.
  3522. *--------------------------------------------------------------------------*/
  3523. int CALLBACK BrowseForWorkingDirCallback (HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData)
  3524. {
  3525. /*
  3526. * once the dialog is initialized, pre-select
  3527. * the current working directory (if there is one)
  3528. */
  3529. if ((msg == BFFM_INITIALIZED) && (lpData != NULL))
  3530. SendMessage (hwnd, BFFM_SETSELECTION, true, lpData);
  3531. return (0);
  3532. }
  3533. /*+-------------------------------------------------------------------------*
  3534. * CTaskPropertiesBase::OnBrowseForWorkingDir
  3535. *
  3536. *
  3537. *--------------------------------------------------------------------------*/
  3538. LRESULT
  3539. CTaskCmdLinePage::OnBrowseForWorkingDir (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
  3540. {
  3541. TCHAR szDisplayName[MAX_PATH];
  3542. tstring strCurrentDir = MMC::GetWindowText (GetDlgItem (IDC_CommandWorkingDir));
  3543. BROWSEINFO bi;
  3544. bi.hwndOwner = m_hWnd;
  3545. bi.pidlRoot = NULL;
  3546. bi.pszDisplayName = szDisplayName;
  3547. bi.lpszTitle = NULL;
  3548. bi.ulFlags = BIF_RETURNONLYFSDIRS;
  3549. bi.lpfn = BrowseForWorkingDirCallback;
  3550. bi.lParam = (strCurrentDir.empty()) ? NULL : (LPARAM) strCurrentDir.data();
  3551. bi.iImage = 0;
  3552. LPITEMIDLIST pidlWorkingDir = SHBrowseForFolder (&bi);
  3553. if (pidlWorkingDir != NULL)
  3554. {
  3555. /*
  3556. * expand the pidl and put the working directory into the control
  3557. */
  3558. SHGetPathFromIDList (pidlWorkingDir, szDisplayName);
  3559. SetDlgItemText (IDC_CommandWorkingDir, szDisplayName);
  3560. /*
  3561. * free the pidl
  3562. */
  3563. IMallocPtr spMalloc;
  3564. SHGetMalloc (&spMalloc);
  3565. spMalloc->Free (pidlWorkingDir);
  3566. }
  3567. return (0);
  3568. }
  3569. //############################################################################
  3570. //############################################################################
  3571. //
  3572. // Implementation of class CTempAMCView
  3573. //
  3574. //############################################################################
  3575. //############################################################################
  3576. CNode* CTempAMCView::Create (CConsoleFrame* pFrame, CNode* pRootNode)
  3577. {
  3578. ASSERT (pRootNode != NULL);
  3579. return (Create (pFrame, pRootNode->GetMTNode()));
  3580. }
  3581. CNode* CTempAMCView::Create (CConsoleFrame* pFrame, CMTNode* pRootMTNode)
  3582. {
  3583. ASSERT (pRootMTNode != NULL);
  3584. return (Create (pFrame, pRootMTNode->GetID()));
  3585. }
  3586. CNode* CTempAMCView::Create (CConsoleFrame* pFrame, MTNODEID idRootNode)
  3587. {
  3588. HRESULT hr;
  3589. ASSERT (idRootNode != 0);
  3590. ASSERT (pFrame != NULL);
  3591. CConsoleView* pConsoleView = NULL;
  3592. /*
  3593. * clean up an existing view
  3594. */
  3595. Destroy();
  3596. ASSERT (m_pViewData == NULL);
  3597. /*
  3598. * create a new view
  3599. */
  3600. CreateNewViewStruct cnvs;
  3601. cnvs.idRootNode = idRootNode;
  3602. cnvs.lWindowOptions = MMC_NW_OPTION_NOPERSIST;
  3603. cnvs.fVisible = false;
  3604. SC sc = pFrame->ScCreateNewView(&cnvs);
  3605. if (sc)
  3606. goto Error;
  3607. m_pViewData = reinterpret_cast<CViewData*>(cnvs.pViewData);
  3608. /*
  3609. * select the new view's root node (can't fail)
  3610. */
  3611. pConsoleView = GetConsoleView();
  3612. ASSERT (pConsoleView != NULL);
  3613. if (pConsoleView != NULL)
  3614. sc = pConsoleView->ScSelectNode (idRootNode);
  3615. if (sc)
  3616. goto Error;
  3617. return (CNode::FromHandle(cnvs.hRootNode));
  3618. Cleanup:
  3619. return (NULL);
  3620. Error:
  3621. TraceError (_T("CTempAMCView::Create"), sc);
  3622. goto Cleanup;
  3623. }