//____________________________________________________________________________ // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997 - 1999 // // File: verbs.cpp // // Contents: // // Classes: // // Functions: // // History: 4/9/1997 RaviR Created //____________________________________________________________________________ // #include "stdafx.h" #include "multisel.h" #include "tasks.h" #include "scopndcb.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #ifdef DBG CTraceTag tagVerbs(TEXT("Verbs"), TEXT("Verbs")); #endif //############################################################################ //############################################################################ // // Implementation of class CConsoleVerbImpl // //############################################################################ //############################################################################ BYTE GetTBSTATE(MMC_BUTTON_STATE mmcState) { switch (mmcState) { case ENABLED: return TBSTATE_ENABLED; case CHECKED: return TBSTATE_CHECKED; case HIDDEN: return TBSTATE_HIDDEN; case INDETERMINATE: return TBSTATE_INDETERMINATE; case BUTTONPRESSED: return TBSTATE_PRESSED; default: ASSERT(0); return TBSTATE_ENABLED; } } EVerb GetEVerb(MMC_CONSOLE_VERB cVerb) { switch (cVerb) { case MMC_VERB_OPEN: return evOpen; case MMC_VERB_CUT: return evCut; case MMC_VERB_COPY: return evCopy; case MMC_VERB_PASTE: return evPaste; case MMC_VERB_DELETE: return evDelete; case MMC_VERB_PROPERTIES: return evProperties; case MMC_VERB_RENAME: return evRename; case MMC_VERB_REFRESH: return evRefresh; case MMC_VERB_PRINT: return evPrint; default: ASSERT(0 && "UNexpected"); return evOpen; } } MMC_CONSOLE_VERB GetConsoleVerb(EVerb eVerb) { switch (eVerb) { case evOpen: return MMC_VERB_OPEN; case evCopy: return MMC_VERB_COPY; case evCut: return MMC_VERB_CUT; case evPaste: return MMC_VERB_PASTE; case evDelete: return MMC_VERB_DELETE; case evProperties: return MMC_VERB_PROPERTIES; case evRename: return MMC_VERB_RENAME; case evRefresh: return MMC_VERB_REFRESH; case evPrint: return MMC_VERB_PRINT; default: ASSERT(0 && "UNexpected"); return MMC_VERB_OPEN; } } DEBUG_DECLARE_INSTANCE_COUNTER(CConsoleVerbImpl); CConsoleVerbImpl::CConsoleVerbImpl() : m_DefaultVerb(MMC_VERB_OPEN), m_pVerbSet(NULL), m_bCutVerbDisabledBySnapin(false) { #ifdef DBG DEBUG_INCREMENT_INSTANCE_COUNTER(CConsoleVerbImpl); dbg_cRef_CConsoleVerbImpl = 0; #endif } #ifdef DBG ULONG CConsoleVerbImpl::InternalAddRef() { ++dbg_cRef_CConsoleVerbImpl; return CComObjectRoot::InternalAddRef(); } ULONG CConsoleVerbImpl::InternalRelease() { --dbg_cRef_CConsoleVerbImpl; return CComObjectRoot::InternalRelease(); } #endif // DBG CConsoleVerbImpl::~CConsoleVerbImpl() { DEBUG_DECREMENT_INSTANCE_COUNTER(CConsoleVerbImpl); } STDMETHODIMP CConsoleVerbImpl::GetVerbState( MMC_CONSOLE_VERB eCmdID, MMC_BUTTON_STATE nState, BOOL* pbState) { DECLARE_SC(sc, TEXT("CConsoleVerbImpl::GetVerbState")); sc = ScCheckPointers(pbState); if (sc) return sc.ToHr(); LPCONSOLE_VERB_STATE pCS = GetConsoleVerbState(eCmdID); sc = ScCheckPointers(pCS, E_UNEXPECTED); if (sc) return sc.ToHr(); /* * Special case for cut verb: * * Pre MMC2.0 : Snapin never called IConsoleVerb::SetVerbState with cut verb * except with (cut, disable) state, to enable cut the Snapin has to enable * copy & delete verbs. * * MMC2.0 : snapin can enable/disable cut verb just like any other verb. * Then if hidden hide it. * * If snapin has enabled or disabled the cut verb then below BLOCK1 is * irrelevant, the BLOCK2 will override the value. * If snapin did not enable the cut verb but enabled copy & delete then * the block BLOCK2. set the cut verb appropriately. */ // BLOCK1. Special case for MMC1.2 cut verb. if ( (eCmdID == MMC_VERB_CUT) && (!m_bCutVerbDisabledBySnapin) ) { // Pre MMC2.0 LPCONSOLE_VERB_STATE pCSDelete = GetConsoleVerbState(MMC_VERB_DELETE); LPCONSOLE_VERB_STATE pCSCopy = GetConsoleVerbState(MMC_VERB_COPY); sc = ScCheckPointers(pCSDelete, pCSCopy, E_UNEXPECTED); if (sc) return sc.ToHr(); if (TBSTATE_ENABLED & pCSCopy->GetState() & pCSDelete->GetState()) { // Set Cut verb to be not hidden & enabled. pCS->SetState(pCS->GetState() & ~GetTBSTATE(HIDDEN)); pCS->SetState(pCS->GetState() | GetTBSTATE(ENABLED)); } } // BLOCK2. Get the given verbs state. *pbState = (pCS->GetState() & GetTBSTATE(nState)) ? TRUE : FALSE; return sc.ToHr(); } STDMETHODIMP CConsoleVerbImpl::SetVerbState( MMC_CONSOLE_VERB eCmdID, MMC_BUTTON_STATE nState, BOOL bState) { LPCONSOLE_VERB_STATE pCS = GetConsoleVerbState(eCmdID); ASSERT(pCS != NULL); if (pCS == NULL) return E_FAIL; // If snapin has enabled/disabled cut verb note it. // Used by CConsoleVerbImpl::GetVerbState. if ( (MMC_VERB_CUT == eCmdID) && (nState & ENABLED) ) m_bCutVerbDisabledBySnapin = (bState == FALSE); if (bState) pCS->SetState(pCS->GetState() | GetTBSTATE(nState)); else pCS->SetState(pCS->GetState() & ~GetTBSTATE(nState)); if (nState == HIDDEN && bState == TRUE) { pCS->SetHiddenBySnapin(true); } /* * If we're enabling, make sure the verb is not hidden. * We do this for compatibility. For v1.0, the default state * for a verb was disabled and visible when it actually should * have been disabled and hidden. Therefore, v1.0 snap-ins could * have written * * pConsoleVerb->SetVerbState (verb, ENABLED, TRUE); * * and had an enabled, visible verb. Now that we've fixed the * default state (bug 150874), we need to make sure v1.0 snap-ins * that wrote code like the above will still work as they used to. */ if ((nState == ENABLED) && (bState == TRUE) && (!pCS->IsHiddenBySnapin())) pCS->SetState(pCS->GetState() & ~GetTBSTATE(HIDDEN)); ASSERT(GetVerbSet() != NULL); if (GetVerbSet() != NULL) GetVerbSet()->Notify(this, eCmdID); return S_OK; } HRESULT CConsoleVerbImpl::SetDisabledAll(void) { for(int i=0; i< evMax; i++) m_rgConsoleVerbStates[i].Disable(); m_bCutVerbDisabledBySnapin = false; return S_OK; } STDMETHODIMP CConsoleVerbImpl::SetDefaultVerb(MMC_CONSOLE_VERB eCmdID) { m_DefaultVerb = eCmdID; return S_OK; } LPCONSOLE_VERB_STATE CConsoleVerbImpl::GetConsoleVerbState(MMC_CONSOLE_VERB eCmdID) { if( (eCmdID < MMC_VERB_FIRST) || (eCmdID > MMC_VERB_LAST) ) return NULL; else return &m_rgConsoleVerbStates[eCmdID- MMC_VERB_FIRST]; } //############################################################################ //############################################################################ // // Implementation of class CVerbSet // //############################################################################ //############################################################################ DEBUG_DECLARE_INSTANCE_COUNTER(CVerbSet); /*+-------------------------------------------------------------------------* * * _QueryConsoleVerb * * PURPOSE: * * PARAMETERS: * CNode* pNode : * LPCONSOLEVERB* ppConsoleVerb : * * RETURNS: * HRESULT * *+-------------------------------------------------------------------------*/ HRESULT _QueryConsoleVerb(CNode* pNode, LPCONSOLEVERB* ppConsoleVerb) { DECLARE_SC(sc, TEXT("::_QueryConsoleVerb")); sc = ScCheckPointers(pNode, ppConsoleVerb); if (sc) return sc.ToHr(); *ppConsoleVerb = NULL; CComponent *pComponent = pNode->GetPrimaryComponent(); sc = ScCheckPointers(pComponent, E_UNEXPECTED); if (sc) return sc.ToHr(); IFramePrivate *pFrame = pComponent->GetIFramePrivate(); sc = ScCheckPointers(pFrame, E_UNEXPECTED); if (sc) return sc.ToHr(); sc = pFrame->QueryConsoleVerb(ppConsoleVerb); if (sc) return sc.ToHr(); return sc.ToHr(); } /*+-------------------------------------------------------------------------* * * CVerbSetBase::_GetVerbState * * PURPOSE: Return the state of given verb. The state is in current * IConsoleVerb ptr. Translate the states from this object * into the SVerbState array. * * PARAMETERS: * EVerb ev : * * RETURNS: * BYTE * *+-------------------------------------------------------------------------*/ BYTE CVerbSetBase::_GetVerbState(EVerb ev) { if (m_rbVerbState[ev].bAskSnapin != 1) return m_rbVerbState[ev].nState; if (m_spConsoleVerbCurr == NULL) return 0; m_rbVerbState[ev].nState = 0; // reset MMC_CONSOLE_VERB verb = ::GetConsoleVerb(ev); BOOL bReturn = FALSE; m_spConsoleVerbCurr->GetVerbState(verb, ENABLED, &bReturn); if (bReturn == TRUE) m_rbVerbState[ev].nState |= TBSTATE_ENABLED; m_spConsoleVerbCurr->GetVerbState(verb, HIDDEN, &bReturn); if (bReturn == TRUE) m_rbVerbState[ev].nState |= TBSTATE_HIDDEN; m_rbVerbState[ev].bAskSnapin = 2; return m_rbVerbState[ev].nState; } /*+-------------------------------------------------------------------------* * * CVerbSetBase::ScComputeVerbStates * * PURPOSE: With given context like scope or result, if result is it background * or ocx or web or multiselection compute the verbstates. * * Eventhough snapin can set any verb for its items certain verbs are * not valid in some circumstances. This method takes care of that. * * RETURNS: * SC * *+-------------------------------------------------------------------------*/ SC CVerbSetBase::ScComputeVerbStates() { DECLARE_SC(sc, TEXT("CVerbSetBase::ScComputeVerbStates")); // reset m_spConsoleVerbCurr = NULL; for (int i=0; i