Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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