/*--------------------------------------------------------------------------* * * Microsoft Windows * Copyright (C) Microsoft Corporation, 1992 - 1999 * * File: taskui.cpp * * Contents: Implementation file for console taskpad UI classes. * * History: 29-Oct-98 jeffro Created * *--------------------------------------------------------------------------*/ #include "stdafx.h" #include "tasks.h" #include "nodepath.h" #include "oncmenu.h" #include "scopndcb.h" #include "rsltitem.h" #include "conview.h" #include "conframe.h" #include "bitmap.h" #include "util.h" //############################################################################ //############################################################################ // // Implementation of class CTaskpadFrame // //############################################################################ //############################################################################ CTaskpadFrame::CTaskpadFrame(CNode *pNodeTarget, CConsoleTaskpad* pConsoleTaskpad, CViewData *pViewData, bool fCookieValid, LPARAM lCookie) { m_pNodeTarget = pNodeTarget; m_pConsoleTaskpad = pConsoleTaskpad; m_pViewData = pViewData; m_fCookieValid = fCookieValid; m_lCookie = lCookie; if(pConsoleTaskpad) m_pConsoleTaskpad = pConsoleTaskpad; else m_pConsoleTaskpad = new CConsoleTaskpad(); m_fNew = (pConsoleTaskpad == NULL); m_bTargetNodeSelected = (pNodeTarget != NULL); } CTaskpadFrame::CTaskpadFrame(const CTaskpadFrame &rhs) { m_pNodeTarget = rhs.m_pNodeTarget; m_pConsoleTaskpad = rhs.m_pConsoleTaskpad; m_pViewData = rhs.m_pViewData; m_fCookieValid = rhs.m_fCookieValid; m_fNew = rhs.m_fNew; m_lCookie = rhs.m_lCookie; m_bTargetNodeSelected = rhs.m_bTargetNodeSelected; } //############################################################################ //############################################################################ // // Implementation of class CWizardPage // //############################################################################ //############################################################################ WTL::CFont CWizardPage::m_fontWelcome; void CWizardPage::OnWelcomeSetActive(HWND hWnd) { WTL::CPropertySheetWindow(::GetParent(hWnd)).SetWizardButtons (PSWIZB_NEXT); } void CWizardPage::OnWelcomeKillActive(HWND hWnd) { WTL::CPropertySheetWindow(::GetParent(hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT); } void CWizardPage::InitFonts(HWND hWnd) { if (m_fontWelcome.m_hFont != NULL) return; CWindow wnd = hWnd; WTL::CClientDC dc (wnd); if (dc.m_hDC == NULL) return; // set the correct font for the title. LOGFONT lf; WTL::CFont fontDefault = wnd.GetFont(); fontDefault.GetLogFont(&lf); fontDefault.Detach(); // set the correct font for the welcome line CStr strWelcomeFont; strWelcomeFont.LoadString(GetStringModule(), IDS_WizardTitleFont); CStr strWelcomeFontSize; strWelcomeFont.LoadString(GetStringModule(), IDS_WizardTitleFontSize); int nPointSize = _ttoi(strWelcomeFont); lf.lfWeight = FW_BOLD; lf.lfHeight = -MulDiv(nPointSize, dc.GetDeviceCaps(LOGPIXELSY), 72); lf.lfWidth = 0; _tcscpy(lf.lfFaceName, strWelcomeFont); m_fontWelcome.CreateFontIndirect(&lf); } void CWizardPage::OnInitWelcomePage(HWND hDlg) { InitFonts(hDlg); CWindow wndTitle = ::GetDlgItem (hDlg, IDC_WELCOME); wndTitle.SetFont (m_fontWelcome); } void CWizardPage::OnInitFinishPage(HWND hDlg) { InitFonts(hDlg); CWindow wndTitle = ::GetDlgItem (hDlg, IDC_COMPLETING); wndTitle.SetFont (m_fontWelcome); WTL::CPropertySheetWindow(::GetParent(hDlg)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadPropertySheet // //############################################################################ //############################################################################ /* CTaskpadPropertySheet::CTaskpadPropertySheet * * PURPOSE: Constructor * * PARAMETERS: None * */ CTaskpadPropertySheet::CTaskpadPropertySheet(CNode *pNodeTarget, CConsoleTaskpad & rConsoleTaskpad, bool fNew, LPARAM lparamSelectedNode, bool fLParamValid, CViewData *pViewData, eReason reason): BC(), CTaskpadFrame(pNodeTarget, &rConsoleTaskpad, pViewData, fLParamValid, lparamSelectedNode), m_proppTaskpadGeneral(this), m_proppTasks(this, (reason == eReason_NEWTASK)? true : false), m_fInsertNode(false), m_fNew(fNew), m_eReason(reason) { // Add the property pages AddPage( m_proppTaskpadGeneral ); if(!fNew) AddPage( m_proppTasks ); if(Reason()==eReason_NEWTASK) { ASSERT(!fNew); SetActivePage(1); // the tasks page } /* * give the property sheet a title (the string must be a member so * it lives until DoModal, where it will actually get used. */ m_strTitle = rConsoleTaskpad.GetName(); /* * HACK: We should be able to use * * SetTitle (m_strTitle.data(), PSH_PROPTITLE); * * but ATL21 has a bogus assert (it asserts (lpszText == NULL) * instead of (lpszText != NULL). */ // SetTitle (m_strTitle.data(), PSH_PROPTITLE); m_psh.pszCaption = m_strTitle.data(); m_psh.dwFlags |= PSH_PROPTITLE; // hide the Apply button m_psh.dwFlags |= PSH_NOAPPLYNOW; } /*+-------------------------------------------------------------------------* * CTaskpadPropertySheet::~CTaskpadPropertySheet * * PURPOSE: * * PARAMETERS: * * RETURNS: * /*+-------------------------------------------------------------------------*/ CTaskpadPropertySheet::~CTaskpadPropertySheet() { } /*+-------------------------------------------------------------------------* * CTaskpadPropertySheet::DoModal * * PURPOSE: * * PARAMETERS: * * RETURNS: * int /*+-------------------------------------------------------------------------*/ int CTaskpadPropertySheet::DoModal() { // save the current taskpad in case the user wants to cancel. CConsoleTaskpad*pConsoleTaskpad = PConsoleTaskpad(); CConsoleTaskpad consoleTaskpad = *PConsoleTaskpad(); // make a copy CTaskpadFrame::m_pConsoleTaskpad = &consoleTaskpad; // make modifications on the copy. // call the base class method to make changes on the copy. int iResp = BC::DoModal(); if(iResp == IDOK) { *pConsoleTaskpad = consoleTaskpad; // commit changes pConsoleTaskpad->SetDirty(true); } return iResp; } //############################################################################ //############################################################################ // // Implementation of class CTaskpadWizard // //############################################################################ //############################################################################ CTaskpadWizard::CTaskpadWizard( CNode* pNodeTarget, CConsoleTaskpad& rConsoleTaskPad, bool fNew, LPARAM lparamSelectedNode, bool fLParamValid, CViewData* pViewData) : BC(pNodeTarget, &rConsoleTaskPad, pViewData, fLParamValid, lparamSelectedNode) { BC::SetNew(fNew); }; HRESULT CTaskpadWizard::Show(HWND hWndParent, bool *pfStartTaskWizard) { USES_CONVERSION; *pfStartTaskWizard = false; // save the current taskpad in case the user wants to cancel. CConsoleTaskpad*pConsoleTaskpad = PConsoleTaskpad(); CConsoleTaskpad consoleTaskpad = *PConsoleTaskpad(); // make a copy CTaskpadFrame::m_pConsoleTaskpad = &consoleTaskpad; // make modifications on the copy. // create a property sheet IFramePrivatePtr spFrame; spFrame.CreateInstance(CLSID_NodeInit, #if _MSC_VER >= 1100 NULL, #endif MMC_CLSCTX_INPROC); IPropertySheetProviderPtr pIPSP = spFrame; if (pIPSP == NULL) return S_FALSE; HRESULT hr = pIPSP->CreatePropertySheet (L"Cool :-)", FALSE, NULL, NULL, MMC_PSO_NEWWIZARDTYPE); CHECK_HRESULT(hr); RETURN_ON_FAIL(hr); // create property pages CTaskpadWizardWelcomePage welcomePage; CTaskpadStylePage stylePage(this); CTaskpadNodetypePage nodetypePage(this); CTaskpadNamePage namePage(this); CTaskpadWizardFinishPage finishPage(pfStartTaskWizard); // create the pages we'll add in IExtendPropertySheet::CreatePropertyPages CExtendPropSheet* peps; hr = CExtendPropSheet::CreateInstance (&peps); CHECK_HRESULT(hr); RETURN_ON_FAIL(hr); /* * destroying this object will take care of releasing our ref on peps */ IUnknownPtr spUnk = peps; ASSERT (spUnk != NULL); peps->SetWatermarkID (IDB_TASKPAD_WIZARD_WELCOME); peps->SetHeaderID (IDB_TASKPAD_WIZARD_HEADER); peps->AddPage (welcomePage.Create()); peps->AddPage (stylePage.Create()); peps->AddPage (nodetypePage.Create()); peps->AddPage (namePage.Create()); peps->AddPage (finishPage.Create()); hr = pIPSP->AddPrimaryPages(spUnk, FALSE, NULL, FALSE); CHECK_HRESULT(hr); hr = pIPSP->Show((LONG_PTR)hWndParent, 0); CHECK_HRESULT(hr); if(hr==S_OK) { // need to do this explicitly - wizards don't get an OnApply message. Bummer. nodetypePage.OnApply(); *pConsoleTaskpad = consoleTaskpad; // commit changes pConsoleTaskpad->SetDirty(true); } return hr; } //############################################################################ //############################################################################ // // Implementation of class CExtendPropSheetImpl // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CPropertySheetInserter * * Simple output iterator that will add pages to an MMC property sheet * by way of IPropertySheetCallback. *--------------------------------------------------------------------------*/ class CPropertySheetInserter : std::iterator { public: CPropertySheetInserter (IPropertySheetCallback* pPropSheetCallback) : m_spPropSheetCallback (pPropSheetCallback) {} CPropertySheetInserter& operator=(HANDLE hPage) { m_spPropSheetCallback->AddPage ((HPROPSHEETPAGE) hPage); return (*this); } CPropertySheetInserter& operator*() { return (*this); } CPropertySheetInserter& operator++() { return (*this); } CPropertySheetInserter operator++(int) { return (*this); } protected: IPropertySheetCallbackPtr m_spPropSheetCallback; }; /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::AddPage * * *--------------------------------------------------------------------------*/ void CExtendPropSheetImpl::AddPage (HPROPSHEETPAGE hPage) { m_vPages.push_back ((HANDLE) hPage); } /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::SetHeaderID * * *--------------------------------------------------------------------------*/ void CExtendPropSheetImpl::SetHeaderID (int nHeaderID) { m_nHeaderID = nHeaderID; } /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::SetWatermarkID * * *--------------------------------------------------------------------------*/ void CExtendPropSheetImpl::SetWatermarkID (int nWatermarkID) { m_nWatermarkID = nWatermarkID; } /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::CreatePropertyPages * * *--------------------------------------------------------------------------*/ STDMETHODIMP CExtendPropSheetImpl::CreatePropertyPages (IPropertySheetCallback* pPSC, LONG_PTR handle, IDataObject* pDO) { std::copy (m_vPages.begin(), m_vPages.end(), CPropertySheetInserter(pPSC)); return (S_OK); } /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::QueryPagesFor * * *--------------------------------------------------------------------------*/ STDMETHODIMP CExtendPropSheetImpl::QueryPagesFor (IDataObject* pDO) { return (S_OK); } /*+-------------------------------------------------------------------------* * CExtendPropSheetImpl::GetWatermarks * * *--------------------------------------------------------------------------*/ STDMETHODIMP CExtendPropSheetImpl::GetWatermarks (IDataObject* pDO, HBITMAP* phbmWatermark, HBITMAP* phbmHeader, HPALETTE* phPal, BOOL* pbStretch) { *phbmWatermark = (m_nWatermarkID) ? LoadBitmap (_Module.GetResourceInstance(), MAKEINTRESOURCE (m_nWatermarkID)) : NULL; ASSERT ((m_nWatermarkID == 0) || (*phbmWatermark != NULL)); *phbmHeader = (m_nHeaderID) ? LoadBitmap (_Module.GetResourceInstance(), MAKEINTRESOURCE (m_nHeaderID)) : NULL; ASSERT ((m_nHeaderID == 0) || (*phbmHeader != NULL)); *phPal = NULL; *pbStretch = false; return (S_OK); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadNamePage // //############################################################################ //############################################################################ CTaskpadNamePage::CTaskpadNamePage(CTaskpadFrame * pTaskpadFrame) : CTaskpadFramePtr(pTaskpadFrame) { } BOOL CTaskpadNamePage::OnSetActive() { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT); m_strName. Initialize (this, IDC_TASKPAD_TITLE, -1, PConsoleTaskpad()->GetName().data()); m_strDescription.Initialize (this, IDC_TASKPAD_DESCRIPTION,-1, PConsoleTaskpad()->GetDescription().data()); return true; } int CTaskpadNamePage::OnWizardNext() { tstring strName = MMC::GetWindowText (m_strName); if (strName.empty()) { CStr strTitle; strTitle.LoadString(GetStringModule(), IDS_TASKPAD_NAME_REQUIRED_ERROR); MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION); return -1; } tstring strDescription = MMC::GetWindowText (m_strDescription); CConsoleTaskpad* pTaskpad = PConsoleTaskpad(); pTaskpad->SetName (strName); pTaskpad->SetDescription (strDescription); return 0; } int CTaskpadNamePage::OnWizardBack() { return 0; } //############################################################################ //############################################################################ // // Implementation of class CTaskpadWizardWelcomePage // //############################################################################ //############################################################################ LRESULT CTaskpadWizardWelcomePage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font return 0; } bool CTaskpadWizardWelcomePage::OnSetActive() { CWizardPage::OnWelcomeSetActive(m_hWnd); return true; } bool CTaskpadWizardWelcomePage::OnKillActive() { CWizardPage::OnWelcomeKillActive(m_hWnd); return true; } //############################################################################ //############################################################################ // // Implementation of class CTaskpadWizardFinishPage // //############################################################################ //############################################################################ LRESULT CTaskpadWizardFinishPage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CWizardPage::OnInitFinishPage(m_hWnd); // set up the correct title font CheckDlgButton(IDC_START_TASK_WIZARD, BST_CHECKED); return 0; } BOOL CTaskpadWizardFinishPage::OnSetActive() { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH); return true; } BOOL CTaskpadWizardFinishPage::OnWizardFinish() { *m_pfStartTaskWizard = (IsDlgButtonChecked(IDC_START_TASK_WIZARD)==BST_CHECKED); return TRUE; } //############################################################################ //############################################################################ // // Implementation of class CTaskpadStyle // //############################################################################ //############################################################################ CTaskpadStyle::CTaskpadStyle ( ListSize eSize, int idsDescription, int nPreviewBitmapID, DWORD dwOrientation) : m_eSize (eSize), m_idsDescription (idsDescription), m_nPreviewBitmapID (nPreviewBitmapID), m_dwOrientation (dwOrientation) { } CTaskpadStyle::CTaskpadStyle ( ListSize eSize, DWORD dwOrientation) : m_eSize (eSize), m_idsDescription (0), m_nPreviewBitmapID (0), m_dwOrientation (dwOrientation) { } CTaskpadStyle::CTaskpadStyle (const CTaskpadStyle& other) { *this = other; } /*+-------------------------------------------------------------------------* * CTaskpadStyle::operator= * * Custom assignment operator for CTaskpadStyle that does a deep copy of * its contained WTL::CBitmap. *--------------------------------------------------------------------------*/ CTaskpadStyle& CTaskpadStyle::operator= (const CTaskpadStyle& other) { if (this != &other) { m_eSize = other.m_eSize; m_idsDescription = other.m_idsDescription; m_nPreviewBitmapID = other.m_nPreviewBitmapID; m_dwOrientation = other.m_dwOrientation; m_strDescription = other.m_strDescription; /* * WTL::CBitmap does a shallow copy of the bitmap. We need to * do a deep copy here so (*this) and (other) don't both * DeleteObject the same bitmap. */ if (!m_PreviewBitmap.IsNull()) m_PreviewBitmap.DeleteObject(); m_PreviewBitmap = CopyBitmap (other.m_PreviewBitmap); } return (*this); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadStyleBase // //############################################################################ //############################################################################ // static variables CTaskpadStyle CTaskpadStyleBase::s_rgTaskpadStyle[] = { // Size Description Bitmap dwOrientation CTaskpadStyle (eSize_Small, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzSml, TVO_HORIZONTAL), CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzMed, TVO_HORIZONTAL), CTaskpadStyle (eSize_Large, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzLrg, TVO_HORIZONTAL), CTaskpadStyle (eSize_Small, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzSmlD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzMedD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_Large, IDS_TPSTYLE_HORZ_DESCR, IDB_TPPreview_HorzLrgD, TVO_HORIZONTAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_Small, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertSml, TVO_VERTICAL ), CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertMed, TVO_VERTICAL ), CTaskpadStyle (eSize_Large, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertLrg, TVO_VERTICAL ), CTaskpadStyle (eSize_Small, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertSmlD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_Medium, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertMedD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_Large, IDS_TPSTYLE_VERT_DESCR, IDB_TPPreview_VertLrgD, TVO_VERTICAL | TVO_DESCRIPTIONS_AS_TEXT), CTaskpadStyle (eSize_None, IDS_TPSTYLE_NOLIST_DESCR, IDB_TPPreview_Tasks, TVO_NO_RESULTS), CTaskpadStyle (eSize_None, IDS_TPSTYLE_NOLIST_DESCR, IDB_TPPreview_TasksD, TVO_NO_RESULTS | TVO_DESCRIPTIONS_AS_TEXT), }; CTaskpadStyleBase::CTaskpadStyleBase(CTaskpadFrame * pTaskpadFrame) : CTaskpadFramePtr(pTaskpadFrame) { } LRESULT CTaskpadStyleBase::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CWindow wndDlg = HWnd(); m_wndPreview = wndDlg.GetDlgItem (IDC_TaskpadPreview); /* * make sure the taskpad's size is valid (bias to large list) */ ListSize eSize = PConsoleTaskpad()->GetListSize(); if ((eSize != eSize_Small) && (eSize != eSize_Medium)) eSize = eSize_Large; ASSERT ((eSize == eSize_Small) || (eSize == eSize_Large) || (eSize == eSize_Medium)); /* * prime the combo box */ m_wndSizeCombo = wndDlg.GetDlgItem (IDC_Style_SizeCombo); static const struct { ListSize eSize; int nTextID; } ComboData[] = { { eSize_Small, IDS_Small }, { eSize_Medium, IDS_Medium }, { eSize_Large, IDS_Large }, }; for (int i = 0; i < countof (ComboData); i++) { CStr str; VERIFY (str.LoadString(GetStringModule(), ComboData[i].nTextID)); VERIFY (m_wndSizeCombo.InsertString (-1, str) == i); m_wndSizeCombo.SetItemData (i, ComboData[i].eSize); if (eSize == ComboData[i].eSize) m_wndSizeCombo.SetCurSel (i); } /* * make sure something is selected */ ASSERT (m_wndSizeCombo.GetCurSel() != CB_ERR); /* * prime the radio buttons */ int nID; DWORD dwOrientation = PConsoleTaskpad()->GetOrientation(); nID = (dwOrientation & TVO_VERTICAL) ? IDC_Style_VerticalList : (dwOrientation & TVO_HORIZONTAL) ? IDC_Style_HorizontalList : IDC_Style_TasksOnly; CheckRadioButton (HWnd(), IDC_Style_VerticalList, IDC_Style_TasksOnly, nID); nID = (dwOrientation & TVO_DESCRIPTIONS_AS_TEXT) ? IDC_Style_TextDesc : IDC_Style_TooltipDesc; CheckRadioButton (HWnd(), IDC_Style_TooltipDesc, IDC_Style_TextDesc, nID); ASSERT (s_rgTaskpadStyle[FindStyle (dwOrientation, eSize)] == CTaskpadStyle (eSize, dwOrientation)); // prime the check box bool bReplacesDefaultView = PConsoleTaskpad()->FReplacesDefaultView(); ::SendDlgItemMessage(HWnd(), IDC_Style_HideNormalTab, BM_SETCHECK, (WPARAM) bReplacesDefaultView ? BST_CHECKED : BST_UNCHECKED, 0); /* * update the preview and description */ UpdateControls (); return 0; } LRESULT CTaskpadStyleBase::OnSettingChanged( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { UpdateControls (); return 0; } /*+-------------------------------------------------------------------------* * CTaskpadStyleBase::UpdateControls * * *--------------------------------------------------------------------------*/ void CTaskpadStyleBase::UpdateControls () { DWORD dwOrientation; ListSize eSize; GetSettings (dwOrientation, eSize); /* * find the style entry that matches the dialog settings */ int nStyle = FindStyle (dwOrientation, eSize); /* * update the preview bitmap */ m_wndPreview.SetBitmap (s_rgTaskpadStyle[nStyle].GetPreviewBitmap()); /* * update the description text */ SetDlgItemText (HWnd(), IDC_STYLE_DESCRIPTION, s_rgTaskpadStyle[nStyle].GetDescription()); /* * disable the size combo for "Tasks only" taskpads */ m_wndSizeCombo.EnableWindow (!(dwOrientation & TVO_NO_RESULTS)); } /*+-------------------------------------------------------------------------* * CTaskpadStyleBase::FindStyle * * Returns the index of the CTaskpadStyle entry matching the given size * and orientation. *--------------------------------------------------------------------------*/ int CTaskpadStyleBase::FindStyle (DWORD dwOrientation, ListSize eSize) { CTaskpadStyle tps(eSize, dwOrientation); for (int i = 0; i < countof (s_rgTaskpadStyle); i++) { if (s_rgTaskpadStyle[i] == tps) break; } ASSERT (i < countof (s_rgTaskpadStyle)); return (i); } /*+-------------------------------------------------------------------------* * CTaskpadStyleBase::Apply * * *--------------------------------------------------------------------------*/ bool CTaskpadStyleBase::Apply() { DWORD dwOrientation; ListSize eSize; GetSettings (dwOrientation, eSize); // set the "replaces default view" flag. CWindow wnd = HWnd(); bool bReplacesDefaultView = wnd.IsDlgButtonChecked (IDC_Style_HideNormalTab); PConsoleTaskpad()->SetReplacesDefaultView(bReplacesDefaultView); PConsoleTaskpad()->SetOrientation (dwOrientation); PConsoleTaskpad()->SetListSize(eSize); return true; } /*+-------------------------------------------------------------------------* * CTaskpadStyleBase::GetSettings * * Returns the orientation and size presently selected in the dialog. *--------------------------------------------------------------------------*/ void CTaskpadStyleBase::GetSettings (DWORD& dwOrientation, ListSize& eSize) { CWindow wnd = HWnd(); dwOrientation = wnd.IsDlgButtonChecked (IDC_Style_VerticalList) ? TVO_VERTICAL : wnd.IsDlgButtonChecked (IDC_Style_HorizontalList) ? TVO_HORIZONTAL : TVO_NO_RESULTS; if (wnd.IsDlgButtonChecked (IDC_Style_TextDesc)) dwOrientation |= TVO_DESCRIPTIONS_AS_TEXT; eSize = (ListSize) m_wndSizeCombo.GetItemData (m_wndSizeCombo.GetCurSel ()); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadStylePage // //############################################################################ //############################################################################ CTaskpadStylePage::CTaskpadStylePage(CTaskpadFrame * pTaskpadFrame) : CTaskpadFramePtr(pTaskpadFrame), BC2(pTaskpadFrame) { } bool CTaskpadStylePage::OnSetActive() { UpdateControls(); return true; } bool CTaskpadStylePage::OnKillActive() { return CTaskpadStyleBase::Apply(); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadStyle // //############################################################################ //############################################################################ const CStr& CTaskpadStyle::GetDescription () const { if (m_strDescription.IsEmpty()) m_strDescription.LoadString(GetStringModule(), m_idsDescription); ASSERT (!m_strDescription.IsEmpty()); return (m_strDescription); } HBITMAP CTaskpadStyle::GetPreviewBitmap() const { if (m_PreviewBitmap == NULL) m_PreviewBitmap = LoadSysColorBitmap (_Module.GetResourceInstance(), m_nPreviewBitmapID); ASSERT (m_PreviewBitmap != NULL); return (m_PreviewBitmap); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadNodetypeBase // //############################################################################ //############################################################################ CTaskpadNodetypeBase::CTaskpadNodetypeBase(CTaskpadFrame *pTaskpadFrame) : CTaskpadFramePtr(pTaskpadFrame) { } LRESULT CTaskpadNodetypeBase::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { m_bApplytoNodetype = !PConsoleTaskpad()->IsNodeSpecific(); m_bSetDefaultForNodetype = true; //$CHANGE CDefaultTaskpadList *pDefaultTaskpadList = PTaskpadFrame()->PScopeTree()->GetDefaultTaskpadList(); ASSERT(pDefaultTaskpadList != NULL); CDefaultTaskpadList::iterator iter = pDefaultTaskpadList->find(PConsoleTaskpad()->GetNodeType()); if(iter != pDefaultTaskpadList->end()) { if(iter->second == PConsoleTaskpad()->GetID()) { m_bSetDefaultForNodetype = true; } } ::SendDlgItemMessage(HWnd(), IDC_UseForSimilarNodes, BM_SETCHECK, (WPARAM) m_bApplytoNodetype ? BST_CHECKED : BST_UNCHECKED, 0); ::SendDlgItemMessage(HWnd(), IDC_DontUseForSimilarNodes,BM_SETCHECK, (WPARAM) (!m_bApplytoNodetype) ? BST_CHECKED : BST_UNCHECKED, 0); ::SendDlgItemMessage(HWnd(), IDC_SetDefaultForNodetype, BM_SETCHECK, (WPARAM) m_bSetDefaultForNodetype ? BST_CHECKED : BST_UNCHECKED, 0); EnableControls(); return 0; } LRESULT CTaskpadNodetypeBase::OnUseForNodetype(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { m_bApplytoNodetype = true; EnableControls(); return 0; } LRESULT CTaskpadNodetypeBase::OnDontUseForNodetype(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { m_bApplytoNodetype = false; EnableControls(); return 0; } LRESULT CTaskpadNodetypeBase::OnSetAsDefault (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { m_bSetDefaultForNodetype = !m_bSetDefaultForNodetype; EnableControls(); return 0; } void CTaskpadNodetypeBase::EnableControls() { // enable the set as default button only if the taskpad applies to all nodes of the same type. WTL::CButton wndSetAsDefault = ::GetDlgItem(HWnd(), IDC_SetDefaultForNodetype); wndSetAsDefault.EnableWindow (m_bApplytoNodetype); /* * check it if it's disabled */ if (!m_bApplytoNodetype) wndSetAsDefault.SetCheck (BST_CHECKED); } bool CTaskpadNodetypeBase::OnApply() { PConsoleTaskpad()->SetNodeSpecific(!m_bApplytoNodetype); if(!m_bApplytoNodetype) // retarget the taskpad to this node only. { CNode *pNode = PTaskpadFrame()->PNodeTarget(); ASSERT(pNode != NULL); PConsoleTaskpad()->Retarget(pNode); } CDefaultTaskpadList *pDefaultList = PTaskpadFrame()->PScopeTree()->GetDefaultTaskpadList(); ASSERT(pDefaultList != NULL); CDefaultTaskpadList::iterator iter = pDefaultList->find(PConsoleTaskpad()->GetNodeType()); if(m_bApplytoNodetype && m_bSetDefaultForNodetype) { (*pDefaultList)[PConsoleTaskpad()->GetNodeType()] = PConsoleTaskpad()->GetID(); } else { if(iter != pDefaultList->end()) { if(iter->second==PConsoleTaskpad()->GetID()) pDefaultList->erase(iter); } } return true; } //############################################################################ //############################################################################ // // Implementation of class CTaskpadNodetypePage // //############################################################################ //############################################################################ CTaskpadNodetypePage::CTaskpadNodetypePage(CTaskpadFrame *pTaskpadFrame) : CTaskpadNodetypeBase(pTaskpadFrame), CTaskpadFramePtr(pTaskpadFrame) { } //############################################################################ //############################################################################ // // Implementation of class CTaskpadGeneralPage // //############################################################################ //############################################################################ /* CTaskpadGeneralPage::CTaskpadGeneralPage * * PURPOSE: Constructor * * PARAMETERS: None * */ CTaskpadGeneralPage::CTaskpadGeneralPage(CTaskpadFrame * pTaskpadFrame): BC(), CTaskpadFramePtr(pTaskpadFrame), BC2(pTaskpadFrame) { } /*+-------------------------------------------------------------------------* * CTaskpadGeneralPage::OnInitDialog * * PURPOSE: * * PARAMETERS: * INT uMsg: * WPARAM wParam: * LPARAM lParam: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ LRESULT CTaskpadGeneralPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { m_strName. Initialize (this, IDC_TASKPAD_TITLE, -1, PConsoleTaskpad()->GetName().data()); m_strDescription.Initialize (this, IDC_TASKPAD_DESCRIPTION,-1, PConsoleTaskpad()->GetDescription().data()); return 0; } /*+-------------------------------------------------------------------------* * CTaskpadGeneralPage::OnOptions * * *--------------------------------------------------------------------------*/ LRESULT CTaskpadGeneralPage::OnOptions( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { CTaskpadOptionsDlg dlg (PTaskpadFrame()); if (dlg.DoModal() == IDOK) { /* * apply the changes to the taskpad */ CConsoleTaskpad* pTaskpad = PConsoleTaskpad(); //pTaskpad->SetContextFormat (dlg.m_ctxt); UpdateControls(); } return 0; } /*+-------------------------------------------------------------------------* * CTaskpadGeneralPage::OnApply * * PURPOSE: * * PARAMETERS: * * RETURNS: * BOOL /*+-------------------------------------------------------------------------*/ bool CTaskpadGeneralPage::OnApply() { tstring strName = MMC::GetWindowText (m_strName); if (strName.empty()) { CStr strTitle; strTitle.LoadString(GetStringModule(), IDS_TASKPAD_NAME_REQUIRED_ERROR); MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION); return false; } tstring strDescription = MMC::GetWindowText (m_strDescription); CConsoleTaskpad* pTaskpad = PConsoleTaskpad(); pTaskpad->SetName (strName); pTaskpad->SetDescription (strDescription); return BC2::Apply(); } //############################################################################ //############################################################################ // // Implementation of class CTaskpadOptionsDlg // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CTaskpadOptionsDlg::CTaskpadOptionsDlg * * PURPOSE: * * PARAMETERS: * TaskpadFrame * pTaskpadFrame: * CConsoleTask & rConsoleTask: * * RETURNS: * /*+-------------------------------------------------------------------------*/ CTaskpadOptionsDlg::CTaskpadOptionsDlg (CTaskpadFrame* pTaskpadFrame) : CTaskpadFramePtr (pTaskpadFrame), // BC3 (pTaskpadFrame), BC4 (pTaskpadFrame) { } /*+-------------------------------------------------------------------------* * CTaskpadOptionsDlg::~CTaskpadOptionsDlg * * PURPOSE: * * PARAMETERS: * * RETURNS: * /*+-------------------------------------------------------------------------*/ CTaskpadOptionsDlg::~CTaskpadOptionsDlg() { } /*+-------------------------------------------------------------------------* * CTaskpadOptionsDlg::OnInitDialog * * PURPOSE: * * PARAMETERS: * INT uMsg: * WPARAM wParam: * LPARAM lParam: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ LRESULT CTaskpadOptionsDlg::OnInitDialog (HWND hwndFocus, LPARAM lParam, BOOL& bHandled ) { CConsoleTaskpad * pTaskpad = PConsoleTaskpad(); EnableControls(); return (true); } /*+-------------------------------------------------------------------------* * CTaskpadOptionsDlg::EnableControls * * *--------------------------------------------------------------------------*/ void CTaskpadOptionsDlg::EnableControls() { /* bool fUseFixedFormat = IsDlgButtonChecked (IDC_UseFixedFormat); bool fUseCustomFormat = IsDlgButtonChecked (IDC_UseCustomContextFormat); /* * If neither fixed or custom format, then we're displaying no * caption. If there's no caption, there's no room for a change * button, so we'll disable all of the retargetting-related controls * if (!fUseFixedFormat && !fUseCustomFormat && !m_fSavedWorkingSetting) { ASSERT (IsDlgButtonChecked (IDC_NoCaption)); m_fSavedWorkingSetting = true; } else if (m_fSavedWorkingSetting) { m_fSavedWorkingSetting = false; } //BC3::EnableControls(); */ } /*+-------------------------------------------------------------------------* * CTaskpadOptionsDlg::OnApply * * *--------------------------------------------------------------------------*/ bool CTaskpadOptionsDlg::OnApply() { //if(!BC3::OnApply()) // return false; if(!BC4::OnApply()) return false; return (true); } //############################################################################ //############################################################################ // // Implementation of class CDialogBase // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CDialogBase::CDialogBase * * *--------------------------------------------------------------------------*/ template CDialogBase::CDialogBase (bool fAutoCenter /* =false */) : m_fAutoCenter (fAutoCenter) { } /*+-------------------------------------------------------------------------* * CDialogBase::OnInitDialog * * WM_INITDIALOG handler for CDialogBase. *--------------------------------------------------------------------------*/ template LRESULT CDialogBase::OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { if (!m_fAutoCenter) PreventMFCAutoCenter (this); return (OnInitDialog ((HWND) wParam, lParam, bHandled)); } template LRESULT CDialogBase::OnInitDialog (HWND hwndFocus, LPARAM lParam, BOOL& bHandled) { /* * we didn't change the default focus */ return (true); } /*+-------------------------------------------------------------------------* * CDialogBase::OnOK * * IDOK handler for CDialogBase. *--------------------------------------------------------------------------*/ template LRESULT CDialogBase::OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { if (OnApply ()) EndDialog (IDOK); return (0); } /*+-------------------------------------------------------------------------* * CDialogBase::OnCancel * * IDCANCEL handler for CDialogBase. *--------------------------------------------------------------------------*/ template LRESULT CDialogBase::OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { EndDialog (IDCANCEL); return (0); } /*+-------------------------------------------------------------------------* * CDialogBase::EnableDlgItem * * *--------------------------------------------------------------------------*/ template BOOL CDialogBase::EnableDlgItem (int idControl, bool fEnable) { return (::EnableWindow (GetDlgItem (idControl), fEnable)); } /*+-------------------------------------------------------------------------* * CDialogBase::CheckDlgItem * * *--------------------------------------------------------------------------*/ template void CDialogBase::CheckDlgItem (int idControl, int nCheck) { MMC_ATL::CButton btn = GetDlgItem (idControl); btn.SetCheck (nCheck); } /*+-------------------------------------------------------------------------* * CDialogBase::GetDlgItemText * * Returns the text for a given control in the form of a tstring *--------------------------------------------------------------------------*/ template tstring CDialogBase::GetDlgItemText (int idControl) { return (MMC::GetWindowText (GetDlgItem (idControl))); } /*+-------------------------------------------------------------------------* * CDialogBase::SetDlgItemText * * Sets the text for a given control in the form of a tstring *--------------------------------------------------------------------------*/ template BOOL CDialogBase::SetDlgItemText (int idControl, tstring str) { return (BaseClass::SetDlgItemText (idControl, str.data())); } //############################################################################ //############################################################################ // // Implementation of class CTaskPropertiesBase // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::CTaskPropertiesBase * * *--------------------------------------------------------------------------*/ CTaskPropertiesBase::CTaskPropertiesBase ( CTaskpadFrame* pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : CTaskpadFramePtr(pTaskpadFrame), m_pTask (&consoleTask), m_fNew (fNew) { } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::ScOnVisitContextMenu * * *--------------------------------------------------------------------------*/ // forward declaration of function void RemoveAccelerators(tstring &str); SC CTaskPropertiesBase::ScOnVisitContextMenu(CMenuItem &menuItem) { DECLARE_SC(sc, TEXT("CTaskPropertiesBase::ScOnVisitContextMenu")); WTL::CListBox& wndListBox = GetListBox(); IntToTaskMap& map = GetTaskMap(); // set up a CConsoleTask object CConsoleTask task; tstring strName = menuItem.GetMenuItemName(); RemoveAccelerators(strName); // friendly looking name. task.SetName( strName); task.SetDescription(menuItem.GetMenuItemStatusBarText()); task.SetCommand( menuItem.GetLanguageIndependentPath()); int i = wndListBox.AddString (menuItem.GetPath()); // the "ui-friendly" command path. map[i] = task; // if this task matches the current task, select it in the listbox if (ConsoleTask() == menuItem) wndListBox.SetCurSel (i); return sc; } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::OnCommandListSelChange * * LBN_SELCHANGE handler for CTaskPropertiesBase /*+-------------------------------------------------------------------------*/ LRESULT CTaskPropertiesBase::OnCommandListSelChange(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { int iSelected = WTL::CListBox(hWndCtl).GetCurSel(); IntToTaskMap& TaskMap = GetTaskMap(); CConsoleTask& task = TaskMap[iSelected]; ConsoleTask().SetName(task.GetName()); ConsoleTask().SetDescription(task.GetDescription()); ConsoleTask().SetCommand(task.GetCommand()); return (0); } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::OnApply * * *--------------------------------------------------------------------------* bool CTaskPropertiesBase::OnApply () { // code after this point is executed only for new tasks. if ((IsScopeTask() || IsResultTask()) && (ConsoleTask().GetCommand().length() == 0)) { CStr strError; strError.LoadString(GetStringModule(), IDS_INVALID_COMMAND); MessageBox (strError, NULL, MB_OK | MB_ICONEXCLAMATION); return (false); } return (true); } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::GetDlgItemText * * Returns the text for a given control in the form of a tstring *-------------------------------------------------------------------------- tstring CTaskPropertiesBase::GetDlgItemText (int idControl) { return (MMC::GetWindowText (GetDlgItem (idControl))); } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::SetDlgItemText * * Sets the text for a given control in the form of a tstring *-------------------------------------------------------------------------- BOOL CTaskPropertiesBase::SetDlgItemText (int idControl, tstring str) { return (BaseClass::SetDlgItemText (idControl, str.data())); } */ //############################################################################ //############################################################################ // // class CCommandLineArgumentsMenu // //############################################################################ //############################################################################ class CCommandLineArgumentsMenu { enum { TARGETNODE_ITEMS_BASE = 100, LISTVIEW_ITEMS_BASE = 1000 }; typedef WTL::CMenu CMenu; public: CCommandLineArgumentsMenu(HWND hWndParent, int nIDButton, HWND hWndListCtrl); bool Popup(); CStr GetResultString() {return m_strResult;} private: void AddMenuItemsForTargetNode(CMenu &menu); void AddMenuItemsForListView(CMenu &menu); private: HWND m_hWndParent; HWND m_hWndListCtrl; int m_nIDButton; CStr m_strResult; // the string which was created as a result of the selection }; CCommandLineArgumentsMenu::CCommandLineArgumentsMenu(HWND hWndParent, int nIDButton, HWND hWndListCtrl) : m_hWndParent(hWndParent), m_nIDButton(nIDButton), m_hWndListCtrl(hWndListCtrl) { } void CCommandLineArgumentsMenu::AddMenuItemsForTargetNode(CMenu &menu) { bool fSucceeded = menu.CreatePopupMenu(); ASSERT(fSucceeded); CStr strTargetNodeName; strTargetNodeName.LoadString(GetStringModule(), IDS_TargetNodeName); fSucceeded = menu.AppendMenu(MF_STRING, TARGETNODE_ITEMS_BASE, (LPCTSTR)strTargetNodeName); ASSERT(fSucceeded); CStr strTargetNodeParentName; strTargetNodeParentName.LoadString(GetStringModule(), IDS_TargetNodeParentName); fSucceeded = menu.AppendMenu(MF_STRING, TARGETNODE_ITEMS_BASE + 1, (LPCTSTR)strTargetNodeParentName); ASSERT(fSucceeded); fSucceeded = menu.AppendMenu(MF_SEPARATOR, 0); ASSERT(fSucceeded); } void CCommandLineArgumentsMenu::AddMenuItemsForListView(CMenu &menu) { ASSERT(m_hWndListCtrl); WTL::CHeaderCtrl headerCtrl(ListView_GetHeader(m_hWndListCtrl)); int cItems = headerCtrl.GetItemCount(); for (int i=0; i= TARGETNODE_ITEMS_BASE && iResp < LISTVIEW_ITEMS_BASE) { TCHAR szBuffer[10]; _itot(iResp-TARGETNODE_ITEMS_BASE, szBuffer, 10); m_strResult.Format(TEXT("$NAME<%s>"), szBuffer); } else // is a list view menu item. The return value is of the form $COL { TCHAR szBuffer[10]; _itot(iResp-LISTVIEW_ITEMS_BASE, szBuffer, 10); m_strResult.Format(TEXT("$COL<%s>"), szBuffer); } return (iResp != 0); } //############################################################################ //############################################################################ // // Implementation of class CTasksListDialog // //############################################################################ //############################################################################ /* CTasksListDialog::CTasksListDialog * * PURPOSE: Constructor * * PARAMETERS: None */ template CTasksListDialog::CTasksListDialog(CTaskpadFrame* pTaskpadFrame, bool bNewTaskOnInit, bool bDisplayProperties) : BC(), m_bNewTaskOnInit(bNewTaskOnInit), m_pTaskpadFrame(pTaskpadFrame), m_bDisplayProperties(bDisplayProperties) { } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnInitDialog * * PURPOSE: * * PARAMETERS: * INT uMsg: * WPARAM wParam: * LPARAM lParam: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { m_buttonNewTask.Attach(::GetDlgItem( m_hWnd, IDC_NEW_TASK_BT)); m_buttonRemoveTask.Attach(::GetDlgItem( m_hWnd, IDC_REMOVE_TASK)); m_buttonModifyTask.Attach(::GetDlgItem( m_hWnd, IDC_MODIFY)); m_buttonMoveUp.Attach(::GetDlgItem( m_hWnd, IDC_MOVE_UP)); m_buttonMoveDown.Attach(::GetDlgItem( m_hWnd, IDC_MOVE_DOWN)); m_listboxTasks.Attach(::GetDlgItem( m_hWnd, IDC_LIST_TASKS)); m_listboxTasks.SetExtendedListViewStyle(LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT); // set up the image list WTL::CImageList imageList; // the destructor will not call a destroy. This is by design - the listbox will do the destroy. imageList.Create (16, 16, ILC_COLOR , 4 /*the minimum number of images*/, 10); m_listboxTasks.SetImageList((HIMAGELIST) imageList, LVSIL_SMALL); // insert the list columns LV_COLUMN lvc; lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; CStr temp; temp.LoadString(GetStringModule(), IDS_COLUMN_TASK); lvc.pszText = const_cast((LPCTSTR)temp); lvc.cx = 100; lvc.iSubItem = 0; int iCol = m_listboxTasks.InsertColumn(0, &lvc); ASSERT(iCol == 0); temp.LoadString(GetStringModule(), IDS_COLUMN_TOOLTIP); lvc.pszText = const_cast((LPCTSTR)temp); lvc.cx = 140; lvc.iSubItem = 1; iCol = m_listboxTasks.InsertColumn(1, &lvc); ASSERT(iCol == 1); // insert all the items UpdateTaskListbox(PConsoleTaskpad()->BeginTask()); if(FNewTaskOnInit()) // simulate the "New Task" button being clicked. { m_buttonNewTask.PostMessage (BM_CLICK); } return 0; } template LRESULT CTasksListDialog::OnCustomDraw( int id, LPNMHDR pnmh, BOOL& bHandled ) { NMLVCUSTOMDRAW * pnmlv = (NMLVCUSTOMDRAW *) pnmh; // the custom draw structure NMCUSTOMDRAW & nmcd = pnmlv->nmcd; int nItem = nmcd.dwItemSpec; switch(nmcd.dwDrawStage & ~CDDS_SUBITEM) { case CDDS_PREPAINT: // the initial notification return CDRF_NOTIFYITEMDRAW; // we want to know about each item's paint. case CDDS_ITEMPREPAINT: return DrawItem(&nmcd); default: return 0; } } template LRESULT CTasksListDialog::DrawItem(NMCUSTOMDRAW *pnmcd) { NMLVCUSTOMDRAW * pnmlv = (NMLVCUSTOMDRAW *) pnmcd; HDC &hdc = pnmcd->hdc; int nItem = pnmcd->dwItemSpec; TaskIter itTask = PConsoleTaskpad()->BeginTask(); std::advance (itTask, nItem); bool bWindowHasFocus = (GetFocus() == (HWND) m_listboxTasks); bool bFocused = pnmcd->uItemState & CDIS_FOCUS; bool bHot = pnmcd->uItemState & CDIS_HOT; bool bShowSelAlways = m_listboxTasks.GetStyle() & LVS_SHOWSELALWAYS; /* * NOTE: There's a bug in the list view control that will * set CDIS_SELECTED for *all* items (not just selected items) * if LVS_SHOWSELALWAYS is specified. Interrogate the item * directly to get the right setting. */ // bool bSelected = pnmcd->uItemState & CDIS_SELECTED; bool bSelected = m_listboxTasks.GetItemState (nItem, LVIS_SELECTED); #if DBG // bFocused should always be false if the window doesn't have the focus if (!bWindowHasFocus) ASSERT (!bFocused); #endif RECT rectBounds; m_listboxTasks.GetItemRect (nItem, &rectBounds, LVIR_BOUNDS); // figure out colors int nTextColor, nBackColor; if (bSelected && bWindowHasFocus) { nTextColor = COLOR_HIGHLIGHTTEXT; nBackColor = COLOR_HIGHLIGHT; } else if (bSelected && bShowSelAlways) { nTextColor = COLOR_BTNTEXT; nBackColor = COLOR_BTNFACE; } else { nTextColor = COLOR_WINDOWTEXT; nBackColor = COLOR_WINDOW; } // empty (or fill) the region FillRect (hdc, &rectBounds, ::GetSysColorBrush (nBackColor)); // draw the text. COLORREF nTextColorOld = SetTextColor (hdc, ::GetSysColor (nTextColor)); COLORREF nBackColorOld = SetBkColor (hdc, ::GetSysColor (nBackColor)); RECT rectIcon; m_listboxTasks.GetItemRect(nItem, &rectIcon, LVIR_ICON); /* * Preserve icon shape when BitBlitting it to a * mirrored DC. */ DWORD dwLayout=0L; if ((dwLayout=GetLayout(hdc)) & LAYOUT_RTL) { SetLayout(hdc, dwLayout|LAYOUT_BITMAPORIENTATIONPRESERVED); } itTask->Draw(hdc, &rectIcon, true /*bSmall*/); /* * Restore the DC to its previous layout state. */ if (dwLayout & LAYOUT_RTL) { SetLayout(hdc, dwLayout); } RECT rectLabel; UINT uFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER | DT_WORD_ELLIPSIS; m_listboxTasks.GetItemRect(nItem,&rectLabel, LVIR_LABEL); // get the label rectangle DrawText(hdc, itTask->GetName().data(),-1,&rectLabel, uFormat); RECT rectDescr; m_listboxTasks.GetSubItemRect(nItem, 1 /*descr column*/, LVIR_LABEL, &rectDescr); DrawText(hdc, itTask->GetDescription().data(),-1,&rectDescr, uFormat); SetTextColor(hdc, nTextColorOld); SetBkColor (hdc, nBackColorOld); if (bFocused) ::DrawFocusRect(hdc, &rectBounds); return CDRF_SKIPDEFAULT; // we've drawn the whole item ourselves } template void CTasksListDialog::OnTaskProperties() { if(!m_bDisplayProperties) // don't display any properties if not needed. return; int iSelected = GetCurSel(); if(iSelected == LB_ERR) // defensive return; TaskIter itTask = MapTaskIterators()[iSelected]; CTaskPropertySheet dlg(NULL, PTaskpadFrame(), *itTask, false); if (dlg.DoModal() == IDOK) { *itTask = dlg.ConsoleTask(); UpdateTaskListbox (itTask); } } template int CTasksListDialog::GetCurSel() { int i = (int)PListBoxTasks()->SendMessage(LVM_GETNEXTITEM, -1, MAKELPARAM(LVNI_ALL | LVNI_FOCUSED, 0)); return (i==-1) ? LB_ERR : i; } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnTaskChanged * * PURPOSE: * * PARAMETERS: * ORD wNotifyCode: * WORD wID: * HWND hWndCtl: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnTaskChanged( int id, LPNMHDR pnmh, BOOL& bHandled ) { NMLISTVIEW *pnlv = (LPNMLISTVIEW) pnmh; EnableButtons(); return 0; } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnNewTask * * PURPOSE: * * PARAMETERS: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnNewTask() { bool fRestartTaskWizard = true; while(fRestartTaskWizard) { CTaskWizard taskWizard; if (taskWizard.Show(m_hWnd, PTaskpadFrame(), true, &fRestartTaskWizard)==S_OK) { CConsoleTaskpad::TaskIter itTask; CConsoleTaskpad * pTaskpad = PConsoleTaskpad(); // get the iterator of the selected task. The new task will be inserted just after this. int iSelected = GetCurSel(); if (iSelected == LB_ERR) itTask = pTaskpad->BeginTask(); else { /* * InsertTask inserts before the given iterator. We need to * bump itTask so it gets inserted after the selected task. */ itTask = MapTaskIterators()[iSelected]; ASSERT (itTask != pTaskpad->EndTask()); ++itTask; } UpdateTaskListbox (pTaskpad->InsertTask (itTask, taskWizard.ConsoleTask())); } else break; } return 0; } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnRemoveTask * * PURPOSE: * * PARAMETERS: * ORD wNotifyCode: * WORD wID: * HWND hWndCtl: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnRemoveTask( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iSelected = GetCurSel(); if(iSelected == LB_ERR) return 0; // get the current task TaskIter taskIterator = MapTaskIterators()[iSelected]; UpdateTaskListbox(PConsoleTaskpad()->EraseTask(taskIterator)); return 0; } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnMoveUp * * PURPOSE: * * PARAMETERS: * ORD wNotifyCode: * WORD wID: * HWND hWndCtl: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnMoveUp(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iSelected = GetCurSel(); if(iSelected == LB_ERR) return 0; // get the current task TaskIter itTask = MapTaskIterators()[iSelected]; // defensive coding if(itTask==PConsoleTaskpad()->BeginTask()) return 0; // point to the previous task TaskIter itPreviousTask = itTask; --itPreviousTask; // swap the tasks std::iter_swap (itTask, itPreviousTask); UpdateTaskListbox(itPreviousTask); return 0; } /*+-------------------------------------------------------------------------* * CTasksListDialog::OnMoveDown * * PURPOSE: * * PARAMETERS: * ORD wNotifyCode: * WORD wID: * HWND hWndCtl: * BOOL& bHandled: * * RETURNS: * LRESULT /*+-------------------------------------------------------------------------*/ template LRESULT CTasksListDialog::OnMoveDown( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { int iSelected = GetCurSel(); if(iSelected == LB_ERR) return 0; // get the current task TaskIter itTask = MapTaskIterators()[iSelected]; ASSERT (itTask != PConsoleTaskpad()->EndTask()); // point to the next task TaskIter itNextTask = itTask; ++itNextTask; // defensive coding if(itNextTask==PConsoleTaskpad()->EndTask()) return 0; // swap the tasks std::iter_swap (itTask, itNextTask); UpdateTaskListbox(itNextTask); return 0; } /*+-------------------------------------------------------------------------* * CTasksListDialog::UpdateTaskListbox * * PURPOSE: * * PARAMETERS: * TaskIter itSelectedTask: * * RETURNS: * void /*+-------------------------------------------------------------------------*/ template void CTasksListDialog::UpdateTaskListbox(TaskIter itSelectedTask) { USES_CONVERSION; TaskIter itTask; int iSelect = 0; int iInsert = 0; // clear the listbox and the iterator map PListBoxTasks()->DeleteAllItems(); MapTaskIterators().clear(); for (iInsert = 0, itTask = PConsoleTaskpad()->BeginTask(); itTask != PConsoleTaskpad()->EndTask(); ++itTask, ++iInsert) { LV_ITEM LVItem; LVItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; LVItem.iItem = iInsert; LVItem.iImage = 0; LVItem.iSubItem = 0; LVItem.pszText = const_cast(itTask->GetName().data()); int i = PListBoxTasks()->InsertItem(&LVItem); ASSERT(i==iInsert); // LV_Item for setting tooltim column LV_ITEM LVItem2; LVItem2.iItem = iInsert; LVItem2.mask = LVIF_TEXT; LVItem2.iSubItem = 1; LVItem2.pszText = const_cast(itTask->GetDescription().data()); BOOL bStat = PListBoxTasks()->SetItem(&LVItem2); ASSERT(bStat); MapTaskIterators()[i] = itTask; if(itTask == itSelectedTask) iSelect = i; } PListBoxTasks()->SetItemState(iSelect, LVIS_FOCUSED| LVIS_SELECTED , LVIS_FOCUSED| LVIS_SELECTED ); PListBoxTasks()->EnsureVisible(iSelect, false /*fPartialOK*/); EnableButtons(); } /*+-------------------------------------------------------------------------* * CTasksListDialog::EnableButtons * * PURPOSE: * * PARAMETERS: * * RETURNS: * void /*+-------------------------------------------------------------------------*/ template void CTasksListDialog::EnableButtons() { bool bEnableDelete = true; bool bEnableMoveUp = true; bool bEnableMoveDown = true; bool bEnableModify = true; int iSelected = GetCurSel(); if(iSelected == LB_ERR) { bEnableDelete = false; bEnableMoveUp = false; bEnableMoveDown = false; bEnableModify = false; } else { TaskIter taskIterator = MapTaskIterators()[iSelected]; TaskIter taskIteratorNext = taskIterator; taskIteratorNext++; if(taskIterator==PConsoleTaskpad()->BeginTask()) bEnableMoveUp = false; if(taskIteratorNext==PConsoleTaskpad()->EndTask()) bEnableMoveDown = false; } EnableButtonAndCorrectFocus( m_buttonRemoveTask, bEnableDelete ); EnableButtonAndCorrectFocus( m_buttonModifyTask, bEnableModify ); EnableButtonAndCorrectFocus( m_buttonMoveUp, bEnableMoveUp ); EnableButtonAndCorrectFocus( m_buttonMoveDown, bEnableMoveDown ); } /***************************************************************************\ * * METHOD: CTasksListDialog::EnableButtonAndCorrectFocus * * PURPOSE: Enables/disables button. Moves focus to OK, if it's on the button * being disabled * * PARAMETERS: * WTL::CButton& button * BOOL bEnable * * RETURNS: * void * \***************************************************************************/ template void CTasksListDialog::EnableButtonAndCorrectFocus( WTL::CButton& button, BOOL bEnable ) { // if the focus belongs to the window being disabled, // set it to the OK button if ( ( !bEnable ) && ( ::GetFocus() == button ) ) { // need to do some funny stuff here. see KB article Q67655 for details // Reset the current default push button to a regular button. button.SendMessage( BM_SETSTYLE, BS_PUSHBUTTON, (LONG)TRUE ); // set focus to IDOK ::SetFocus( ::GetDlgItem( GetParent(), IDOK ) ); // inform dialog about the new default button ::SendMessage( GetParent(), DM_SETDEFID, IDOK, 0 ); } button.EnableWindow( bEnable ); } //############################################################################ //############################################################################ // // Implementation of class CContextMenuVisitor // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CContextMenuVisitor::ScTraverseContextMenu * * PURPOSE: Creates and traverses the context menu tree for the selected item, * whether scope or result. * * PARAMETERS: * Node * pNodeTarget: The scope item whose menu is traversed (or NULL) * CScopeTree * pCScopeTree: Points to a CScopeTree * BOOL fScopeItem: TRUE if the selected item is a result item, else FALSE. * CNode * pNodeScope: The scope item which has the focus. * LPARAM resultItemParam: The result item whose menu is traversed (or NULL) * * RETURNS: * SC /*+-------------------------------------------------------------------------*/ SC CContextMenuVisitor::ScTraverseContextMenu(CNode *pNodeTarget, CScopeTree *pCScopeTree, BOOL fScopeItem, CNode *pNodeScope, LPARAM resultItemParam, bool bShowSaveList) { DECLARE_SC(sc, TEXT("CContextMenuVisitor::ScTraverseContextMenu")); sc = ScCheckPointers(pNodeTarget); if(sc) return sc; // set the context info structure. // include flag to force Open verb on scope item menus, so that an open task // will always be available and enabled. CContextMenuInfo contextInfo; contextInfo.Initialize(); contextInfo.m_dwFlags = CMINFO_USE_TEMP_VERB | CMINFO_SHOW_SCOPEITEM_OPEN; // Validate parameters if(fScopeItem) { sc = ScCheckPointers(pNodeScope); if(sc) return sc; // show the view menu items only for the selected scope node // NOTE: cannot compare the pNode's directly - they are from different views. // must compare the MTNodes. if(pNodeTarget->GetMTNode()==pNodeScope->GetMTNode()) contextInfo.m_dwFlags |= CMINFO_SHOW_VIEW_ITEMS; resultItemParam = 0; // we don't need this } else { // Virtual list can have lparam of 0 // (this condition must have braces as long as the assert is the // only conditional statement, to avoid C4390: empty controlled statement) if (!(pNodeTarget && pNodeTarget->GetViewData()->IsVirtualList()) && !IS_SPECIAL_LVDATA (resultItemParam)) { ASSERT(resultItemParam); CResultItem* pri = CResultItem::FromHandle(resultItemParam); if((pri != NULL) && pri->IsScopeItem()) // scope items in the result pane. { fScopeItem = true; pNodeTarget = CNode::FromResultItem (pri); resultItemParam = 0; contextInfo.m_dwFlags |= CMINFO_SCOPEITEM_IN_RES_PANE; } } pNodeScope = NULL; // we don't need this. } CNodeCallback* pNodeCallback = dynamic_cast(pNodeTarget->GetViewData()->GetNodeCallback()); contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT; contextInfo.m_eDataObjectType = fScopeItem ? CCT_SCOPE: CCT_RESULT; contextInfo.m_bBackground = FALSE; contextInfo.m_hSelectedScopeNode = CNode::ToHandle(pNodeScope); contextInfo.m_resultItemParam = resultItemParam; contextInfo.m_bMultiSelect = (resultItemParam == LVDATA_MULTISELECT); contextInfo.m_bScopeAllowed = fScopeItem; if (bShowSaveList) contextInfo.m_dwFlags |= CMINFO_SHOW_SAVE_LIST; contextInfo.m_hWnd = pNodeTarget->GetViewData()->GetView(); contextInfo.m_pConsoleView = pNodeTarget->GetViewData()->GetConsoleView(); // Create a CContextMenu and initialize it. CContextMenu * pContextMenu = NULL; ContextMenuPtr spContextMenu; sc = CContextMenu::ScCreateInstance(&spContextMenu, &pContextMenu); if(sc) return sc; sc = ScCheckPointers(pContextMenu, spContextMenu.GetInterfacePtr(), E_UNEXPECTED); if(sc) return sc; pContextMenu->ScInitialize(pNodeTarget, pNodeCallback, pCScopeTree, contextInfo); if(sc) return sc; // build and traverse the context menu. sc = pContextMenu->ScBuildContextMenu(); if(sc) return sc; sc = ScTraverseContextMenu(pContextMenu); if(sc) return sc; // the context menu is freed in the destructor of the smart pointer, so we need to set the pointer to NULL. pContextMenu = NULL; return sc; } /*+-------------------------------------------------------------------------* * * CContextMenuVisitor::ScTraverseContextMenu * * PURPOSE: Iterates thru the context menu. * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CContextMenuVisitor::ScTraverseContextMenu(CContextMenu *pContextMenu) { DECLARE_SC(sc, TEXT("CContextMenuVisitor::ScTraverseContextMenu")); sc = ScCheckPointers(pContextMenu, E_UNEXPECTED); if(sc) return sc; CMenuItem *pMenuItem = NULL; int iIndex = 0; do { sc = pContextMenu->ScGetItem(iIndex++, &pMenuItem); if(sc) return sc; if(!pMenuItem) return sc; // all done. bool bVisitItem = false; sc = ScShouldItemBeVisited(pMenuItem, pContextMenu->PContextInfo(), bVisitItem); if(sc) return sc; if(bVisitItem) { // Call the vistor on this item. SC sc = ScOnVisitContextMenu(*pMenuItem); if(sc == SC(S_FALSE)) // S_FALSE is the code to not continue traversal. { return sc; } } } while(pMenuItem != NULL); return sc; } /*+-------------------------------------------------------------------------* * * CContextMenuVisitor::ScShouldItemBeVisited * * PURPOSE: Filters items in the traversed tree of menu items to determine whether * the ScOnVisitContextMenu callback should be called. * * PARAMETERS: * CMenuItem * pMenuItem : The menu item to filter * * bool &bVisitItem: [out]: Whether ScOnVisitContextMenu should be called. * * RETURNS: * bool: true if ScOnVisitContextMenu should be called on this item. * *+-------------------------------------------------------------------------*/ SC CContextMenuVisitor::ScShouldItemBeVisited(CMenuItem *pMenuItem, CContextMenuInfo *pContextInfo, /*out*/ bool &bVisitItem) { DECLARE_SC(sc, TEXT("CContextMenuInfo::FVisitItem")); sc = ScCheckPointers(pMenuItem, pContextInfo); if(sc) return sc; bVisitItem = false; if(pMenuItem->IsSpecialSeparator() || pMenuItem->IsSpecialInsertionPoint() || (pMenuItem->GetMenuItemFlags() & MF_SEPARATOR)) { bVisitItem = false; // don't call ScOnVisitContextMenu for this item return sc; } else if(IsSystemOwnerID(pMenuItem->GetMenuItemOwner())) // inserted by the MMC { long nCommandID = pMenuItem->GetCommandID(); // filter out unneeded verbs // also check for scope items in the result pane - these are treated as result items. if( (pContextInfo->m_eDataObjectType == CCT_SCOPE) && (!(pContextInfo->m_dwFlags & CMINFO_SCOPEITEM_IN_RES_PANE)) ) { // scope menu item switch(nCommandID) { case MID_RENAME: case MID_DELETE: case MID_COPY: case MID_CUT: case MID_NEW_TASKPAD_FROM_HERE: // New taskpad from here bVisitItem = false; return sc; break; default: bVisitItem = true; return sc; break; } } else { if(pContextInfo->m_bMultiSelect) // result item, multi select { switch(nCommandID) { case MID_RENAME: case MID_PASTE: case MID_REFRESH: case MID_OPEN: bVisitItem = false; return sc; break; default: bVisitItem = true; return sc; break; } } else // result item, single select { switch(nCommandID) { case MID_OPEN: bVisitItem = false; return sc; break; default: bVisitItem = true; return sc; break; } } } } else { bVisitItem = true; return sc; } } //############################################################################ //############################################################################ // // Implementation of class CBrowserCookieList // //############################################################################ //############################################################################ CBrowserCookieList::~CBrowserCookieList() { iterator iter; for (iter = begin(); iter != end(); iter++) { iter->DeleteNode(); } } //############################################################################ //############################################################################ // // Implementation of class CMTBrowserCtrl // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::CMTBrowserCtrl * * PURPOSE: * * PARAMETERS: * WND hWnd: * CScopeTree * pScopeTree: * * RETURNS: * /*+-------------------------------------------------------------------------*/ CMTBrowserCtrl::CMTBrowserCtrl() : m_pScopeTree(NULL) { } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::~CMTBrowserCtrl * * PURPOSE: * * PARAMETERS: * * RETURNS: * /*+-------------------------------------------------------------------------*/ CMTBrowserCtrl::~CMTBrowserCtrl() { CBrowserCookieList::iterator iter; for (iter = PBrowserCookieList()->begin(); iter != PBrowserCookieList()->end(); iter++) iter->DeleteNode(); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::Initialize * * PURPOSE: * * PARAMETERS: * * RETURNS: * void /*+-------------------------------------------------------------------------*/ void CMTBrowserCtrl::Initialize(const InitData& init) { ASSERT (::IsWindow (init.hwnd)); ASSERT (init.pScopeTree != NULL); SubclassWindow (init.hwnd); m_pScopeTree = init.pScopeTree; /* * Copy the list of nodes to exclude. This list is likely to be very * small. If we find that it can be large, we may want to sort it * so that we can later do a binary search instead of a linear search. */ m_vpmtnExclude = init.vpmtnExclude; #if OptimizeExcludeList std::sort (m_vpmtnExclude.begin(), m_vpmtnExclude.end()); #endif /* * set the image list of the tree view control */ HIMAGELIST hImageList = m_pScopeTree->GetImageList (); SetImageList (hImageList, TVSIL_NORMAL); /* * if no root was provided, default to the console root */ CMTNode* pmtnRoot = init.pmtnRoot; if (pmtnRoot == NULL) pmtnRoot = m_pScopeTree->GetRoot(); ASSERT (pmtnRoot != NULL); /* * add the root item */ CBrowserCookie browserCookie (pmtnRoot, NULL); HTREEITEM htiRoot = InsertItem (browserCookie, TVI_ROOT, TVI_FIRST); /* * if no selection node was provided, default to the root */ CMTNode* pmtnSelect = init.pmtnSelect; if (pmtnSelect == NULL) pmtnSelect = pmtnRoot; ASSERT (pmtnSelect != NULL); /* * select the specified node */ SelectNode (pmtnSelect); /* * insure that the root item is expanded */ Expand (htiRoot, TVE_EXPAND); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::InsertItem * * PURPOSE: * * PARAMETERS: * MTNode * pMTNode: * HTREEITEM hParent: * HTREEITEM hInsertAfter: * * RETURNS: * HTREEITEM /*+-------------------------------------------------------------------------*/ HTREEITEM CMTBrowserCtrl::InsertItem( const CBrowserCookie& browserCookie, HTREEITEM hParent, HTREEITEM hInsertAfter) { /* * don't insert the item if it is in the exclude list */ if (IsMTNodeExcluded (browserCookie.PMTNode())) return (NULL); UINT nMask = TVIF_PARAM | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT | TVIF_CHILDREN; PBrowserCookieList()->push_back(browserCookie); CBrowserCookie *pBrowserCookie = & (PBrowserCookieList()->back()); CMTNode * pMTNode = pBrowserCookie->PMTNode(); tstring strName = pMTNode->GetDisplayName(); TV_INSERTSTRUCT tvis; tvis.hParent = hParent; tvis.hInsertAfter = hInsertAfter; tvis.item.mask = nMask; tvis.item.pszText = const_cast(strName.data()); tvis.item.iImage = pMTNode->GetImage(); tvis.item.iSelectedImage = pMTNode->GetOpenImage(); tvis.item.state = 0; tvis.item.stateMask = 0; tvis.item.lParam = reinterpret_cast(pBrowserCookie); tvis.item.cChildren = 1; return BC::InsertItem(&tvis); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::IsMTNodeExcluded * * Returns true if the given MTNode is in the exclude list. *--------------------------------------------------------------------------*/ bool CMTBrowserCtrl::IsMTNodeExcluded (CMTNode* pmtn) const { CMTNodeCollection::const_iterator itEnd = m_vpmtnExclude.end(); CMTNodeCollection::const_iterator itFound = #if OptimizeExcludeList std::lower_bound (m_vpmtnExclude.begin(), itEnd, pmtn); #else std::find (m_vpmtnExclude.begin(), itEnd, pmtn); #endif return (itFound != itEnd); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::OnItemExpanding * * Reflected TVN_ITEMEXPANDING handler for CMTBrowserCtrl. The class that * uses a CMTBrowserCtrl must have REFLECT_NOTIFICATIONS as the last entry * in its message map. *--------------------------------------------------------------------------*/ LRESULT CMTBrowserCtrl::OnItemExpanding (int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { /* * this should only handle messages that originated from itself */ ASSERT (pnmh->hwndFrom == m_hWnd); /* * insert the children for this node, if we're expanding */ LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh; if (pnmtv->action == TVE_EXPAND) ExpandItem (pnmtv->itemNew); return (0); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::ExpandItem * * *--------------------------------------------------------------------------*/ #define TVIF_REQUIRED (TVIF_PARAM | TVIF_HANDLE | TVIF_STATE) bool CMTBrowserCtrl::ExpandItem (const TV_ITEM& itemExpand) { /* * make sure all of the fields we require can be trusted */ ASSERT ((itemExpand.mask & TVIF_REQUIRED) == TVIF_REQUIRED); /* * if we've already added children, bail */ if (itemExpand.state & TVIS_EXPANDEDONCE) return (true); CMTNode *pmtnParent = MTNodeFromItem (&itemExpand); ASSERT (pmtnParent != NULL); /* * make sure the master tree node has been expanded */ if (!pmtnParent->WasExpandedAtLeastOnce() && FAILED (pmtnParent->Expand())) return (false); /* * insert tree nodes for all (non-excluded) children of this MTNode */ HTREEITEM hParent = itemExpand.hItem; bool bHasChildren = false; for (CMTNode* pmtn = pmtnParent->GetChild(); pmtn; pmtn = pmtn->GetNext()) { if (InsertItem (CBrowserCookie(pmtn, NULL), hParent, TVI_LAST)) bHasChildren = true; } /* * if the parent has no children - set its * cChildren to zero to get rid of the "+" */ if (!bHasChildren) { TV_ITEM item; item.mask = TVIF_HANDLE | TVIF_CHILDREN; item.hItem = hParent; item.cChildren = 0; SetItem(&item); } return (true); } /*+-------------------------------------------------------------------------* * CBrowserCookie::DeleteNode * * *--------------------------------------------------------------------------*/ void CBrowserCookie::DeleteNode() { delete m_pNode; m_pMTNode = NULL; m_pNode = NULL; } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::FindMTNode * * *--------------------------------------------------------------------------*/ bool CMTBrowserCtrl::SelectNode (CMTNode* pmtnSelect) { HTREEITEM htiRoot = GetRootItem(); CMTNode* pmtnRoot = MTNodeFromItem (htiRoot); CMTNodeCollection vNodes; /* * walk up the tree to find the root */ while (pmtnSelect != NULL) { vNodes.push_back (pmtnSelect); if (pmtnSelect == pmtnRoot) break; pmtnSelect = pmtnSelect->Parent(); } /* * if we didn't find the root, fail */ if (pmtnSelect == NULL) return (false); ASSERT (!vNodes.empty()); ASSERT (vNodes.back() == pmtnRoot); HTREEITEM htiSelect = htiRoot; HTREEITEM htiWatch; /* * expand the tree to the node we want to select */ for (int i = vNodes.size()-1; (i > 0) && (htiSelect != NULL); i--) { if (!Expand (htiSelect, TVE_EXPAND)) break; htiSelect = FindChildItemByMTNode (htiSelect, vNodes[i-1]); } /* * select the node */ SelectItem (htiSelect); return (true); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::GetSelectedMTNode * * Returns the MTNode corresponding to the selected node in the tree *--------------------------------------------------------------------------*/ CMTNode* CMTBrowserCtrl::GetSelectedMTNode () const { CMTBrowserCtrl* pMutableThis = const_cast(this); return (MTNodeFromItem (pMutableThis->GetSelectedItem ())); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::CookieFromItem * * *--------------------------------------------------------------------------*/ CBrowserCookie* CMTBrowserCtrl::CookieFromItem (HTREEITEM hti) const { return (CookieFromLParam (GetItemData (hti))); } CBrowserCookie* CMTBrowserCtrl::CookieFromItem (const TV_ITEM* ptvi) const { return (CookieFromLParam (ptvi->lParam)); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::CookieFromLParam * * *--------------------------------------------------------------------------*/ CBrowserCookie* CMTBrowserCtrl::CookieFromLParam (LPARAM lParam) const { return (reinterpret_cast(lParam)); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::MTNodeFromItem * * *--------------------------------------------------------------------------*/ CMTNode* CMTBrowserCtrl::MTNodeFromItem (HTREEITEM hti) const { return (CookieFromItem(hti)->PMTNode()); } CMTNode* CMTBrowserCtrl::MTNodeFromItem (const TV_ITEM* ptvi) const { return (CookieFromItem(ptvi)->PMTNode()); } /*+-------------------------------------------------------------------------* * CMTBrowserCtrl::FindChildItemByMTNode * * Returns the HTREEITEM for the child node of htiParent which refers * to pmtnToFind, NULL if no match. *--------------------------------------------------------------------------*/ HTREEITEM CMTBrowserCtrl::FindChildItemByMTNode ( HTREEITEM htiParent, const CMTNode* pmtnToFind) { HTREEITEM htiChild; for (htiChild = GetChildItem (htiParent); htiChild != NULL; htiChild = GetNextSiblingItem (htiChild)) { if (MTNodeFromItem (htiChild) == pmtnToFind) break; } return (htiChild); } //############################################################################ //############################################################################ // // Implementation of class CMirrorListView // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * HackDuplicate * * HACK: This is here for theming support. himlSource comes from the conui * list control, which uses comctlv5 imagelists. A v6 list control cannot * use v5 imagelists (images aren't drawn correctly), so we need to create * a v6 imagelist for the v6 list control to use. * * ImageList_Duplicate would do the job for us, but it is not compatible * with v5 imagelists. We'll write to and read from a v5-compatible stream * to duplicate it instead. *--------------------------------------------------------------------------*/ HIMAGELIST HackDuplicate (HIMAGELIST himlSource) { DECLARE_SC (sc, _T("HackDuplicate")); HIMAGELIST himlDuplicate; /* * create a temporary stream for conversion */ IStreamPtr spStream; sc = CreateStreamOnHGlobal (NULL /*alloc for me*/, true /*fDeleteOnRelease*/, &spStream); if (sc) return (NULL); /* * write the source imagelist to the stream in a v5-compatible format */ sc = WriteCompatibleImageList (himlSource, spStream); if (sc) return (NULL); /* * rewind the stream */ LARGE_INTEGER origin = { 0, 0 }; sc = spStream->Seek (origin, STREAM_SEEK_SET, NULL); if (sc) return (NULL); /* * reconstitute the imagelist */ sc = ReadCompatibleImageList (spStream, himlDuplicate); if (sc) return (NULL); return (himlDuplicate); } CMirrorListView::CMirrorListView () : m_fVirtualSource (false) { } void CMirrorListView::AttachSource (HWND hwndList, HWND hwndSourceList) { #ifdef DBG /* * the window we're attaching to should be a list view */ TCHAR szClassName[countof (WC_LISTVIEW)]; ::GetClassName (hwndSourceList, szClassName, countof (szClassName)); ASSERT (lstrcmp (szClassName, WC_LISTVIEW) == 0); #endif SubclassWindow (hwndList); m_wndSourceList = hwndSourceList; m_fVirtualSource = (m_wndSourceList.GetStyle() & LVS_OWNERDATA) != 0; /* * Our listview will always be virtual, so we don't have to duplicate * the data that may already be in the source listview. The list view * control doesn't allow changing the LVS_OWNERDATA style bit, so we * need to make sure that the control we're attaching to already has it */ const DWORD dwForbiddenStyles = LVS_SHAREIMAGELISTS; const DWORD dwRequiredImmutableStyles = LVS_OWNERDATA; const DWORD dwRequiredMutableStyles = 0; const DWORD dwRequiredStyles = dwRequiredImmutableStyles | dwRequiredMutableStyles; ASSERT ((dwForbiddenStyles & dwRequiredStyles) == 0); ASSERT ((dwRequiredImmutableStyles & dwRequiredMutableStyles) == 0); ASSERT ((GetStyle() & dwRequiredImmutableStyles) == dwRequiredImmutableStyles); DWORD dwStyle = GetStyle() | dwRequiredStyles & ~dwForbiddenStyles; SetWindowLong (GWL_STYLE, dwStyle); /* * copy the image lists */ SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_NORMAL)), LVSIL_NORMAL); SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_SMALL)), LVSIL_SMALL); SetImageList (HackDuplicate(m_wndSourceList.GetImageList (LVSIL_STATE)), LVSIL_STATE); /* * insert the columns */ InsertColumns (); /* * copy the items (we're virtual, so copying the items only means we * copy the item count) */ SetItemCount (m_wndSourceList.GetItemCount()); } /*+-------------------------------------------------------------------------* * CMirrorListView::InsertColumns * * *--------------------------------------------------------------------------*/ void CMirrorListView::InsertColumns () { WTL::CRect rect; GetClientRect (rect); int cxColumn = rect.Width() - GetSystemMetrics (SM_CXVSCROLL); InsertColumn (0, NULL, LVCFMT_LEFT, cxColumn, -1); } /*+-------------------------------------------------------------------------* * CMirrorListView::OnGetDispInfo * * LVN_GETDISPINFO handler for CMirrorListView. *--------------------------------------------------------------------------*/ LRESULT CMirrorListView::OnGetDispInfo (int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { LV_DISPINFO* plvdi = (LV_DISPINFO *) pnmh; return (m_wndSourceList.GetItem (&plvdi->item)); } /*+-------------------------------------------------------------------------* * CMirrorListView::ForwardVirtualNotification * * Generic notification handler for CMirrorListView. *--------------------------------------------------------------------------*/ LRESULT CMirrorListView::ForwardVirtualNotification (int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { /* * if the source list is virtual, forward the notification */ if (m_fVirtualSource) return (ForwardNotification (idCtrl, pnmh, bHandled)); return (0); } /*+-------------------------------------------------------------------------* * CMirrorListView::ForwardNotification * * Forwards list view notifications to the source list view's parent. *--------------------------------------------------------------------------*/ LRESULT CMirrorListView::ForwardNotification (int idCtrl, LPNMHDR pnmh, BOOL& bHandled) { return (::SendMessage (m_wndSourceList.GetParent(), WM_NOTIFY, idCtrl, (LPARAM) pnmh)); } /*+-------------------------------------------------------------------------* * CMirrorListView::ForwardMessage * * Forwards list view messages to the source list view. *--------------------------------------------------------------------------*/ LRESULT CMirrorListView::ForwardMessage (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { return (m_wndSourceList.SendMessage (uMsg, wParam, lParam)); } /*+-------------------------------------------------------------------------* * CMirrorListView::GetSelectedItemData * * *--------------------------------------------------------------------------*/ LRESULT CMirrorListView::GetSelectedItemData () { int nSelectedItem = GetSelectedIndex(); return ((m_fVirtualSource) ? nSelectedItem : GetItemData (nSelectedItem)); } //############################################################################ //############################################################################ // // Implementation of class CMyComboBox // //############################################################################ //############################################################################ /*+-------------------------------------------------------------------------* * CMyComboBox::InsertStrings * * *--------------------------------------------------------------------------*/ void CMyComboBox::InsertStrings (const int rgStringIDs[], int cStringIDs) { ASSERT (IsWindow ()); CStr str; for (int i = 0; i < cStringIDs; ++i) { /* * load the string and stick it in the combo */ VERIFY (str.LoadString (GetStringModule(), rgStringIDs[i])); int nIndex = AddString (str); ASSERT (nIndex >= 0); /* * set the string ID as the combo item's data */ SetItemData (nIndex, rgStringIDs[i]); } } /*+-------------------------------------------------------------------------* * CMyComboBox::GetSelectedItemData * * *--------------------------------------------------------------------------*/ LPARAM CMyComboBox::GetSelectedItemData () const { return (GetItemData (GetCurSel ())); } /*+-------------------------------------------------------------------------* * CMyComboBox::SelectItemByData * * *--------------------------------------------------------------------------*/ void CMyComboBox::SelectItemByData (LPARAM lParam) { int nIndex = FindItemByData(lParam); if (nIndex != -1) SetCurSel (nIndex); } /*+-------------------------------------------------------------------------* * CMyComboBox::FindItemByData * * *--------------------------------------------------------------------------*/ int CMyComboBox::FindItemByData (LPARAM lParam) const { int cItems = GetCount (); for (int i = 0; i < cItems; i++) { if (GetItemData (i) == lParam) break; } ASSERT (i <= cItems); if (i >= cItems) i = -1; return (i); } //############################################################################ //############################################################################ // // Utility functions // //############################################################################ //############################################################################ namespace MMC { /*+-------------------------------------------------------------------------* * GetWindowText * * Returns the text for a given window in the form of a tstring *--------------------------------------------------------------------------*/ tstring GetWindowText (HWND hwnd) { int cchText = GetWindowTextLength (hwnd) + 1; LPTSTR pszText = (LPTSTR) _alloca (cchText * sizeof (TCHAR)); ::GetWindowText (hwnd, pszText, cchText); return (pszText); } }; // namespace MMC /*+-------------------------------------------------------------------------* * PreventMFCAutoCenter * * MFC applications set a CBT hook which will subclass all non-MFC windows * with an MFC subclass proc. That subclass proc will auto-magically center * dialogs on their parents. * * We can prevent this auto-centering, by slightly adjusting the position of * the window during WM_INITDIALOG. *--------------------------------------------------------------------------*/ void PreventMFCAutoCenter (MMC_ATL::CWindow* pwnd) { RECT rect; pwnd->GetWindowRect (&rect); OffsetRect (&rect, 0, 1); pwnd->MoveWindow (&rect, false); } /*+-------------------------------------------------------------------------* * LoadSysColorBitmap * * Loads a bitmap resource and converts gray scale colors to the 3-D colors * of the current color scheme. *--------------------------------------------------------------------------*/ HBITMAP LoadSysColorBitmap (HINSTANCE hInst, UINT id, bool bMono) { return ((HBITMAP) LoadImage (hInst, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_LOADMAP3DCOLORS)); } //############################################################################ //############################################################################ // // Implementation of class CTaskPropertySheet // //############################################################################ //############################################################################ CTaskPropertySheet::CTaskPropertySheet(HWND hWndParent, CTaskpadFrame * pTaskpadFrame, CConsoleTask &consoleTask, bool fNew) : m_consoleTask(consoleTask), m_namePage(pTaskpadFrame, ConsoleTask(), fNew), m_cmdLinePage(pTaskpadFrame, ConsoleTask(), fNew), m_taskSymbolDialog(ConsoleTask()) { // Add property pages AddPage(m_namePage); AddPage(m_taskSymbolDialog); if(consoleTask.GetTaskType()==eTask_CommandLine) AddPage(m_cmdLinePage); static CStr strModifyTitle; strModifyTitle.LoadString(GetStringModule(), IDS_TaskProps_ModifyTitle); // set internal state - not using ATL's SetTitle because of bogus assert. m_psh.pszCaption = (LPCTSTR) strModifyTitle; m_psh.dwFlags &= ~PSH_PROPTITLE; } //############################################################################ //############################################################################ // // Implementation of class CTaskWizard // //############################################################################ //############################################################################ HRESULT CTaskWizard::Show(HWND hWndParent, CTaskpadFrame * pTaskpadFrame, bool fNew, bool *pfRestartTaskWizard) { USES_CONVERSION; *pfRestartTaskWizard = false; IFramePrivatePtr spFrame; spFrame.CreateInstance(CLSID_NodeInit, #if _MSC_VER >= 1100 NULL, #endif MMC_CLSCTX_INPROC); IPropertySheetProviderPtr pIPSP = spFrame; if (pIPSP == NULL) return S_FALSE; HRESULT hr = pIPSP->CreatePropertySheet (L"Cool :-)", FALSE, NULL, NULL, MMC_PSO_NEWWIZARDTYPE); CHECK_HRESULT(hr); if (FAILED(hr)) return hr; // create property pages CTaskWizardWelcomePage welcomePage (pTaskpadFrame, ConsoleTask(), fNew); CTaskWizardTypePage typePage (pTaskpadFrame, ConsoleTask(), fNew); CTaskCmdLineWizardPage cmdLinePage (pTaskpadFrame, ConsoleTask(), fNew); CTaskWizardFavoritePage favoritePage(pTaskpadFrame, ConsoleTask(), fNew); CTaskWizardMenuPage menuPage (pTaskpadFrame, ConsoleTask(), fNew); CTaskNameWizardPage namePage (pTaskpadFrame, ConsoleTask(), fNew); CTaskSymbolWizardPage symbolPage (ConsoleTask()); CTaskWizardFinishPage finishPage (pTaskpadFrame, ConsoleTask(), pfRestartTaskWizard); // create the pages we'll add in IExtendPropertySheet::CreatePropertyPages CExtendPropSheet* peps; hr = CExtendPropSheet::CreateInstance (&peps); CHECK_HRESULT(hr); RETURN_ON_FAIL(hr); /* * destroying this object will take care of releasing our ref on peps */ IUnknownPtr spUnk = peps; ASSERT (spUnk != NULL); peps->SetWatermarkID (IDB_TASKPAD_WIZARD_WELCOME); peps->SetHeaderID (IDB_TASKPAD_WIZARD_HEADER); peps->AddPage (welcomePage.Create()); peps->AddPage (typePage.Create()); peps->AddPage (menuPage.Create()); peps->AddPage (favoritePage.Create()); peps->AddPage (cmdLinePage.Create()); peps->AddPage (namePage.Create()); peps->AddPage (symbolPage.Create()); peps->AddPage (finishPage.Create()); hr = pIPSP->AddPrimaryPages(spUnk, FALSE, NULL, FALSE); CHECK_HRESULT(hr); hr = pIPSP->Show((LONG_PTR)hWndParent, 0); CHECK_HRESULT(hr); return hr; } //############################################################################ //############################################################################ // // Implementation of class CTaskWizardWelcomePage // //############################################################################ //############################################################################ LRESULT CTaskWizardWelcomePage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CWizardPage::OnInitWelcomePage(m_hWnd); // set up the correct title font return 0; } bool CTaskWizardWelcomePage::OnSetActive() { CWizardPage::OnWelcomeSetActive(m_hWnd); return true; } bool CTaskWizardWelcomePage::OnKillActive() { CWizardPage::OnWelcomeKillActive(m_hWnd); return true; } //############################################################################ //############################################################################ // // Implementation of class CTaskWizardFinishPage // //############################################################################ //############################################################################ CTaskWizardFinishPage::CTaskWizardFinishPage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool *pfRestartTaskWizard) : m_pConsoleTask(&consoleTask), m_taskpadFrameTemp(*pTaskpadFrame), m_consoleTaskpadTemp(*(pTaskpadFrame->PConsoleTaskpad())), BaseClass(&m_taskpadFrameTemp, false, false), CTaskpadFramePtr(pTaskpadFrame) { m_taskpadFrameTemp.SetConsoleTaskpad(&m_consoleTaskpadTemp); m_pfRestartTaskWizard = pfRestartTaskWizard; /* * welcome and finish pages in Wizard97-style wizards don't have headers */ m_psp.dwFlags |= PSP_HIDEHEADER; } LRESULT CTaskWizardFinishPage::OnInitDialog ( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { BaseClass::OnInitDialog(uMsg, wParam, lParam, bHandled); // call the base class -required here. CWizardPage::OnInitFinishPage(m_hWnd); // set up the correct title font CheckDlgButton(IDB_RESTART_TASK_WIZARD, BST_UNCHECKED); return 0; } BOOL CTaskWizardFinishPage::OnSetActive() { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_FINISH); CConsoleTaskpad* pTaskpad = m_taskpadFrameTemp.PConsoleTaskpad(); *pTaskpad = *(CTaskpadFramePtr::PTaskpadFrame()->PConsoleTaskpad()); // reset the taskpad CConsoleTaskpad::TaskIter itTask = pTaskpad->EndTask(); // add the task to the list. UpdateTaskListbox (pTaskpad->InsertTask (itTask, ConsoleTask())); return TRUE; } BOOL CTaskWizardFinishPage::OnWizardFinish() { *m_pfRestartTaskWizard = (IsDlgButtonChecked(IDB_RESTART_TASK_WIZARD)==BST_CHECKED); return TRUE; } int CTaskWizardFinishPage::OnWizardBack() { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT); return 0; } //############################################################################ //############################################################################ // // Implementation of class CTaskWizardTypePage // //############################################################################ //############################################################################ CTaskWizardTypePage::CTaskWizardTypePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : CTaskpadFramePtr(pTaskpadFrame) { m_pConsoleTask = &consoleTask; } int CTaskWizardTypePage::OnWizardNext() { int ID = 0; // go to the appropriate page. switch(ConsoleTask().GetTaskType()) { case eTask_Result: case eTask_Scope: case eTask_Target: ID = IDD_TASK_WIZARD_MENU_PAGE; break; case eTask_CommandLine: ID = IDD_TASK_WIZARD_CMDLINE_PAGE; break; case eTask_Favorite: ID = IDD_TASK_WIZARD_FAVORITE_PAGE; break; default: ASSERT(0 && "Should not come here."); break; } return ID; } LRESULT CTaskWizardTypePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { int ID = 0; switch (ConsoleTask().GetTaskType()) { case eTask_Result: case eTask_Target: // all these types have identical handlers in this page. case eTask_Scope: ID = IDC_MENU_TASK; break; case eTask_CommandLine: ID = IDC_CMDLINE_TASK; break; case eTask_Favorite: ID = IDC_NAVIGATION_TASK; break; default: ASSERT(0 && "Should not come here."); break; } ::SendDlgItemMessage(m_hWnd, ID, BM_SETCHECK, (WPARAM) true, 0); return 0; } LRESULT CTaskWizardTypePage::OnMenuTask ( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { if( (ConsoleTask().GetTaskType() != eTask_Scope) || (ConsoleTask().GetTaskType() != eTask_Result) ) // if changing task types { ConsoleTask() = CConsoleTask(); // clear out the task info. ConsoleTask().SetTaskType(eTask_Scope); } return 0; } LRESULT CTaskWizardTypePage::OnCmdLineTask( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { if(ConsoleTask().GetTaskType() != eTask_CommandLine) // if changing task types { ConsoleTask() = CConsoleTask(); // clear out the task info. ConsoleTask().SetTaskType(eTask_CommandLine); } return 0; } LRESULT CTaskWizardTypePage::OnFavoriteTask(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { if(ConsoleTask().GetTaskType() != eTask_Favorite) // if changing task types { ConsoleTask() = CConsoleTask(); // clear out the task info. ConsoleTask().SetTaskType(eTask_Favorite); } return 0; } //############################################################################ //############################################################################ // // Implementation of class CTaskNamePage // //############################################################################ //############################################################################ CTaskNamePage::CTaskNamePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : CTaskpadFramePtr(pTaskpadFrame) { m_pConsoleTask = &consoleTask; /* * if this page is for a new task, we'll be running in a wizard (not * a property sheet) */ m_fRunAsWizard = fNew; } BOOL CTaskNamePage::SetTaskName(bool fCheckIfOK) { /* * get the task name */ CWindow wndTaskName = GetDlgItem (IDC_TaskName); tstring strName = MMC::GetWindowText (wndTaskName); /* * a name is required (usually) */ if (fCheckIfOK && strName.empty()) { CStr strError; strError.LoadString(GetStringModule(), IDS_TaskProps_ErrorNoTaskName); MessageBox (strError); wndTaskName.SetFocus (); return (false); // don't allow the change. } /* * get the description */ tstring strDescription = MMC::GetWindowText (GetDlgItem (IDC_TaskDescription)); /* * update the task */ ConsoleTask().SetName (strName); ConsoleTask().SetDescription (strDescription); return (true); } int CTaskNamePage::OnWizardNext() { if(!SetTaskName(true)) return -1; return IDD_TASK_WIZARD_SYMBOL_PAGE; } int CTaskNamePage::OnWizardBack() { int ID = 0; // go to the appropriate page. switch(ConsoleTask().GetTaskType()) { case eTask_Result: case eTask_Scope: case eTask_Target: ID = IDD_TASK_WIZARD_MENU_PAGE; break; case eTask_CommandLine: ID = IDD_TASK_WIZARD_CMDLINE_PAGE; break; case eTask_Favorite: ID = IDD_TASK_WIZARD_FAVORITE_PAGE; break; default: ASSERT(0 && "Should not come here."); break; } return ID; } BOOL CTaskNamePage::OnSetActive() { // Set the correct wizard buttons (only if we're running as a wizard) if (m_fRunAsWizard) WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK | PSWIZB_NEXT); ::SetDlgItemText (m_hWnd, IDC_TaskName, ConsoleTask().GetName().data()); ::SetDlgItemText (m_hWnd, IDC_TaskDescription, ConsoleTask().GetDescription().data()); return TRUE; } BOOL CTaskNamePage::OnKillActive() { SetTaskName(false); // don't care if it is blank (eg if user pressed "Back" button.) return TRUE; } //############################################################################ //############################################################################ // // Implementation of class CTaskWizardMenuPage // //############################################################################ //############################################################################ CTaskWizardMenuPage::CTaskWizardMenuPage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : CTaskpadFramePtr(pTaskpadFrame), BC2(pTaskpadFrame, consoleTask, fNew) { m_pMirrorTargetNode = NULL; } BOOL CTaskWizardMenuPage::OnSetActive() { return TRUE; } BOOL CTaskWizardMenuPage::OnKillActive() { return TRUE; } int CTaskWizardMenuPage::OnWizardNext() { if(m_wndCommandListbox.GetCurSel() == LB_ERR) // no selection, display error { CStr strTitle; strTitle.LoadString(GetStringModule(), IDS_TASK_MENU_COMMAND_REQUIRED); MessageBox(strTitle, NULL, MB_OK | MB_ICONEXCLAMATION); return -1; } return IDD_TASK_WIZARD_NAME_PAGE; } CTaskWizardMenuPage::_TaskSource CTaskWizardMenuPage::s_rgTaskSource[] = { {IDS_TASKSOURCE_RESULT, eTask_Result}, {IDS_TASKSOURCE_SCOPE, eTask_Scope}, }; LRESULT CTaskWizardMenuPage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { //attach HWNDs to CWindows m_wndCommandListbox = GetDlgItem (IDC_CommandList); CNode* pTargetNode = NULL; if(PTaskpadFrame()->PConsoleTaskpad()->HasTarget()) pTargetNode = PNodeTarget(); // populate the drop down m_wndSourceCombo = GetDlgItem (IDC_TASK_SOURCE_COMBO); for (int i = 0; i < countof (s_rgTaskSource); i++) { CStr str; VERIFY (str.LoadString(GetStringModule(), s_rgTaskSource[i].idsName)); VERIFY (m_wndSourceCombo.InsertString (-1, str) == i); } /* * attach the scope browser to the scope tree */ CMTBrowserCtrl::InitData init; init.hwnd = GetDlgItem (IDC_ScopeTree); init.pScopeTree = PScopeTree(); init.pmtnSelect = (pTargetNode != NULL) ? pTargetNode->GetMTNode() : NULL; // remember the task type... eConsoleTaskType type = ConsoleTask().GetTaskType(); m_wndScopeTree.Initialize (init); // populate the result menu item list. if (pTargetNode /*&& bResultTask*/) { InitResultView (pTargetNode); } // reset the task type from above... ConsoleTask().SetTaskType(type); EnableWindows(); OnSettingsChanged(); return 0; } void CTaskWizardMenuPage::ShowWindow(HWND hWnd, bool bShowWindow) { if (!::IsWindow(hWnd)) return; ::ShowWindow (hWnd, bShowWindow ? SW_SHOW : SW_HIDE); ::EnableWindow(hWnd, bShowWindow); } void CTaskWizardMenuPage::EnableWindows() { eConsoleTaskType type = ConsoleTask().GetTaskType(); if(type == eTask_Target) type = eTask_Scope; // for the purposes of the UI these are identical. // display the correct task type. for(int i = 0; i< countof (s_rgTaskSource); i++) { if(s_rgTaskSource[i].type == type) break; } ASSERT(i 0); ASSERT(bResultItems || !bResultTask); ::EnableWindow(GetDlgItem(IDC_RESULT_TASK), bResultItems); */ ShowWindow(GetDlgItem(IDC_RESULT_TASK_DESCR), bResultTask); ShowWindow(GetDlgItem(IDC_CONSOLE_TREE_CAPTION), !bResultTask); ShowWindow(GetDlgItem(IDC_ScopeTree), !bResultTask); ShowWindow(GetDlgItem(IDC_ResultList), bResultTask); } LRESULT CTaskWizardMenuPage::OnSettingChanged( WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled ) { OnSettingsChanged(); return 0; } void CTaskWizardMenuPage::OnSettingsChanged() { eConsoleTaskType type = s_rgTaskSource[m_wndSourceCombo.GetCurSel()].type; ConsoleTask().SetTaskType(type); EnableWindows(); if(type == eTask_Scope) { HTREEITEM hti = m_wndScopeTree.GetSelectedItem(); m_wndScopeTree.SelectItem(NULL); // remove the selection m_wndScopeTree.SelectItem(hti); // reselect it. } else { // empty the list box m_wndCommandListbox.ResetContent(); SelectFirstResultItem(false); SelectFirstResultItem(true); } } /*+-------------------------------------------------------------------------* * CTaskWizardMenuPage::OnScopeItemChanged * * /*+-------------------------------------------------------------------------*/ LRESULT CTaskWizardMenuPage::OnScopeItemChanged(int id, LPNMHDR pnmh, BOOL& bHandled) { // empty the list box m_wndCommandListbox.ResetContent(); LPNMTREEVIEW pnmtv = (LPNMTREEVIEW) pnmh; CBrowserCookie *pBrowserCookie = m_wndScopeTree.CookieFromItem (&pnmtv->itemNew); if(!pBrowserCookie) // no item selected return 0; CNode* pNode = pBrowserCookie->PNode(); CMTNode * pMTNode = pBrowserCookie->PMTNode(); // validate parameters ASSERT(pMTNode); ASSERT(PTaskpadFrame()->PViewData()); if(!pNode) { pNode = pMTNode->GetNode(PTaskpadFrame()->PViewData()); if(!pNode) return 0; pBrowserCookie->SetNode(pNode); HRESULT hr = pNode->InitComponents(); if (FAILED(hr)) return 0; } bool bNodeIsTarget = PTaskpadFrame()->PConsoleTaskpad()->HasTarget() && (PNodeTarget()->GetMTNode() == pNode->GetMTNode()); // set the correct task type. ConsoleTask().SetTaskType(bNodeIsTarget ? eTask_Target : eTask_Scope); // retarget the scope node bookmark if(!bNodeIsTarget) ConsoleTask().RetargetScopeNode(pNode); int cResultItemCount = ListView_GetItemCount(m_MirroredView.GetListCtrl()); SC sc = ScTraverseContextMenu(pNode, PScopeTree(), TRUE, PTaskpadFrame()->PNodeTarget(), 0, bNodeIsTarget && (cResultItemCount > 0)/*bShowSaveList*/); return (0); } void CTaskWizardMenuPage::InitResultView (CNode* pRootNode) { /* * create the temporary view whose contents we'll mirror */ ASSERT (pRootNode != NULL); m_pMirrorTargetNode = m_MirroredView.Create (PScopeTree()->GetConsoleFrame(), pRootNode); ASSERT (m_pMirrorTargetNode != NULL); /* * force the snap-in into a standard list view */ HRESULT hr; hr = m_pMirrorTargetNode->InitComponents (); hr = m_pMirrorTargetNode->ShowStandardListView (); if (FAILED (hr)) { // TODO(jeffro): handle snap-ins that don't support a standard list view } /* * attach the temporary view's list view to our mirror list view */ m_wndResultView.AttachSource (GetDlgItem (IDC_ResultList), m_MirroredView.GetListCtrl()); //SelectFirstResultItem(); } void CTaskWizardMenuPage::SelectFirstResultItem(bool bSelect) { /* * Select the first item. Note that one would think we'd be able to use: * * m_wndResultView.SetItemState (0, LVIS_SELECTED, LVIS_SELECTED); * * to select the item. We can't though because that overload of * SetItemState sends LVM_SETITEM, which fails for virtual listviews. * * If we instead use: * * m_wndResultView.SetItemState (nItem, LV_ITEM* pItem) * * then LVM_SETITEMSTATE will be sent, which works for virtual listviews. */ int i = m_wndResultView.GetItemCount(); if(i == 0) return; LV_ITEM lvi; lvi.mask = LVIF_STATE; lvi.iItem = 0; lvi.state = bSelect ? LVIS_SELECTED : 0; lvi.stateMask = LVIS_SELECTED; m_wndResultView.SetItemState (0, &lvi); } /*+-------------------------------------------------------------------------* * CTaskWizardMenuPage::OnResultItemChanged * * *--------------------------------------------------------------------------*/ LRESULT CTaskWizardMenuPage::OnResultItemChanged(int id, LPNMHDR pnmh, BOOL& bHandled) { NM_LISTVIEW* pnmlv = (NM_LISTVIEW*) pnmh; /* * if a new item is being selected, populate the result menu item list */ if ((pnmlv->uNewState & LVIS_SELECTED) && !(pnmlv->uOldState & LVIS_SELECTED)) { ASSERT (m_pMirrorTargetNode != NULL); m_wndCommandListbox.ResetContent(); SC sc = ScTraverseContextMenu (m_pMirrorTargetNode, PScopeTree(), FALSE, NULL, m_wndResultView.GetSelectedItemData ()); } // set the correct task type. ConsoleTask().SetTaskType(eTask_Result); return (0); } //############################################################################ //############################################################################ // // Implementation of class CTaskWizardFavoritePage // //############################################################################ //############################################################################ CTaskWizardFavoritePage::CTaskWizardFavoritePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : CTaskpadFramePtr(pTaskpadFrame), m_bItemSelected(false) { m_pConsoleTask = &consoleTask; } CTaskWizardFavoritePage::~CTaskWizardFavoritePage() { } BOOL CTaskWizardFavoritePage::OnSetActive() { SetItemSelected(m_bItemSelected); // restore the state. return true; } BOOL CTaskWizardFavoritePage::OnKillActive() { return true; } int CTaskWizardFavoritePage::OnWizardBack() { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT); return IDD_TASK_WIZARD_TYPE_PAGE; } int CTaskWizardFavoritePage::OnWizardNext() { return IDD_TASK_WIZARD_NAME_PAGE; } void CTaskWizardFavoritePage::SetItemSelected(bool bItemSelected) { m_bItemSelected = bItemSelected; // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (bItemSelected ? (PSWIZB_BACK | PSWIZB_NEXT) : (PSWIZB_BACK)); } LRESULT CTaskWizardFavoritePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CConsoleView* pConsoleView = PTaskpadFrame()->PViewData()->GetConsoleView(); if (pConsoleView != NULL) { HWND hwndCtrl = pConsoleView->CreateFavoriteObserver (m_hWnd, IDC_FavoritesTree); ASSERT(hwndCtrl != NULL); HWND hWndStatic = GetDlgItem(IDC_FAVORITE_STATIC); ASSERT(hWndStatic != NULL); RECT rectStatic; ::GetWindowRect(hWndStatic, &rectStatic); WTL::CPoint pointTopLeft; pointTopLeft.y = rectStatic.top; pointTopLeft.x = rectStatic.left; ::ScreenToClient(m_hWnd, &pointTopLeft); ::SetWindowPos(hwndCtrl, NULL, pointTopLeft.x, pointTopLeft.y, rectStatic.right -rectStatic.left, rectStatic.bottom - rectStatic.top, SWP_NOZORDER); } return 0; } LRESULT CTaskWizardFavoritePage::OnItemChanged (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { CMemento *pMemento = (CMemento *)wParam; if(pMemento != NULL) { ConsoleTask().SetMemento(*pMemento); } else { // Set the correct wizard buttons. WTL::CPropertySheetWindow(::GetParent(m_hWnd)).SetWizardButtons (PSWIZB_BACK); } SetItemSelected(pMemento!=NULL); return 0; } //############################################################################ //############################################################################ // // Implementation of class CTaskCmdLinePage // //############################################################################ //############################################################################ // contents of the "Run:" combo box const int const CTaskCmdLinePage::s_rgidWindowStates[] = { IDS_TaskProps_Restored, IDS_TaskProps_Minimized, IDS_TaskProps_Maximized, }; CTaskCmdLinePage::CTaskCmdLinePage(CTaskpadFrame * pTaskpadFrame, CConsoleTask & consoleTask, bool fNew) : m_hBitmapRightArrow(NULL), CTaskpadFramePtr(pTaskpadFrame) { m_pConsoleTask = &consoleTask; } CTaskCmdLinePage::~CTaskCmdLinePage() { if(m_hBitmapRightArrow) ::DeleteObject(m_hBitmapRightArrow); } BOOL CTaskCmdLinePage::OnSetActive() { return TRUE; } BOOL CTaskCmdLinePage::OnKillActive() { switch (m_wndWindowStateCombo.GetSelectedItemData()) { case IDS_TaskProps_Restored: ConsoleTask().SetWindowState (eState_Restored); break; case IDS_TaskProps_Maximized: ConsoleTask().SetWindowState (eState_Maximized); break; case IDS_TaskProps_Minimized: ConsoleTask().SetWindowState (eState_Minimized); break; } ConsoleTask().SetCommand (MMC::GetWindowText (GetDlgItem (IDC_Command))); ConsoleTask().SetParameters(MMC::GetWindowText (GetDlgItem (IDC_CommandArgs))); ConsoleTask().SetDirectory (MMC::GetWindowText (GetDlgItem (IDC_CommandWorkingDir))); return TRUE; } int CTaskCmdLinePage::OnWizardNext() { // make sure we have a command tstring strCommand = MMC::GetWindowText (GetDlgItem (IDC_Command)); if (strCommand.empty()) { CStr strError; strError.LoadString(GetStringModule(), IDS_TaskProps_ErrorNoCommand); MessageBox (strError); ::SetFocus (GetDlgItem (IDC_Command)); return (-1); } return IDD_TASK_WIZARD_NAME_PAGE; } LRESULT CTaskCmdLinePage::OnInitDialog( UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled ) { // Attach HWNDs to CWindows m_wndRightArrowButton = GetDlgItem (IDC_BrowseForArguments); m_wndWindowStateCombo = GetDlgItem (IDC_CommandWindowStateCombo); // the menu arrow (OBM_NARROW) is defined by the system. m_hBitmapRightArrow = LoadBitmap(NULL, MAKEINTRESOURCE(OBM_MNARROW)); m_wndRightArrowButton.SetBitmap(m_hBitmapRightArrow); // populate the combo boxes m_wndWindowStateCombo. InsertStrings (s_rgidWindowStates, countof (s_rgidWindowStates)); // select the appropriate items in the combo boxes switch (ConsoleTask().GetWindowState()) { case eState_Restored: m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Restored); break; case eState_Minimized: m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Minimized); break; case eState_Maximized: m_wndWindowStateCombo.SelectItemByData(IDS_TaskProps_Maximized); break; } ::SetDlgItemText (m_hWnd, IDC_Command, ConsoleTask().GetCommand().data()); ::SetDlgItemText (m_hWnd, IDC_CommandArgs, ConsoleTask().GetParameters().data()); ::SetDlgItemText (m_hWnd, IDC_CommandWorkingDir, ConsoleTask().GetDirectory().data()); return 0; } LRESULT CTaskCmdLinePage::OnBrowseForArguments(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { CCommandLineArgumentsMenu commandLineArgumentsMenu(m_hWnd, IDC_BrowseForArguments, PTaskpadFrame()->PViewData()->GetListCtrl()); if(commandLineArgumentsMenu.Popup()) { HWND hWndCommandArgs = ::GetDlgItem(m_hWnd, IDC_CommandArgs); // replace the selection appropriately. ::SendMessage(hWndCommandArgs, EM_REPLACESEL, (WPARAM)(BOOL) true /*fCanUndo*/, (LPARAM)(LPCTSTR)commandLineArgumentsMenu.GetResultString()); ::SetFocus(hWndCommandArgs); } return 0; } /*+-------------------------------------------------------------------------* * CTaskCmdLinePage::OnBrowseForCommand * * *--------------------------------------------------------------------------*/ LRESULT CTaskCmdLinePage::OnBrowseForCommand (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { tstring strCommand = MMC::GetWindowText (GetDlgItem (IDC_Command)); CStr strFilter; strFilter.LoadString(GetStringModule(), IDS_TaskProps_ProgramFilter); /* * The file dialog expects embedded \0's in the string, but those * don't load well. The string in the resource file has \\ where * the \0 should be, so let's make the substitution now. */ for (LPTSTR pch = strFilter.GetBuffer (0); *pch != _T('\0'); pch++) { if (*pch == _T('\\')) *pch = _T('\0'); } // don't call ReleaseBuffer, since the string now contains \0 chars WTL::CFileDialog dlg (true, NULL, strCommand.data(), OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, strFilter, m_hWnd); if (dlg.DoModal() == IDOK) SetDlgItemText (IDC_Command, dlg.m_szFileName); return (0); } /*+-------------------------------------------------------------------------* * BrowseForWorkingDirCallback * * Helper function for CTaskPropertiesBase::OnBrowseForWorkingDir. It is * used to select the current working directory when the "Pick a Directory" * dialog is displayed. *--------------------------------------------------------------------------*/ int CALLBACK BrowseForWorkingDirCallback (HWND hwnd, UINT msg, LPARAM lParam, LPARAM lpData) { /* * once the dialog is initialized, pre-select * the current working directory (if there is one) */ if ((msg == BFFM_INITIALIZED) && (lpData != NULL)) SendMessage (hwnd, BFFM_SETSELECTION, true, lpData); return (0); } /*+-------------------------------------------------------------------------* * CTaskPropertiesBase::OnBrowseForWorkingDir * * *--------------------------------------------------------------------------*/ LRESULT CTaskCmdLinePage::OnBrowseForWorkingDir (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled) { TCHAR szDisplayName[MAX_PATH]; tstring strCurrentDir = MMC::GetWindowText (GetDlgItem (IDC_CommandWorkingDir)); BROWSEINFO bi; bi.hwndOwner = m_hWnd; bi.pidlRoot = NULL; bi.pszDisplayName = szDisplayName; bi.lpszTitle = NULL; bi.ulFlags = BIF_RETURNONLYFSDIRS; bi.lpfn = BrowseForWorkingDirCallback; bi.lParam = (strCurrentDir.empty()) ? NULL : (LPARAM) strCurrentDir.data(); bi.iImage = 0; LPITEMIDLIST pidlWorkingDir = SHBrowseForFolder (&bi); if (pidlWorkingDir != NULL) { /* * expand the pidl and put the working directory into the control */ SHGetPathFromIDList (pidlWorkingDir, szDisplayName); SetDlgItemText (IDC_CommandWorkingDir, szDisplayName); /* * free the pidl */ IMallocPtr spMalloc; SHGetMalloc (&spMalloc); spMalloc->Free (pidlWorkingDir); } return (0); } //############################################################################ //############################################################################ // // Implementation of class CTempAMCView // //############################################################################ //############################################################################ CNode* CTempAMCView::Create (CConsoleFrame* pFrame, CNode* pRootNode) { ASSERT (pRootNode != NULL); return (Create (pFrame, pRootNode->GetMTNode())); } CNode* CTempAMCView::Create (CConsoleFrame* pFrame, CMTNode* pRootMTNode) { ASSERT (pRootMTNode != NULL); return (Create (pFrame, pRootMTNode->GetID())); } CNode* CTempAMCView::Create (CConsoleFrame* pFrame, MTNODEID idRootNode) { HRESULT hr; ASSERT (idRootNode != 0); ASSERT (pFrame != NULL); CConsoleView* pConsoleView = NULL; /* * clean up an existing view */ Destroy(); ASSERT (m_pViewData == NULL); /* * create a new view */ CreateNewViewStruct cnvs; cnvs.idRootNode = idRootNode; cnvs.lWindowOptions = MMC_NW_OPTION_NOPERSIST; cnvs.fVisible = false; SC sc = pFrame->ScCreateNewView(&cnvs); if (sc) goto Error; m_pViewData = reinterpret_cast(cnvs.pViewData); /* * select the new view's root node (can't fail) */ pConsoleView = GetConsoleView(); ASSERT (pConsoleView != NULL); if (pConsoleView != NULL) sc = pConsoleView->ScSelectNode (idRootNode); if (sc) goto Error; return (CNode::FromHandle(cnvs.hRootNode)); Cleanup: return (NULL); Error: TraceError (_T("CTempAMCView::Create"), sc); goto Cleanup; }