|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: menubtns.cpp
//
// Contents: Menu Buttons implementation
//
// History: 08-27-99 AnandhaG Created
//
//--------------------------------------------------------------------------
#include "stdafx.h"
#include "AMC.h"
#include "ChildFrm.h"
#include "menubtns.h"
#include "AMCView.h"
#include "mainfrm.h"
#include "menubar.h"
#include "util.h" // GetTBBtnTextAndStatus()
CMenuButtonsMgrImpl::CMenuButtonsMgrImpl() : m_pChildFrame(NULL), m_pMainFrame(NULL), m_pMenuBar(NULL) { m_MenuButtons.clear(); m_AttachedMenuButtons.clear(); }
CMenuButtonsMgrImpl::~CMenuButtonsMgrImpl() { m_MenuButtons.clear(); m_AttachedMenuButtons.clear(); }
//+-------------------------------------------------------------------
//
// Member: ScInit
//
// Synopsis: Init the Menubuttons mgr.
//
// Arguments: [pMainFrame] - Ptr to Main Frame window.
// [pChildFrameWnd] - Ptr to child frame window.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScInit (CMainFrame* pMainFrame, CChildFrame* pChildFrameWnd) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScInit"));
if ( (NULL == pChildFrameWnd) || (NULL == pMainFrame)) return (sc = E_INVALIDARG);
m_pChildFrame = pChildFrameWnd; m_pMainFrame = pMainFrame;
return sc; }
//+-------------------------------------------------------------------
//
// Member: ScAddMenuButton
//
// Synopsis: Adds a menu button to the data structure
// and calls ScAddMenuButtonToMenu.
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback for button click.
// [idCommand] - Button command id.
// [lpButtonText] - Button text.
// [lpStatusText] - Button status text.
//
// Returns: SC
//
// Note : The status text is not used.
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScAddMenuButton( CMenuButtonNotify* pMenuBtnNotifyClbk, INT idCommand, LPCOLESTR lpButtonText, LPCOLESTR lpStatusText) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScAddMenuButton"));
// Validate the data
if ( (NULL == pMenuBtnNotifyClbk) || (NULL == lpButtonText) || (NULL == lpStatusText) ) return (sc = E_INVALIDARG);
// Add the data to our data structure
MMC_MenuButtonCollection::iterator it; it = GetMMCMenuButton( pMenuBtnNotifyClbk, idCommand); if (it != m_MenuButtons.end()) { // Duplicate Menu button found.
// The pMenuButtonNofifyClbk represents IMenuButton
// given to the snapin and we found another button
// with idCommand already added by this snapin.
// For compatibility reasons (disk mgmt) this is not an error.
return (sc = S_OK); }
MMC_MENUBUTTON mmb; mmb.pMenuButtonNotifyClbk = pMenuBtnNotifyClbk; mmb.idCommand = idCommand;
USES_CONVERSION; mmb.lpButtonText = OLE2CT(lpButtonText); mmb.lpStatusText = OLE2CT(lpStatusText);
// Add the MMC_MENUBUTTON to the our array.
m_MenuButtons.push_back(mmb);
// Add the menubuttons to main menu
sc = ScAddMenuButtonsToMainMenu(); if (sc) return sc;
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScModifyMenuButton
//
// Synopsis: Modify button text or status text for menu button
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback for button click.
// [idCommand] - Button command id.
// [lpButtonText] - Button text.
// [lpStatusText] - Button status text.
//
// Returns: SC
//
// Note : The status text is not used.
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScModifyMenuButton( CMenuButtonNotify* pMenuBtnNotifyClbk, INT idCommand, LPCOLESTR lpButtonText, LPCOLESTR lpStatusText) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScModifyMenuButton"));
// Validate the data
if ( (NULL == pMenuBtnNotifyClbk) || (NULL == lpButtonText) || (NULL == lpStatusText) ) return (sc = E_INVALIDARG);
if ( (NULL == m_pChildFrame) || (false == m_pChildFrame->IsChildFrameActive()) ) return (sc = E_UNEXPECTED);
// Iterate thro the vector and find the MMC_MENUBUTTON for
// given CMenuButtonNotify* and Command id of button.
MMC_MenuButtonCollection::iterator it; it = GetMMCMenuButton( pMenuBtnNotifyClbk, idCommand); if (it == m_MenuButtons.end()) { // Menu button not found.
// The pMenuButtonNofifyClbk represents IMenuButton
// given to the snapin and we could not find a menu button
// with idCommand already added by this snapin.
return (sc = E_INVALIDARG); }
it->pMenuButtonNotifyClbk = pMenuBtnNotifyClbk; it->idCommand = idCommand;
USES_CONVERSION; it->lpButtonText = OLE2CT(lpButtonText); it->lpStatusText = OLE2CT(lpStatusText);
if (NULL == m_pMenuBar) return (sc = E_UNEXPECTED);
// Change the name of the menu item.
if (-1 != it->nCommandIDFromMenuBar) { sc = (m_pMenuBar->SetMenuButton(it->nCommandIDFromMenuBar, it->lpButtonText.data()) == -1) ? E_FAIL : S_OK; if (sc) return sc; }
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScModifyMenuButtonState
//
// Synopsis: Modify menu button state.
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback for button click.
// [idCommand] - Button command id.
// [nState] - The state to be modified.
// [bState] - Set or Reset the state.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScModifyMenuButtonState( CMenuButtonNotify* pMenuBtnNotifyClbk, INT idCommand, MMC_BUTTON_STATE nState, BOOL bState) { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScModifyMenuButtonState"));
// Validate the data
if (NULL == pMenuBtnNotifyClbk) return (sc = E_INVALIDARG);
if (NULL == m_pChildFrame) return (sc = E_UNEXPECTED);
// If childframe is not active, menus for this viewdoes not exist.
if (false == m_pChildFrame->IsChildFrameActive()) { switch (nState) { case ENABLED: // Enabling is illegal disabling is Ok (do nothing).
sc = bState ? E_FAIL : S_OK; break;
case HIDDEN: // Hiding is Ok(do nothing), Un-hiding is illegal.
sc = bState ? S_OK : E_FAIL; break;
case BUTTONPRESSED: sc = E_FAIL; // Always fail.
break;
default: ASSERT(FALSE); sc = E_FAIL; break; }
return sc; }
// Iterate thro the vector and find the MMC_MENUBUTTON for
// given CMenuButtonNotify* and Command id of button.
MMC_MenuButtonCollection::iterator it; it = GetMMCMenuButton( pMenuBtnNotifyClbk, idCommand); if (it == m_MenuButtons.end()) { // Menu button not found.
// The pMenuButtonNofifyClbk represents IMenuButton
// given to the snapin and we could not find a menu button
// with idCommand already added by this snapin.
return (sc = E_INVALIDARG); }
// Note the hidden state specified by the snapin.
if (HIDDEN == nState) { bool bShow = (FALSE == bState);
it->SetShowMenu(bShow);
// If a menu button is to be un-hidden make sure that snapin buttons
// are allowed in this view. Ask view-data for this information.
if (bShow) { CAMCView* pAMCView = m_pChildFrame->GetAMCView(); if (NULL == pAMCView) return (sc = E_UNEXPECTED);
SViewData* pViewData = pAMCView->GetViewData(); if (NULL == pViewData) return (sc = E_UNEXPECTED);
// We have noted the hidden state of the button.
// Return S_OK if menubuttons are disabled for this view.
// Later when the menus are turned on the hidden state will
// be properly restored.
if (! pViewData->IsSnapinMenusAllowed()) return (sc = S_OK); } }
if (NULL == m_pMenuBar) return (sc = E_UNEXPECTED);
BOOL bRet = FALSE;
switch (nState) { case ENABLED: bRet = m_pMenuBar->EnableButton(it->nCommandIDFromMenuBar , bState); break;
case HIDDEN: bRet = m_pMenuBar->HideButton(it->nCommandIDFromMenuBar , bState); break;
case BUTTONPRESSED: bRet = m_pMenuBar->PressButton(it->nCommandIDFromMenuBar, bState); break;
default: ASSERT(FALSE); bRet = FALSE; break; }
sc = bRet ? S_OK : E_FAIL; return sc; }
//+-------------------------------------------------------------------
//
// Member: ScAddMenuButtonsToMainMenu
//
// Synopsis: Add the menu buttons that are not yet added to
// the main menu.
//
// Arguments: None
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScAddMenuButtonsToMainMenu () { AFX_MANAGE_STATE (AfxGetAppModuleState()); DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScAddMenuButtonsToMainMenu"));
// To add a menu button the following conditions must be true.
// 1. The child frame window must be active.
if ( (NULL == m_pChildFrame) || (false == m_pChildFrame->IsChildFrameActive()) ) return (sc = E_UNEXPECTED);
CAMCView* pAMCView = m_pChildFrame->GetAMCView(); if (NULL == pAMCView) return (sc = E_UNEXPECTED);
SViewData* pViewData = pAMCView->GetViewData(); if (NULL == pViewData) return (sc = E_UNEXPECTED);
if (NULL == m_pMainFrame) return (sc = E_UNEXPECTED);
m_pMenuBar = m_pMainFrame->GetMenuBar(); if (NULL == m_pMenuBar) return (sc = E_FAIL);
MMC_MenuButtonCollection::iterator it; for (it = m_MenuButtons.begin(); it != m_MenuButtons.end(); ++it) { // 2. The menu button is attached (IControlbar::Attach was called).
if (IsAttached(it->pMenuButtonNotifyClbk) == false) continue;
// 3. The button is not already added.
if (FALSE == m_pMenuBar->IsButtonHidden(it->nCommandIDFromMenuBar)) continue;
BOOL bHidden = FALSE;
if (false == pViewData->IsSnapinMenusAllowed()) bHidden = TRUE;
it->nCommandIDFromMenuBar = m_pMenuBar->InsertMenuButton((LPCTSTR)it->lpButtonText.data(), bHidden || !(it->CanShowMenu()) );
// In user mode there are no menus so this assert is not valid.
// ASSERT(-1 != it->nCommandIDFromMenuBar);
}
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScNotifyMenuClick
//
// Synopsis: A menu button is clicked. Notify appropriate owner
// to display a menu.
//
// Arguments:
// [nCommandID] - Command ID
// [pt] - display co-ordinates for popup menu.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScNotifyMenuClick(const INT nCommandID, const POINT& pt) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScNotifyMenuClick")); CAMCView* pAMCView = NULL;
MMC_MenuButtonCollection::iterator it;
// Get the MenuButton data.
it = GetMMCMenuButton( nCommandID ); if (it == m_MenuButtons.end()) return (sc = E_FAIL);
pAMCView = m_pChildFrame->GetAMCView(); if (NULL == pAMCView) return (sc = E_FAIL);
// This is snapin owned menu, so get the
// selected HNODE, lParam (if result item)
// MENUBUTTONDATA.
HNODE hNode; bool bScope; LPARAM lParam; MENUBUTTONDATA menuButtonData;
// Get the details about the selected item.
sc = pAMCView->ScGetFocusedItem (hNode, lParam, bScope); if (sc) return sc;
menuButtonData.idCommand = it->idCommand; menuButtonData.x = pt.x; menuButtonData.y = pt.y;
// Notify snapin about the click
if (NULL == it->pMenuButtonNotifyClbk) return (sc = E_UNEXPECTED);
sc = it->pMenuButtonNotifyClbk->ScNotifyMenuBtnClick(hNode, bScope, lParam, menuButtonData); if (sc) return sc;
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScAttachMenuButton
//
// Synopsis: Attach the menu buttons object (this object corresponds
// to the IMenuButton object exposed to the snapin).
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback for menu button click.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScAttachMenuButton (CMenuButtonNotify* pMenuBtnNotifyClbk) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScAttachMenuButton"));
MMC_AttachedMenuButtons::iterator it = m_AttachedMenuButtons.find(pMenuBtnNotifyClbk); if (m_AttachedMenuButtons.end() != it) { // Already attached, nothing wrong calling twice, return S_FALSE.
return (sc = S_FALSE); }
// Add the button to the set.
std::pair<MMC_AttachedMenuButtons::iterator, bool> rc = m_AttachedMenuButtons.insert(pMenuBtnNotifyClbk); if (false == rc.second) return (sc = E_FAIL);
// The menu buttons may already be added (without calling
// IControlbar::Attach)
// So give a chance for those buttons that are already added
// but just now attached to get themself added to the main menu.
sc = ScAddMenuButtonsToMainMenu (); if (sc) return sc;
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScDetachMenuButton
//
// Synopsis: Detach the menu buttons object (this object corresponds
// to the IMenuButton object exposed to the snapin).
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback for menu button click.
//
// Returns: SC
//
// Note : Detach removes the menu buttons and destroys the object.
// So to re-create the menu button the snapin should again
// do IMenuButton::AddButton and IControlbar::Attach.
// This is how it is designed in mmc 1.0
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScDetachMenuButton (CMenuButtonNotify* pMenuBtnNotifyClbk) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScDetachMenuButton"));
if ( (NULL == m_pChildFrame) || (false == m_pChildFrame->IsChildFrameActive())) return (sc = S_OK); // When child-frame is deactivated the menus are removed.
// Make sure the menu is currently attached.
if (m_AttachedMenuButtons.end() == m_AttachedMenuButtons.find(pMenuBtnNotifyClbk)) // This Menu Button is not attached.
return (sc = E_UNEXPECTED);
if ( (NULL == m_pMainFrame) || (NULL == m_pMenuBar) ) return (sc = E_UNEXPECTED);
MMC_MenuButtonCollection::iterator it = m_MenuButtons.begin(); while ( it != m_MenuButtons.end()) { if (it->pMenuButtonNotifyClbk == pMenuBtnNotifyClbk) { BOOL bRet = FALSE;
// Remove the menu button from Main Menu.
if (-1 != it->nCommandIDFromMenuBar) bRet = m_pMenuBar->DeleteMenuButton(it->nCommandIDFromMenuBar);
// The CMenubar removes all the menus when childframe is de-activated.
// So DeleteMenuButton will fail if the button does not exist.
// Therefore we do not check below error.
// if (FALSE == bRet)
// return (sc = E_FAIL);
// Delete the object in our data structure
it = m_MenuButtons.erase(it); } else ++it; }
// Delete the IMenuButton ref from the set.
m_AttachedMenuButtons.erase(pMenuBtnNotifyClbk);
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScToggleMenuButton
//
// Synopsis: Hide or Show the given menu buttons.
//
// Arguments:
// [bShow] - Show or Hide the menu buttons.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScToggleMenuButton(BOOL bShow) { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScToggleMenuButton"));
if ( (NULL == m_pChildFrame) || (false == m_pChildFrame->IsChildFrameActive()) || (NULL == m_pMenuBar) ) return (sc = E_UNEXPECTED);
// Go thro all the menu buttons added.
MMC_MenuButtonCollection::iterator it; for (it = m_MenuButtons.begin(); it != m_MenuButtons.end(); ++it) { BOOL bRetVal = TRUE; // Init to true so that failure (false) can be checked below.
// Toggle the menu hidden status. If the menu is
// un-hidden then check if it is allowed.
bRetVal = m_pMenuBar->HideButton(it->nCommandIDFromMenuBar, bShow ? !(it->CanShowMenu()) : TRUE);
if (FALSE == bRetVal) return (sc = E_FAIL); }
return (sc); }
//+-------------------------------------------------------------------
//
// Member: ScDisableMenuButtons
//
// Synopsis: Disable all the menubuttons.
//
// Arguments: None.
//
// Returns: SC
//
//--------------------------------------------------------------------
SC CMenuButtonsMgrImpl::ScDisableMenuButtons() { DECLARE_SC(sc, _T("CMenuButtonsMgrImpl::ScDisableMenuButtons"));
if ( (NULL == m_pChildFrame) || (false == m_pChildFrame->IsChildFrameActive()) || (NULL == m_pMenuBar) ) return (sc = E_UNEXPECTED);
// Go thro all the menu buttons added.
MMC_MenuButtonCollection::iterator it; for (it = m_MenuButtons.begin(); it != m_MenuButtons.end(); ++it) { if (m_pMenuBar->IsButtonEnabled(it->nCommandIDFromMenuBar)) { BOOL bRet = m_pMenuBar->EnableButton(it->nCommandIDFromMenuBar, false);
if (FALSE == bRet) return (sc = E_FAIL); } }
return (sc); }
//+-------------------------------------------------------------------
//
// Member: GetMMCMenuButton
//
// Synopsis: Given the Notify callback and button command id get the button
//
// Arguments:
// [pMenuBtnNotifyClbk] - Callback for Menu click.
// [idCommand] - Button command id.
//
// Returns: iterator to MMC_MenuButtonCollection
//
//--------------------------------------------------------------------
MMC_MenuButtonCollection::iterator CMenuButtonsMgrImpl::GetMMCMenuButton( CMenuButtonNotify* pMenuBtnNotifyClbk, INT idCommand) { MMC_MenuButtonCollection::iterator it; for (it = m_MenuButtons.begin(); it != m_MenuButtons.end(); ++it) { if ( (it->pMenuButtonNotifyClbk == pMenuBtnNotifyClbk) && (it->idCommand == idCommand) ) { return it; } }
return m_MenuButtons.end(); }
//+-------------------------------------------------------------------
//
// Member: GetMMCMenuButton
//
// Synopsis: Given the command id get the button
//
// Arguments:
// [nCommandID] - Command ID.
//
// Returns: iterator to MMC_MenuButtonCollection
//
//--------------------------------------------------------------------
MMC_MenuButtonCollection::iterator CMenuButtonsMgrImpl::GetMMCMenuButton( INT nCommandID) { MMC_MenuButtonCollection::iterator it; for (it = m_MenuButtons.begin(); it != m_MenuButtons.end(); ++it) { if ( it->nCommandIDFromMenuBar == nCommandID ) { return it; } }
return m_MenuButtons.end(); }
//+-------------------------------------------------------------------
//
// Member: IsAttached
//
// Synopsis: Given the notify callback, check if the MenuButtons
// object is attached or not.
//
// Arguments:
// [pMenuBtnNotifyClbk] - Notify callback.
//
// Returns: bool
//
//--------------------------------------------------------------------
bool CMenuButtonsMgrImpl::IsAttached( CMenuButtonNotify* pMenuBtnNotifyClbk) { MMC_AttachedMenuButtons::iterator it = m_AttachedMenuButtons.find(pMenuBtnNotifyClbk); if (m_AttachedMenuButtons.end() != it) return true;
return false; }
|