3371 lines
91 KiB
C++
3371 lines
91 KiB
C++
//____________________________________________________________________________
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: oncmenu.cpp
|
|
//
|
|
// Contents:
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 1/9/1997 RaviR Created
|
|
//____________________________________________________________________________
|
|
//
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "tasks.h"
|
|
#include "oncmenu.h"
|
|
#include <comcat.h> // COM Component Categories Manager
|
|
#include "compcat.h"
|
|
#include "guids.h"
|
|
#include "newnode.h"
|
|
#include "..\inc\amcmsgid.h"
|
|
#include "multisel.h"
|
|
#include "scopndcb.h"
|
|
#include "cmenuinfo.h"
|
|
#include "contree.h"
|
|
#include "conview.h"
|
|
#include "conframe.h"
|
|
#include "rsltitem.h"
|
|
#include "variant.h" // ConvertByRefVariantToByValue
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
// forward reference
|
|
class CConsoleStatusBar;
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Language-independent menu names. DO NOT CHANGE THESE!!
|
|
//
|
|
// the macro expands out to something like
|
|
// const LPCTSTR szCONTEXTHELP = TEXT("_CONTEXTHELP")
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
#define DECLARE_MENU_ITEM(_item) const LPCTSTR sz##_item = TEXT("_")TEXT(#_item);
|
|
|
|
DECLARE_MENU_ITEM(CONTEXTHELP)
|
|
DECLARE_MENU_ITEM(VIEW)
|
|
DECLARE_MENU_ITEM(CUSTOMIZE)
|
|
DECLARE_MENU_ITEM(COLUMNS)
|
|
DECLARE_MENU_ITEM(VIEW_LARGE)
|
|
DECLARE_MENU_ITEM(VIEW_SMALL)
|
|
DECLARE_MENU_ITEM(VIEW_LIST)
|
|
DECLARE_MENU_ITEM(VIEW_DETAIL)
|
|
DECLARE_MENU_ITEM(VIEW_FILTERED)
|
|
DECLARE_MENU_ITEM(ORGANIZE_FAVORITES)
|
|
DECLARE_MENU_ITEM(CUT)
|
|
DECLARE_MENU_ITEM(COPY)
|
|
DECLARE_MENU_ITEM(PASTE)
|
|
DECLARE_MENU_ITEM(DELETE)
|
|
DECLARE_MENU_ITEM(PRINT)
|
|
DECLARE_MENU_ITEM(RENAME)
|
|
DECLARE_MENU_ITEM(REFRESH)
|
|
DECLARE_MENU_ITEM(SAVE_LIST)
|
|
DECLARE_MENU_ITEM(PROPERTIES)
|
|
DECLARE_MENU_ITEM(OPEN)
|
|
DECLARE_MENU_ITEM(EXPLORE)
|
|
DECLARE_MENU_ITEM(NEW_TASKPAD_FROM_HERE)
|
|
DECLARE_MENU_ITEM(EDIT_TASKPAD)
|
|
DECLARE_MENU_ITEM(DELETE_TASKPAD)
|
|
DECLARE_MENU_ITEM(ARRANGE_ICONS)
|
|
DECLARE_MENU_ITEM(ARRANGE_AUTO)
|
|
DECLARE_MENU_ITEM(LINE_UP_ICONS)
|
|
DECLARE_MENU_ITEM(TASK)
|
|
DECLARE_MENU_ITEM(CREATE_NEW)
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Trace Tags
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
#ifdef DBG
|
|
CTraceTag tagOnCMenu(TEXT("OnCMenu"), TEXT("OnCMenu"));
|
|
#endif
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CCustomizeViewDialog
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
class CCustomizeViewDialog : public CDialogImpl<CCustomizeViewDialog>
|
|
{
|
|
typedef CCustomizeViewDialog ThisClass;
|
|
typedef CDialogImpl<CCustomizeViewDialog> BaseClass;
|
|
|
|
public:
|
|
// Operators
|
|
enum { IDD = IDD_CUSTOMIZE_VIEW };
|
|
CCustomizeViewDialog(CViewData *pViewData);
|
|
|
|
protected:
|
|
BEGIN_MSG_MAP(ThisClass)
|
|
MESSAGE_HANDLER (WM_INITDIALOG, OnInitDialog)
|
|
CONTEXT_HELP_HANDLER()
|
|
COMMAND_ID_HANDLER (IDOK, OnOK)
|
|
COMMAND_HANDLER (IDC_CUST_STD_MENUS, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_SNAPIN_MENUS, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_STD_BUTTONS, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_SNAPIN_BUTTONS, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_STATUS_BAR, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_DESC_BAR, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_CONSOLE_TREE, BN_CLICKED, OnClick)
|
|
COMMAND_HANDLER (IDC_CUST_TASKPAD_TABS, BN_CLICKED, OnClick)
|
|
END_MSG_MAP();
|
|
|
|
IMPLEMENT_CONTEXT_HELP(g_aHelpIDs_IDD_CUSTOMIZE_VIEW);
|
|
|
|
LRESULT OnInitDialog (UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
|
LRESULT OnOK (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
LRESULT OnCancel (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
LRESULT OnClick (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled);
|
|
|
|
|
|
bool PureIsDlgButtonChecked (int nIDButton) const
|
|
{ return (IsDlgButtonChecked(nIDButton) == BST_CHECKED); }
|
|
|
|
private:
|
|
CViewData * m_pViewData;
|
|
bool m_bStdMenus : 1;
|
|
bool m_bSnapinMenus : 1;
|
|
bool m_bStdButtons : 1;
|
|
bool m_bSnapinButtons : 1;
|
|
bool m_bStatusBar : 1;
|
|
bool m_bDescBar : 1;
|
|
bool m_bConsoleTree : 1;
|
|
bool m_bTaskpadTabs : 1;
|
|
};
|
|
|
|
CCustomizeViewDialog::CCustomizeViewDialog(CViewData *pViewData)
|
|
: m_pViewData(pViewData)
|
|
{
|
|
DWORD dwToolbarsDisplayed = pViewData->GetToolbarsDisplayed();
|
|
|
|
m_bStdMenus = dwToolbarsDisplayed & STD_MENUS;
|
|
m_bSnapinMenus = dwToolbarsDisplayed & SNAPIN_MENUS;
|
|
m_bStdButtons = dwToolbarsDisplayed & STD_BUTTONS;
|
|
m_bSnapinButtons = dwToolbarsDisplayed & SNAPIN_BUTTONS;
|
|
m_bStatusBar = pViewData->IsStatusBarVisible();
|
|
m_bDescBar = pViewData->IsDescBarVisible();
|
|
m_bConsoleTree = pViewData->IsScopePaneVisible();
|
|
m_bTaskpadTabs = pViewData->AreTaskpadTabsAllowed();
|
|
}
|
|
|
|
LRESULT
|
|
CCustomizeViewDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
|
{
|
|
/*
|
|
* Since these two values correspond to the possible values of a bool,
|
|
* we don't have to have an ugly conditional operator below, i.e.:
|
|
*
|
|
* CheckDlgButton (..., (m_bStdMenus) ? BST_CHECKED : BST_UNCHECKED);
|
|
*/
|
|
ASSERT (BST_CHECKED == true);
|
|
ASSERT (BST_UNCHECKED == false);
|
|
|
|
CheckDlgButton (IDC_CUST_SNAPIN_MENUS, m_bSnapinMenus);
|
|
CheckDlgButton (IDC_CUST_SNAPIN_BUTTONS, m_bSnapinButtons);
|
|
CheckDlgButton (IDC_CUST_STATUS_BAR, m_bStatusBar);
|
|
CheckDlgButton (IDC_CUST_DESC_BAR, m_bDescBar);
|
|
CheckDlgButton (IDC_CUST_TASKPAD_TABS, m_bTaskpadTabs);
|
|
|
|
// if snap-in has disabled standard menus and toolbars, don't
|
|
// allow user to enable them.
|
|
// (Note: NOTOOLBARS disables both menus and toolbars)
|
|
if (m_pViewData->GetWindowOptions() & MMC_NW_OPTION_NOTOOLBARS)
|
|
{
|
|
CheckDlgButton (IDC_CUST_STD_MENUS, false);
|
|
CheckDlgButton (IDC_CUST_STD_BUTTONS, false);
|
|
|
|
::EnableWindow (GetDlgItem(IDC_CUST_STD_MENUS), false);
|
|
::EnableWindow (GetDlgItem(IDC_CUST_STD_BUTTONS), false);
|
|
}
|
|
else
|
|
{
|
|
CheckDlgButton (IDC_CUST_STD_MENUS, m_bStdMenus);
|
|
CheckDlgButton (IDC_CUST_STD_BUTTONS, m_bStdButtons);
|
|
}
|
|
|
|
// if snap-in has disable the scope pane, then don't let user
|
|
// try to enable/disable scope tree access.
|
|
if (m_pViewData->GetWindowOptions() & MMC_NW_OPTION_NOSCOPEPANE)
|
|
{
|
|
CheckDlgButton (IDC_CUST_CONSOLE_TREE, false);
|
|
|
|
::EnableWindow (GetDlgItem(IDC_CUST_CONSOLE_TREE), false);
|
|
}
|
|
else
|
|
{
|
|
CheckDlgButton (IDC_CUST_CONSOLE_TREE, m_bConsoleTree);
|
|
}
|
|
|
|
// Disable/Remove the "Close"/"ALT+F4" from the dialog.
|
|
HMENU hSysMenu = GetSystemMenu(FALSE);
|
|
if (hSysMenu)
|
|
VERIFY(RemoveMenu(hSysMenu, SC_CLOSE, MF_BYCOMMAND));
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
LRESULT
|
|
CCustomizeViewDialog::OnClick (WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
|
{
|
|
CConsoleView* pConsoleView = m_pViewData->GetConsoleView();
|
|
ASSERT (pConsoleView != NULL);
|
|
|
|
switch (wID)
|
|
{
|
|
case IDC_CUST_STD_MENUS:
|
|
m_pViewData->ToggleToolbar(MID_STD_MENUS);
|
|
break;
|
|
|
|
case IDC_CUST_SNAPIN_MENUS:
|
|
m_pViewData->ToggleToolbar(MID_SNAPIN_MENUS);
|
|
break;
|
|
|
|
case IDC_CUST_STD_BUTTONS:
|
|
m_pViewData->ToggleToolbar(MID_STD_BUTTONS);
|
|
break;
|
|
|
|
case IDC_CUST_SNAPIN_BUTTONS:
|
|
m_pViewData->ToggleToolbar(MID_SNAPIN_BUTTONS);
|
|
break;
|
|
|
|
case IDC_CUST_STATUS_BAR:
|
|
if (pConsoleView != NULL)
|
|
pConsoleView->ScToggleStatusBar();
|
|
break;
|
|
|
|
case IDC_CUST_DESC_BAR:
|
|
if (pConsoleView != NULL)
|
|
pConsoleView->ScToggleDescriptionBar();
|
|
break;
|
|
|
|
case IDC_CUST_CONSOLE_TREE:
|
|
if (pConsoleView != NULL)
|
|
pConsoleView->ScToggleScopePane();
|
|
break;
|
|
|
|
case IDC_CUST_TASKPAD_TABS:
|
|
if (pConsoleView != NULL)
|
|
pConsoleView->ScToggleTaskpadTabs();
|
|
break;
|
|
}
|
|
|
|
return (0);
|
|
}
|
|
|
|
LRESULT
|
|
CCustomizeViewDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
|
|
{
|
|
EndDialog(IDOK);
|
|
return 0;
|
|
}
|
|
|
|
|
|
//############################################################################
|
|
//############################################################################
|
|
//
|
|
// Implementation of class CContextMenu
|
|
//
|
|
//############################################################################
|
|
//############################################################################
|
|
|
|
DEBUG_DECLARE_INSTANCE_COUNTER(CContextMenu);
|
|
|
|
CContextMenu::CContextMenu() :
|
|
m_pNode(NULL),
|
|
m_pNodeCallback(NULL),
|
|
m_pCScopeTree(NULL),
|
|
m_eDefaultVerb((MMC_CONSOLE_VERB)0),
|
|
m_lCommandIDMax(0),
|
|
m_pStatusBar(NULL),
|
|
m_pmenuitemRoot(NULL),
|
|
m_MaxPrimaryOwnerID(OWNERID_PRIMARY_MIN),
|
|
m_MaxThirdPartyOwnerID(OWNERID_THIRD_PARTY_MIN),
|
|
m_CurrentExtensionOwnerID(OWNERID_NATIVE),
|
|
m_nNextMenuItemID(MENUITEM_BASE_ID),
|
|
m_fPrimaryInsertionFlags(0),
|
|
m_fThirdPartyInsertionFlags(0),
|
|
m_fAddingPrimaryExtensionItems(false),
|
|
m_fAddedThirdPartyExtensions(false),
|
|
m_SnapinList(NULL)
|
|
{
|
|
DEBUG_INCREMENT_INSTANCE_COUNTER(CContextMenu);
|
|
|
|
// Fix!!
|
|
m_SnapinList = new SnapinStructList;
|
|
ASSERT(m_SnapinList);
|
|
}
|
|
|
|
SC
|
|
CContextMenu::ScInitialize(
|
|
CNode* pNode,
|
|
CNodeCallback* pNodeCallback,
|
|
CScopeTree* pCScopeTree,
|
|
const CContextMenuInfo& contextInfo)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScInitialize"));
|
|
|
|
m_pNode = pNode;
|
|
m_pNodeCallback = pNodeCallback;
|
|
m_pCScopeTree = pCScopeTree;
|
|
m_ContextInfo = contextInfo;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
CContextMenu::~CContextMenu()
|
|
{
|
|
EmptyMenuList();
|
|
|
|
ASSERT(m_SnapinList != NULL);
|
|
if (m_SnapinList != NULL)
|
|
{
|
|
#ifdef DBG
|
|
int const count = m_SnapinList->GetCount();
|
|
ASSERT( count == 0);
|
|
#endif
|
|
delete m_SnapinList;
|
|
}
|
|
|
|
|
|
DEBUG_DECREMENT_INSTANCE_COUNTER(CContextMenu);
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::SetStatusBar
|
|
*
|
|
* PURPOSE: Sets the status bar pointer.
|
|
*
|
|
* PARAMETERS:
|
|
* CConsoleStatusBar * pStatusBar :
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
void
|
|
CContextMenu::SetStatusBar(CConsoleStatusBar *pStatusBar)
|
|
{
|
|
if(NULL != pStatusBar)
|
|
m_pStatusBar = pStatusBar;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::GetStatusBar
|
|
*
|
|
* PURPOSE: Returns a pointer to the status bar to use when displaying the menu.
|
|
*
|
|
* RETURNS:
|
|
* CConsoleStatusBar *
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
CConsoleStatusBar *
|
|
CContextMenu::GetStatusBar()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::GetStatusBar"));
|
|
|
|
if(m_pStatusBar)
|
|
return m_pStatusBar;
|
|
|
|
if(m_pNode && m_pNode->GetViewData())
|
|
{
|
|
m_pStatusBar = m_pNode->GetViewData()->GetStatusBar();
|
|
return m_pStatusBar;
|
|
}
|
|
|
|
// last try, use the console view
|
|
if(m_ContextInfo.m_pConsoleView)
|
|
{
|
|
sc = m_ContextInfo.m_pConsoleView->ScGetStatusBar(&m_pStatusBar);
|
|
if(sc)
|
|
return NULL;
|
|
}
|
|
|
|
return m_pStatusBar;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScCreateInstance
|
|
*
|
|
* PURPOSE: Creates a new context menu instance.
|
|
*
|
|
* PARAMETERS:
|
|
* ContextMenu ** ppContextMenu : pointer to the ContextMenu interface on
|
|
* the instance. This maintains the lifetime.
|
|
*
|
|
* CContextMenu **ppCContextMenu : If non-null, returns the derived object pointer.
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScCreateInstance(ContextMenu **ppContextMenu, CContextMenu **ppCContextMenu)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScCreateInstance"));
|
|
|
|
sc = ScCheckPointers(ppContextMenu, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CComObject<CMMCNewEnumImpl<CContextMenu, CContextMenu::Position, CContextMenu> > *pContextMenu = NULL;
|
|
sc = pContextMenu->CreateInstance(&pContextMenu);
|
|
|
|
if(sc.IsError() || !pContextMenu)
|
|
return (sc = E_UNEXPECTED).ToHr();
|
|
|
|
*ppContextMenu = pContextMenu; // handles the lifetime.
|
|
(*ppContextMenu)->AddRef(); // addref for client.
|
|
|
|
if(ppCContextMenu != NULL)
|
|
*ppCContextMenu = pContextMenu;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScCreateContextMenu
|
|
*
|
|
* PURPOSE: Creates a context menu for the specified node.
|
|
*
|
|
* PARAMETERS:
|
|
* PNODE pNode :
|
|
* PPCONTEXTMENU ppContextMenu :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScCreateContextMenu( PNODE pNode, HNODE hNode, PPCONTEXTMENU ppContextMenu,
|
|
CNodeCallback *pNodeCallback, CScopeTree *pScopeTree)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScCreateContextMenu"));
|
|
|
|
CNode *pNodeTarget = CNode::FromHandle(hNode);
|
|
|
|
// validate parameters
|
|
sc = ScCheckPointers(pNode, pNodeTarget, ppContextMenu);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// init out parameter
|
|
*ppContextMenu = NULL;
|
|
|
|
BOOL bIsScopeNode = false;
|
|
|
|
sc = pNode->IsScopeNode(&bIsScopeNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if(!bIsScopeNode)
|
|
return (sc = E_NOTIMPL); // TODO: result items and multiselect items.
|
|
|
|
|
|
// create a context menu object initialized to the specified node.
|
|
CContextMenu *pContextMenu = NULL;
|
|
// not using upt parameter directly to avoid returning the object
|
|
// with an error result code. See bug 139528
|
|
// will assign at the end when we now that everything succeeded
|
|
ContextMenuPtr spContextMenu;
|
|
sc = CContextMenu::ScCreateContextMenuForScopeNode(pNodeTarget, pNodeCallback, pScopeTree,
|
|
&spContextMenu, pContextMenu);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = pContextMenu->ScBuildContextMenu();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// return the object
|
|
*ppContextMenu = spContextMenu.Detach();
|
|
|
|
return sc;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* METHOD: CContextMenu::ScCreateContextMenuForScopeNode
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CNode *pNode - [in] node on which the context menu will be created
|
|
* CNodeCallback *pNodeCallback - [in] node callback
|
|
* CScopeTree *pScopeTree - [in] scope tree
|
|
* PPCONTEXTMENU ppContextMenu - [out] context menu interface
|
|
* CContextMenu * &pContextMenu - [out] context menu raw pointer
|
|
*
|
|
* RETURNS:
|
|
* SC - result code
|
|
*
|
|
\***************************************************************************/
|
|
SC
|
|
CContextMenu::ScCreateContextMenuForScopeNode(CNode *pNode, CNodeCallback *pNodeCallback,
|
|
CScopeTree *pScopeTree,
|
|
PPCONTEXTMENU ppContextMenu,
|
|
CContextMenu * &pContextMenu)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScCreateContextMenuForScopeNode"));
|
|
|
|
// validate parameters
|
|
sc = ScCheckPointers(ppContextMenu);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CContextMenuInfo contextInfo;
|
|
|
|
// always use the temp verbs - cannot depend on what the active pane is
|
|
contextInfo.m_dwFlags = CMINFO_USE_TEMP_VERB;
|
|
|
|
bool fScopeItem = true;
|
|
|
|
// initialize the context info structure.
|
|
{
|
|
contextInfo.m_eContextMenuType = MMC_CONTEXT_MENU_DEFAULT;
|
|
contextInfo.m_eDataObjectType = fScopeItem ? CCT_SCOPE: CCT_RESULT;
|
|
contextInfo.m_bBackground = FALSE;
|
|
contextInfo.m_hSelectedScopeNode = NULL; //assigned below
|
|
contextInfo.m_resultItemParam = NULL; //resultItemParam;
|
|
contextInfo.m_bMultiSelect = FALSE; //(resultItemParam == LVDATA_MULTISELECT);
|
|
contextInfo.m_bScopeAllowed = fScopeItem;
|
|
contextInfo.m_dwFlags |= CMINFO_SHOW_SCOPEITEM_OPEN; // when called through the object model, always add the open item so that this can be accessed.
|
|
|
|
|
|
if ( pNode!= NULL )
|
|
{
|
|
|
|
CViewData *pViewData = pNode->GetViewData();
|
|
CConsoleView *pView = NULL;
|
|
if (NULL != pViewData && NULL != (pView = pViewData->GetConsoleView()))
|
|
{
|
|
// set the owner of the view
|
|
contextInfo.m_hSelectedScopeNode = pView->GetSelectedNode();
|
|
|
|
//if the scope node is also the owner of the view ,
|
|
// add more menu items
|
|
if (contextInfo.m_hSelectedScopeNode == CNode::ToHandle(pNode))
|
|
{
|
|
contextInfo.m_dwFlags |= CMINFO_SHOW_VIEWOWNER_ITEMS;
|
|
|
|
// show view items as well
|
|
contextInfo.m_dwFlags |= CMINFO_SHOW_VIEW_ITEMS;
|
|
|
|
//.. and if there is a list it can be saved
|
|
if ( NULL != pViewData->GetListCtrl() )
|
|
contextInfo.m_dwFlags |= CMINFO_SHOW_SAVE_LIST;
|
|
}
|
|
}
|
|
|
|
contextInfo.m_hWnd = pNode->GetViewData()->GetView();
|
|
contextInfo.m_pConsoleView = pNode->GetViewData()->GetConsoleView();
|
|
}
|
|
}
|
|
// create a context menu object initialized to the specified node.
|
|
sc = CContextMenu::ScCreateInstance(ppContextMenu, &pContextMenu);
|
|
if (sc)
|
|
return sc;
|
|
|
|
// recheck the pointer
|
|
sc = ScCheckPointers(pContextMenu, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
sc = pContextMenu->ScInitialize(pNode, pNodeCallback, pScopeTree, contextInfo);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScCreateSelectionContextMenu
|
|
*
|
|
* PURPOSE: Creates a context menu object for the selection in the list view.
|
|
*
|
|
* PARAMETERS:
|
|
* HNODE hNodeScope :
|
|
* CContextMenuInfo * pContextInfo :
|
|
* PPCONTEXTMENU ppContextMenu :
|
|
* CNodeCallback * pNodeCallback :
|
|
* CScopeTree * pScopeTree :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScCreateSelectionContextMenu( HNODE hNodeScope, const CContextMenuInfo *pContextInfo, PPCONTEXTMENU ppContextMenu,
|
|
CNodeCallback *pNodeCallback, CScopeTree *pScopeTree)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScCreateSelectionContextMenu"));
|
|
|
|
CNode *pNodeSel = CNode::FromHandle(hNodeScope);
|
|
|
|
// validate parameters
|
|
sc = ScCheckPointers(pNodeSel, ppContextMenu);
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
// create a context menu object initialized to the specified node.
|
|
CContextMenu *pContextMenu = NULL;
|
|
|
|
sc = CContextMenu::ScCreateInstance(ppContextMenu, &pContextMenu);
|
|
if(sc.IsError() || !pContextMenu)
|
|
{
|
|
return (sc = E_OUTOFMEMORY);
|
|
}
|
|
|
|
sc = pContextMenu->ScInitialize(pNodeSel, pNodeCallback, pScopeTree, *pContextInfo);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = pContextMenu->ScBuildContextMenu();
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
return sc;
|
|
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScGetItem
|
|
*
|
|
* PURPOSE: Returns the iItem'th menu item.
|
|
*
|
|
* PARAMETERS:
|
|
* int iItem : The zero-based item index.
|
|
* CMenuItem** ppMenuItem :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScGetItem(int iItem, CMenuItem** ppMenuItem)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScGetItem"));
|
|
|
|
sc = ScCheckPointers(ppMenuItem, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// init out param
|
|
*ppMenuItem = NULL;
|
|
|
|
sc = ScGetItem(GetMenuItemList(), iItem, ppMenuItem);
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScGetItem
|
|
*
|
|
* PURPOSE: Returns the nth item in the list of menu items, or NULL if
|
|
* there are insufficient items.
|
|
* Also returns the total count of items in the list.
|
|
*
|
|
* NOTE: This method allows the context menu to be traversed. Just call it
|
|
* with increasing iItem, for 0 <= iItem < count.
|
|
*
|
|
* NOTE: ScGetItemCount benefits from knowledge about implementation details
|
|
* of this function.
|
|
*
|
|
* PARAMETERS:
|
|
* MenuItemList * pMenuItemList : [in] The context menu to traverse.
|
|
* int & iItem : [in, destroyed on exit]: the (zero-based) item index
|
|
* CMenuItem** ppMenuItem : [out]: The iItem'th menu item.
|
|
*
|
|
* RETURNS:
|
|
* SC : S_OK for success, an error code for error.
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScGetItem(MenuItemList *pMenuItemList, int &iItem, CMenuItem** ppMenuItem)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScGetItem"));
|
|
|
|
sc = ScCheckPointers(pMenuItemList, ppMenuItem, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
*ppMenuItem = NULL;
|
|
|
|
POSITION position = pMenuItemList->GetHeadPosition(); // presumably we're already at the head position.
|
|
|
|
while(position!=NULL && *ppMenuItem == NULL)
|
|
{
|
|
CMenuItem* pMenuItem = pMenuItemList->GetNext(position);
|
|
|
|
if( (pMenuItem->IsSpecialSubmenu() || pMenuItem->IsPopupMenu() )
|
|
&& pMenuItem->HasChildList())
|
|
{
|
|
// recurse through the submenus
|
|
sc = ScGetItem( &pMenuItem->GetMenuItemSubmenu(), iItem, ppMenuItem );
|
|
if(sc)
|
|
return sc; // errors get reported right away.
|
|
}
|
|
else if( !pMenuItem->IsSpecialSeparator() && !pMenuItem->IsSpecialInsertionPoint()
|
|
&& !(pMenuItem->GetMenuItemFlags() & MF_SEPARATOR))
|
|
{
|
|
if(iItem-- == 0) // found the i'th item, but keep going to find the count of items.
|
|
*ppMenuItem = pMenuItem;
|
|
}
|
|
}
|
|
|
|
// either found one or iterated to the end ...
|
|
|
|
return sc;
|
|
}
|
|
|
|
/***************************************************************************\
|
|
*
|
|
* METHOD: CContextMenu::ScGetItemCount
|
|
*
|
|
* PURPOSE: Counts menu items by iterating thu them
|
|
*
|
|
* NOTE: benefits from knowledge about implementation details of ScGetItem
|
|
*
|
|
* PARAMETERS:
|
|
* UINT &count
|
|
*
|
|
* RETURNS:
|
|
* SC - result code
|
|
*
|
|
\***************************************************************************/
|
|
SC
|
|
CContextMenu::ScGetItemCount(UINT &count)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScGetItemCount"));
|
|
|
|
count = 0;
|
|
|
|
// set iItem to invalid index - so ScGetItem will iterate to the end
|
|
const int iInvalidIndexToSearch = -1;
|
|
int iItem = iInvalidIndexToSearch;
|
|
|
|
CMenuItem * pMenuItem = NULL;
|
|
sc = ScGetItem(GetMenuItemList(), iItem, &pMenuItem);
|
|
if(sc)
|
|
return sc;
|
|
|
|
ASSERT( pMenuItem == NULL); // we do not expect it to be found!
|
|
|
|
// since iItem was decremented for each element - we can easily
|
|
// calculate how many items we've got
|
|
|
|
count = -(iItem - iInvalidIndexToSearch);
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScEnumNext
|
|
*
|
|
* PURPOSE: Returns a pointer to the next menu item
|
|
*
|
|
* PARAMETERS:
|
|
* Position & pos :
|
|
* PDISPATCH & pDispatch :
|
|
*
|
|
* RETURNS:
|
|
* ::SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
::SC
|
|
CContextMenu::ScEnumNext(Position &pos, PDISPATCH & pDispatch)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScEnumNext"));
|
|
|
|
// initialize out parameter
|
|
pDispatch = NULL;
|
|
|
|
long cnt = 0;
|
|
sc = get_Count(&cnt);
|
|
if (sc)
|
|
return sc;
|
|
|
|
// false if no more items
|
|
if (cnt <= pos)
|
|
return sc = S_FALSE;
|
|
|
|
MenuItem *pMenuItem = NULL; // deliberately not a smart pointer.
|
|
sc = get_Item(CComVariant((int)pos+1) /*convert from zero-based to one-based*/, &pMenuItem);
|
|
if(sc.IsError() || sc == ::SC(S_FALSE))
|
|
return sc; // failed of no with such an index items (S_FALSE)
|
|
|
|
// increment position
|
|
pos++;
|
|
|
|
pDispatch = pMenuItem; //retains the refcount.
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScEnumSkip
|
|
*
|
|
* PURPOSE: Skips the specified number of menu items.
|
|
*
|
|
* PARAMETERS:
|
|
* unsigned long :
|
|
* unsigned long :
|
|
* Position & pos :
|
|
*
|
|
* RETURNS:
|
|
* ::SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
::SC
|
|
CContextMenu::ScEnumSkip(unsigned long celt, unsigned long& celtSkipped, Position &pos)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScEnumSkip"));
|
|
|
|
long count = 0;
|
|
|
|
sc = get_Count(&count);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if(count <= pos + celt) // could not skip as many as needed
|
|
{
|
|
celtSkipped = count - celt - 1;
|
|
pos = count; // one past the end.
|
|
return (sc = S_FALSE);
|
|
}
|
|
else // could skip as many as needed.
|
|
{
|
|
celtSkipped = celt;
|
|
pos += celt;
|
|
|
|
return sc;
|
|
}
|
|
}
|
|
|
|
::SC
|
|
CContextMenu::ScEnumReset(Position &pos)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScEnumReset"));
|
|
|
|
pos = 0;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::get_Count
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* PLONG pCount :
|
|
*
|
|
* RETURNS:
|
|
* STDMETHODIMP
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CContextMenu::get_Count(PLONG pCount)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CMMCContextMenu::get_Count"));
|
|
|
|
sc = ScCheckPointers(pCount);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
// init out param
|
|
*pCount = 0;
|
|
|
|
UINT count = 0;
|
|
sc = ScGetItemCount(count);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
*pCount = count;
|
|
|
|
return sc.ToHr();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::get_Item
|
|
*
|
|
* PURPOSE: Returns the menu item specified by the index.
|
|
*
|
|
* PARAMETERS:
|
|
* long Index : The one-based index of the menu item to return.
|
|
* PPMENUITEM ppMenuItem :
|
|
*
|
|
* RETURNS:
|
|
* STDMETHODIMP
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
STDMETHODIMP
|
|
CContextMenu::get_Item(VARIANT IndexOrName, PPMENUITEM ppMenuItem)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CMMCContextMenu::get_Item"));
|
|
|
|
sc = ScCheckPointers(ppMenuItem);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
// init out param
|
|
*ppMenuItem = NULL;
|
|
|
|
VARIANT* pvarTemp = ConvertByRefVariantToByValue(&IndexOrName);
|
|
sc = ScCheckPointers( pvarTemp, E_UNEXPECTED );
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
bool bByReference = ( 0 != (V_VT(pvarTemp) & VT_BYREF) ); // value passed by reference
|
|
UINT uiVarType = (V_VT(pvarTemp) & VT_TYPEMASK); // get variable type (strip flags)
|
|
|
|
CMenuItem * pMenuItem = NULL;
|
|
|
|
// compute the one-based index of the item
|
|
if (uiVarType == VT_I4) // int type in C++; Long type in VB
|
|
{
|
|
// index: get I4 properly ( see if it's a reference )
|
|
UINT uiIndex = bByReference ? *(pvarTemp->plVal) : pvarTemp->lVal;
|
|
|
|
// find menu item by index
|
|
sc = ScGetItem(uiIndex -1 /* convert from one-based to zero-based */, &pMenuItem);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if (uiVarType == VT_I2) // short type in C++; Integer type in VB
|
|
{
|
|
// index: get I2 properly ( see if it's a reference )
|
|
UINT uiIndex = bByReference ? *(pvarTemp->piVal) : pvarTemp->iVal;
|
|
|
|
// find menu item by index
|
|
sc = ScGetItem(uiIndex -1 /* convert from one-based to zero-based */, &pMenuItem);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if (uiVarType == VT_BSTR) // BSTR type in C++; String type in VB
|
|
{
|
|
// Name: get string properly ( see if it's a reference )
|
|
LPOLESTR lpstrPath = bByReference ? *(pvarTemp->pbstrVal) : pvarTemp->bstrVal;
|
|
|
|
// look for subitem of root menu item
|
|
if (m_pmenuitemRoot)
|
|
{
|
|
USES_CONVERSION;
|
|
// convert to string. Avoid NULL pointer (change to empty string)
|
|
LPCTSTR lpctstrPath = lpstrPath ? OLE2CT(lpstrPath) : _T("");
|
|
// find menu item by path
|
|
pMenuItem = m_pmenuitemRoot->FindItemByPath( lpctstrPath );
|
|
}
|
|
}
|
|
else // something we did not expect
|
|
{
|
|
// we expect either index (VT_I2 , VT_I4) or path (VT_BSTR) only
|
|
// anything else is treatead as invalid agument
|
|
return (sc = E_INVALIDARG).ToHr();
|
|
}
|
|
|
|
if(!pMenuItem) // did not find it - return null
|
|
{
|
|
*ppMenuItem = NULL;
|
|
return (sc = S_FALSE).ToHr();
|
|
}
|
|
|
|
// construct com object
|
|
sc = pMenuItem->ScGetMenuItem(ppMenuItem);
|
|
|
|
return sc.ToHr();
|
|
}
|
|
|
|
|
|
|
|
HRESULT CContextMenu::CreateContextMenuProvider()
|
|
{
|
|
if (PContextInfo()->m_bBackground == TRUE &&
|
|
PContextInfo()->m_eDataObjectType == CCT_SCOPE)
|
|
return S_OK;
|
|
|
|
ASSERT(m_pNode != NULL);
|
|
if (m_pNode == NULL)
|
|
return E_FAIL;
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
do // not a loop
|
|
{
|
|
//
|
|
// Use the standard verb present for this view.
|
|
//
|
|
|
|
if (!(PContextInfo()->m_dwFlags & CMINFO_USE_TEMP_VERB))
|
|
{
|
|
m_spVerbSet = m_pNode->GetViewData()->GetVerbSet();
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Create a temporary Standard verb ..
|
|
//
|
|
|
|
// .. for a scope item
|
|
if (PContextInfo()->m_eDataObjectType == CCT_SCOPE)
|
|
{
|
|
hr = CreateTempVerbSet(true);
|
|
break;
|
|
}
|
|
|
|
// .. for a list item
|
|
if (!IS_SPECIAL_LVDATA(PContextInfo()->m_resultItemParam))
|
|
{
|
|
hr = CreateTempVerbSet(false);
|
|
break;
|
|
}
|
|
|
|
// .. for a multi-sel in list view
|
|
if (PContextInfo()->m_resultItemParam == LVDATA_MULTISELECT)
|
|
{
|
|
hr = CreateTempVerbSetForMultiSel();
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(0);
|
|
hr = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
} while (0);
|
|
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
|
|
m_spVerbSet->GetDefaultVerb(&m_eDefaultVerb);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddInsertionPoint
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* long lCommandID :
|
|
* long lInsertionPointID :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddInsertionPoint(long lCommandID, long lInsertionPointID /*= CCM_INSERTIONPOINTID_ROOT_MENU*/)
|
|
{
|
|
SC sc;
|
|
CONTEXTMENUITEM contextmenuitem;
|
|
|
|
::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
|
|
contextmenuitem.strName = NULL;
|
|
contextmenuitem.strStatusBarText = NULL;
|
|
contextmenuitem.lCommandID = lCommandID;
|
|
contextmenuitem.lInsertionPointID = lInsertionPointID;
|
|
contextmenuitem.fFlags = 0;
|
|
contextmenuitem.fSpecialFlags = CCM_SPECIAL_INSERTION_POINT;
|
|
|
|
sc = AddItem(&contextmenuitem);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
Cleanup:
|
|
return sc;
|
|
Error:
|
|
TraceError(TEXT("CContextMenu::ScAddInsertionPoint"), sc);
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddSeparator
|
|
*
|
|
* PURPOSE: Adds a separator to the context menu
|
|
*
|
|
* PARAMETERS:
|
|
* long lInsertionPointID :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddSeparator(long lInsertionPointID /* = CCM_INSERTIONPOINTID_ROOT_MENU */)
|
|
{
|
|
SC sc;
|
|
CONTEXTMENUITEM contextmenuitem;
|
|
|
|
::ZeroMemory( &contextmenuitem, sizeof(contextmenuitem) );
|
|
contextmenuitem.strName = NULL;
|
|
contextmenuitem.strStatusBarText = NULL;
|
|
contextmenuitem.lCommandID = 0;
|
|
contextmenuitem.lInsertionPointID = lInsertionPointID;
|
|
contextmenuitem.fFlags = MF_SEPARATOR;
|
|
contextmenuitem.fSpecialFlags = CCM_SPECIAL_SEPARATOR;
|
|
|
|
sc = AddItem( &contextmenuitem);
|
|
if(sc)
|
|
goto Error;
|
|
|
|
Cleanup:
|
|
return sc;
|
|
Error:
|
|
TraceError(TEXT("CContextMenu::ScAddSeparator"), sc);
|
|
goto Cleanup;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItem
|
|
*
|
|
* PURPOSE: Adds a menu item to the context menu.
|
|
*
|
|
* PARAMETERS:
|
|
* UINT nResourceID : contains text and status text separated by '\n'
|
|
* long lCommandID : the ID used to notify the IExtendContextMenu when an item is selected
|
|
* long lInsertionPointID : the location to insert the item
|
|
* long fFlags :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItem(
|
|
UINT nResourceID, // contains text and status text separated by '\n'
|
|
LPCTSTR szLanguageIndependentName,
|
|
long lCommandID,
|
|
long lInsertionPointID /* = CCM_INSERTIONPOINTID_ROOT_MENU */,
|
|
long fFlags /* = 0 */)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItem"));
|
|
|
|
sc = ScCheckPointers(szLanguageIndependentName, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
USES_CONVERSION;
|
|
|
|
HINSTANCE hInst = GetStringModule();
|
|
CONTEXTMENUITEM2 contextmenuitem2;
|
|
|
|
// load the resource
|
|
CStr strText;
|
|
strText.LoadString(hInst, nResourceID );
|
|
ASSERT( !strText.IsEmpty() );
|
|
|
|
// split the resource into the menu text and status text
|
|
CStr strStatusText;
|
|
int iSeparator = strText.Find(_T('\n'));
|
|
if (0 > iSeparator)
|
|
{
|
|
ASSERT( FALSE );
|
|
strStatusText = strText;
|
|
}
|
|
else
|
|
{
|
|
strStatusText = strText.Right( strText.GetLength()-(iSeparator+1) );
|
|
strText = strText.Left( iSeparator );
|
|
}
|
|
|
|
// add the menu item
|
|
::ZeroMemory( &contextmenuitem2, sizeof(contextmenuitem2) );
|
|
contextmenuitem2.strName = T2OLE(const_cast<LPTSTR>((LPCTSTR)strText));
|
|
contextmenuitem2.strLanguageIndependentName = T2OLE(const_cast<LPTSTR>(szLanguageIndependentName));
|
|
contextmenuitem2.strStatusBarText = T2OLE(const_cast<LPTSTR>((LPCTSTR)strStatusText));
|
|
contextmenuitem2.lCommandID = lCommandID;
|
|
contextmenuitem2.lInsertionPointID = lInsertionPointID;
|
|
contextmenuitem2.fFlags = fFlags;
|
|
contextmenuitem2.fSpecialFlags = ((fFlags & MF_POPUP) ? CCM_SPECIAL_SUBMENU : 0L) |
|
|
((fFlags & MF_DEFAULT) ? CCM_SPECIAL_DEFAULT_ITEM : 0L);
|
|
|
|
sc = AddItem(&contextmenuitem2);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CContextMenu::CreateTempVerbSetForMultiSel(void)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::CreateTempVerbSetForMultiSel"));
|
|
sc = ScCheckPointers(m_pNode, m_pNodeCallback, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
// set standard bars
|
|
CComObject<CTemporaryVerbSet>* pVerbSet;
|
|
sc = CComObject<CTemporaryVerbSet>::CreateInstance(&pVerbSet);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
sc = ScCheckPointers(pVerbSet, E_OUTOFMEMORY);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
m_spVerbSet = pVerbSet;
|
|
|
|
sc = m_pNodeCallback->ScInitializeTempVerbSetForMultiSel(m_pNode, *pVerbSet);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
return sc.ToHr();
|
|
}
|
|
|
|
|
|
/* CContextMenu::CreateTempVerbSet
|
|
*
|
|
* PURPOSE: Used to create a temporary CVerbSet
|
|
*
|
|
* PARAMETERS:
|
|
* bool bForScopeItem:
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
*/
|
|
HRESULT CContextMenu::CreateTempVerbSet(bool bForScopeItem)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::CreateTempVerbSet"));
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
// ensure component is initialized !!!
|
|
// for instance task wizard will call this for static nodes which aren't expanded yet
|
|
// Does not hurt to check anyway - better safe than sorry
|
|
sc = m_pNode->InitComponents ();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
CComponent* pCC = m_pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pCC, E_FAIL);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
sc = pCC->ScResetConsoleVerbStates();
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
CComObject<CTemporaryVerbSet>* pVerb;
|
|
sc = CComObject<CTemporaryVerbSet>::CreateInstance(&pVerb);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
sc = ScCheckPointers(pVerb, E_OUTOFMEMORY);
|
|
if (sc)
|
|
return sc.ToHr();
|
|
|
|
sc = pVerb->ScInitialize(m_pNode, PContextInfo()->m_resultItemParam, bForScopeItem);
|
|
if (sc)
|
|
{
|
|
delete pVerb;
|
|
return sc.ToHr();
|
|
}
|
|
|
|
m_spVerbSet = pVerb;
|
|
|
|
return sc.ToHr();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::AddMenuItems
|
|
*
|
|
* PURPOSE: Adds all menu items into the menu.
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CContextMenu::AddMenuItems()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::AddMenuItems"));
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
// Add menu items
|
|
|
|
if (PContextInfo()->m_eContextMenuType == MMC_CONTEXT_MENU_VIEW)
|
|
{
|
|
sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_TOP);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if (PContextInfo()->m_dwFlags & CMINFO_FAVORITES_MENU)
|
|
{
|
|
sc = ScAddMenuItemsforFavorites();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if (PContextInfo()->m_bBackground == TRUE)
|
|
{
|
|
if (PContextInfo()->m_eDataObjectType != CCT_SCOPE)
|
|
{
|
|
sc = ScAddMenuItemsForLVBackgnd();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (PContextInfo()->m_eDataObjectType == CCT_SCOPE)
|
|
{
|
|
sc = ScAddMenuItemsForTreeItem();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if ( m_pNode && (PContextInfo()->m_eDataObjectType == CCT_RESULT) &&
|
|
(m_pNode->GetViewData()->HasOCX()) )
|
|
{
|
|
// Selection is an OCX
|
|
sc = ScAddMenuItemsForOCX();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else if ( m_pNode && (PContextInfo()->m_eDataObjectType == CCT_RESULT) &&
|
|
(m_pNode->GetViewData()->HasWebBrowser()) )
|
|
{
|
|
// do nothing for web pages.
|
|
}
|
|
else if (PContextInfo()->m_bMultiSelect == FALSE)
|
|
{
|
|
sc = ScAddMenuItemsForLV();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
else
|
|
{
|
|
sc = ScAddMenuItemsForMultiSelect();
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
}
|
|
|
|
// Add "Help" to every context menu except the view menu
|
|
if (PContextInfo()->m_eContextMenuType != MMC_CONTEXT_MENU_VIEW)
|
|
{
|
|
sc = ScAddSeparator(); // make sure there is a separator.
|
|
if(sc)
|
|
return sc.ToHr();
|
|
|
|
sc = ScAddMenuItem (IDS_MMC_CONTEXTHELP, szCONTEXTHELP, MID_CONTEXTHELP);
|
|
if(sc)
|
|
return sc.ToHr();
|
|
}
|
|
|
|
|
|
return sc.ToHr();
|
|
}
|
|
|
|
|
|
void
|
|
CContextMenu::RemoveTempSelection (CConsoleTree* pConsoleTree)
|
|
{
|
|
if (pConsoleTree != NULL)
|
|
pConsoleTree->ScRemoveTempSelection ();
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CContextMenu::Display
|
|
*
|
|
* PURPOSE: Creates the context menu tree, and shows it, if needed.
|
|
*
|
|
* PARAMETERS:
|
|
* BOOL b: FALSE: (Normal): Display the context menu
|
|
* TRUE: Don't show the context menu
|
|
*
|
|
* RETURNS:
|
|
* HRESULT
|
|
/*+-------------------------------------------------------------------------*/
|
|
HRESULT
|
|
CContextMenu::Display(BOOL b)
|
|
{
|
|
TRACE_METHOD(CContextMenu, Display);
|
|
HRESULT hr = S_OK;
|
|
|
|
// b == 0 => normal
|
|
// b == TRUE => don't show context menu
|
|
|
|
// Validate menu type
|
|
if (PContextInfo()->m_eContextMenuType >= MMC_CONTEXT_MENU_LAST)
|
|
{
|
|
ASSERT(FALSE);
|
|
return S_FALSE;
|
|
}
|
|
|
|
|
|
// Display a context menu for the scope or result side
|
|
if (PContextInfo()->m_eDataObjectType != CCT_SCOPE &&
|
|
PContextInfo()->m_eDataObjectType != CCT_RESULT)
|
|
{
|
|
ASSERT(FALSE);
|
|
return S_FALSE;
|
|
}
|
|
|
|
hr = CreateContextMenuProvider();
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = AddMenuItems();
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
// Display the context menu
|
|
long lSelected = 0; // 0 means no selection
|
|
hr = ShowContextMenuEx(PContextInfo()->m_hWnd,
|
|
PContextInfo()->m_displayPoint.x,
|
|
PContextInfo()->m_displayPoint.y,
|
|
&PContextInfo()->m_rectExclude,
|
|
PContextInfo()->m_bAllowDefaultItem,
|
|
&lSelected);
|
|
|
|
|
|
TRACE(_T("hr = %X, Command %ld\n"), hr, lSelected);
|
|
|
|
RemoveTempSelection (PContextInfo()->m_pConsoleTree); // remove the temporary selection, if any.
|
|
|
|
return hr;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScBuildContextMenu
|
|
*
|
|
* PURPOSE: Builds the context menu.
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScBuildContextMenu()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScBuildContextMenu"));
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Validate menu type
|
|
if (PContextInfo()->m_eContextMenuType >= MMC_CONTEXT_MENU_LAST)
|
|
return (sc = S_FALSE);
|
|
|
|
|
|
// Display a context menu for the scope or result side
|
|
if (PContextInfo()->m_eDataObjectType != CCT_SCOPE &&
|
|
PContextInfo()->m_eDataObjectType != CCT_RESULT)
|
|
return (sc = S_FALSE);
|
|
|
|
sc = CreateContextMenuProvider();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddMenuItems();
|
|
if(sc)
|
|
return sc;
|
|
|
|
CConsoleTree* pConsoleTree = PContextInfo()->m_pConsoleTree; // get this value BEFORE calling BuildAndTraverseCOntextMenu.
|
|
|
|
WTL::CMenu menu;
|
|
VERIFY( menu.CreatePopupMenu() );
|
|
|
|
START_CRITSEC_BOTH;
|
|
|
|
if (NULL == m_pmenuitemRoot)
|
|
return S_OK;
|
|
|
|
sc = BuildContextMenu(menu); // build the context menu
|
|
if(sc)
|
|
return sc;
|
|
|
|
END_CRITSEC_BOTH;
|
|
|
|
/* NOTE: Do NOT use the "this" object or any of its members after this point
|
|
* because it might have been deleted. This happens, for instance, when a selection
|
|
* change occurs.
|
|
*/
|
|
|
|
// remove the temporary selection, if any.
|
|
RemoveTempSelection (pConsoleTree);
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
inline BOOL CContextMenu::IsVerbEnabled(MMC_CONSOLE_VERB verb)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::IsVerbEnabled"));
|
|
|
|
if (verb == MMC_VERB_PASTE)
|
|
{
|
|
ASSERT(m_pNode);
|
|
ASSERT(m_pNodeCallback);
|
|
if (m_pNode == NULL || m_pNodeCallback == NULL)
|
|
return false;
|
|
|
|
bool bPasteAllowed = false;
|
|
// From given context determine whether scope pane or result pane item is selected.
|
|
bool bScope = ( m_ContextInfo.m_bBackground || (m_ContextInfo.m_eDataObjectType == CCT_SCOPE));
|
|
LPARAM lvData = bScope ? NULL : m_ContextInfo.m_resultItemParam;
|
|
|
|
sc = m_pNodeCallback->QueryPasteFromClipboard(CNode::ToHandle(m_pNode), bScope, lvData, bPasteAllowed);
|
|
if (sc)
|
|
return (bPasteAllowed = false);
|
|
|
|
return bPasteAllowed;
|
|
}
|
|
else
|
|
{
|
|
ASSERT(m_spVerbSet != NULL);
|
|
if (m_spVerbSet == NULL)
|
|
return FALSE;
|
|
|
|
BOOL bFlag = FALSE;
|
|
m_spVerbSet->GetVerbState(verb, HIDDEN, &bFlag);
|
|
if (bFlag == TRUE)
|
|
return FALSE;
|
|
|
|
m_spVerbSet->GetVerbState(verb, ENABLED, &bFlag);
|
|
return bFlag;
|
|
}
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForViewMenu
|
|
*
|
|
* PURPOSE: Adds the menu items for the View menu
|
|
*
|
|
* PARAMETERS:
|
|
* MENU_LEVEL menuLevel :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForViewMenu(MENU_LEVEL menuLevel)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::AddMenuItemsForViewMenu"));
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CViewData* pViewData = m_pNode->GetViewData();
|
|
|
|
sc = ScCheckPointers(pViewData, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
ASSERT(pViewData != NULL);
|
|
|
|
LONG lInsertID = 0;
|
|
|
|
int nViewMode = -1;
|
|
|
|
if (PContextInfo()->m_spListView)
|
|
nViewMode = PContextInfo()->m_spListView->GetViewMode();
|
|
|
|
// If no a top level menu, insert the view submenu item
|
|
// and insert view items under it
|
|
if (menuLevel == MENU_LEVEL_SUB)
|
|
{
|
|
sc = ScAddMenuItem(IDS_VIEW, szVIEW, MID_VIEW, 0, MF_POPUP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
lInsertID = MID_VIEW;
|
|
}
|
|
|
|
// Add cols only if it is List View in report or filtered mode.
|
|
if ((m_pNode->GetViewData() ) &&
|
|
(m_pNode->GetViewData()->GetListCtrl() ) &&
|
|
( (nViewMode == MMCLV_VIEWSTYLE_REPORT) ||
|
|
(nViewMode == MMCLV_VIEWSTYLE_FILTERED) ) )
|
|
{
|
|
sc = ScAddMenuItem(IDS_COLUMNS, szCOLUMNS, MID_COLUMNS, lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScAddSeparator( lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
|
|
DWORD dwListOptions = pViewData->GetListOptions();
|
|
DWORD dwMiscOptions = pViewData->GetMiscOptions();
|
|
|
|
// If allowed, insert the standard listview choices
|
|
if (!(dwMiscOptions & RVTI_MISC_OPTIONS_NOLISTVIEWS))
|
|
{
|
|
#define STYLECHECK(Mode) ((Mode == nViewMode) ? MF_CHECKED|MFT_RADIOCHECK : 0)
|
|
|
|
|
|
sc = ScAddMenuItem(IDS_VIEW_LARGE, szVIEW_LARGE, MID_VIEW_LARGE, lInsertID, STYLECHECK(LVS_ICON));
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem(IDS_VIEW_SMALL, szVIEW_SMALL, MID_VIEW_SMALL, lInsertID, STYLECHECK(LVS_SMALLICON));
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem(IDS_VIEW_LIST, szVIEW_LIST, MID_VIEW_LIST, lInsertID, STYLECHECK(LVS_LIST));
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem(IDS_VIEW_DETAIL, szVIEW_DETAIL, MID_VIEW_DETAIL, lInsertID, STYLECHECK(LVS_REPORT));
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (dwListOptions & RVTI_LIST_OPTIONS_FILTERED)
|
|
{
|
|
sc = ScAddMenuItem(IDS_VIEW_FILTERED, szVIEW_FILTERED, MID_VIEW_FILTERED, lInsertID, STYLECHECK(MMCLV_VIEWSTYLE_FILTERED));
|
|
if(sc)
|
|
return sc;
|
|
|
|
}
|
|
|
|
sc = ScAddSeparator( lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
// Ask IComponent to insert view items
|
|
if (m_spIDataObject == NULL)
|
|
{
|
|
sc = ScCheckPointers (m_pNode->GetMTNode(), E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
sc = m_pNode->GetMTNode()->QueryDataObject(CCT_SCOPE, &m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScCheckPointers(m_spIDataObject, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CComponent* pCC = m_pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pCC, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IUnknownPtr spUnknown = pCC->GetIComponent();
|
|
sc = ScCheckPointers(spUnknown);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add insertion point for primary custom views
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_VIEW, lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (pViewData->AllowViewCustomization())
|
|
{
|
|
// "Customize" menu item
|
|
sc = ScAddSeparator( lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem( IDS_CUSTOMIZE, szCUSTOMIZE, MID_CUSTOMIZE, lInsertID);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsforFavorites
|
|
*
|
|
* PURPOSE: Adds items for the Favorites menu
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsforFavorites()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsforFavorites"));
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CViewData* pViewData = m_pNode->GetViewData();
|
|
sc = ScCheckPointers(pViewData, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (pViewData->IsAuthorMode())
|
|
{
|
|
sc = ScAddMenuItem( IDS_ORGANIZEFAVORITES, szORGANIZE_FAVORITES, MID_ORGANIZE_FAVORITES);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForVerbSets
|
|
*
|
|
* PURPOSE: Adds the built-in menu items for the verbs
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForVerbSets()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForVerbSets"));
|
|
|
|
// Add print menu item
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
if (IsVerbEnabled(MMC_VERB_CUT) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_CUT, szCUT, MID_CUT);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_COPY) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_COPY, szCOPY, MID_COPY);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_PASTE) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_PASTE, szPASTE, MID_PASTE);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_DELETE) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_DELETE, szDELETE, MID_DELETE);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_PRINT) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_PRINT, szPRINT, MID_PRINT);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_RENAME) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_RENAME, szRENAME, MID_RENAME);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_REFRESH) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_REFRESH, szREFRESH, MID_REFRESH);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
// NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB
|
|
|
|
// In the verb add command because it is diaplayed next to the verbs
|
|
|
|
// Send a message to the list asking if it has anything on it.
|
|
// If so, display the 'save list' item
|
|
|
|
if (PContextInfo()->m_dwFlags & CMINFO_SHOW_SAVE_LIST)
|
|
{
|
|
sc = ScAddMenuItem( IDS_SAVE_LIST, szSAVE_LIST, MID_LISTSAVE);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
// NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB | NOT A VERB
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Ask the node whether it will put up property pages. If so add the
|
|
// "Properties" menu item
|
|
if (IsVerbEnabled(MMC_VERB_PROPERTIES) == TRUE)
|
|
{
|
|
// Do not make properties bold for scope items.
|
|
bool bScopeItemInScopePane = (CMINFO_DO_SCOPEPANE_MENU & m_ContextInfo.m_dwFlags);
|
|
bool bEnablePropertiesAsDefaultMenu = ( (m_eDefaultVerb == MMC_VERB_PROPERTIES) && (! bScopeItemInScopePane) );
|
|
|
|
sc = ScAddMenuItem( IDS_PROPERTIES, szPROPERTIES, MID_PROPERTIES, 0,
|
|
bEnablePropertiesAsDefaultMenu ? MF_DEFAULT : 0);
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForTreeItem
|
|
*
|
|
* PURPOSE: Adds menu items for a scope node in the tree
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForTreeItem()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForTreeItem"));
|
|
|
|
sc = ScCheckPointers(m_pNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CMTNode* pMTNode = m_pNode->GetMTNode();
|
|
CViewData* pViewData = m_pNode->GetViewData();
|
|
|
|
sc = ScCheckPointers(pMTNode, pViewData);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Show Open item if enabled or forced by caller
|
|
if ( IsVerbEnabled(MMC_VERB_OPEN) == TRUE ||
|
|
PContextInfo()->m_dwFlags & CMINFO_SHOW_SCOPEITEM_OPEN )
|
|
{
|
|
sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0,
|
|
(m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add "Create New" menu item
|
|
sc = ScAddSubmenu_CreateNew(m_pNode->IsStaticNode());
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add "Task" menu item
|
|
sc = ScAddSubmenu_Task();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Show the view menu
|
|
if (PContextInfo()->m_dwFlags & CMINFO_SHOW_VIEW_ITEMS)
|
|
{
|
|
sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_SUB);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
// New window is allowed only if the view allows customization and
|
|
// it is not SDI user mode.
|
|
if (m_pNode->AllowNewWindowFromHere() && !pViewData->IsUser_SDIMode())
|
|
ScAddMenuItem( IDS_EXPLORE, szEXPLORE, MID_EXPLORE);
|
|
|
|
|
|
// Taskpad editing only allowed in author mode and for node that owns the view
|
|
if (pViewData->IsAuthorMode() && (PContextInfo()->m_dwFlags & CMINFO_SHOW_VIEWOWNER_ITEMS))
|
|
{
|
|
// add the "New Taskpad..." menu item
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem( IDS_NEW_TASKPAD_FROM_HERE, szNEW_TASKPAD_FROM_HERE,
|
|
MID_NEW_TASKPAD_FROM_HERE);
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
// add the "Edit Taskpad" and "Delete Taskpad" menus item if the callback pointer is non-null.
|
|
if ((pViewData->m_spTaskCallback != NULL) &&
|
|
(pViewData->m_spTaskCallback->IsEditable() == S_OK))
|
|
{
|
|
sc = ScAddMenuItem( IDS_EDIT_TASKPAD, szEDIT_TASKPAD, MID_EDIT_TASKPAD);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem( IDS_DELETE_TASKPAD, szDELETE_TASKPAD, MID_DELETE_TASKPAD);
|
|
if(sc)
|
|
return sc;
|
|
|
|
}
|
|
}
|
|
|
|
sc = ScAddMenuItemsForVerbSets();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Ask the snap-ins to add there menu items.
|
|
CComponentData* pCCD = pMTNode->GetPrimaryComponentData();
|
|
|
|
if (m_spIDataObject == NULL)
|
|
{
|
|
sc = pMTNode->QueryDataObject(CCT_SCOPE, &m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
//ASSERT(m_pNode->GetPrimaryComponent() != NULL);
|
|
//IUnknownPtr spUnknown = m_pNode->GetPrimaryComponent()->GetIComponent();
|
|
// TODO: This is temporary. All context menu notifications should
|
|
// go to IComponent's in the future.
|
|
IUnknownPtr spUnknown = pCCD->GetIComponentData();
|
|
ASSERT(spUnknown != NULL);
|
|
|
|
sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
sc = AddThirdPartyExtensionItems(m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForMultiSelect
|
|
*
|
|
* PURPOSE: Menu for use when multiple items are selected and the right mouse button is pressed
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForMultiSelect()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForMultiSelect"));
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// no Create New menu for result items
|
|
sc = ScAddSubmenu_Task();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItemsForVerbSets();
|
|
if(sc)
|
|
return sc;
|
|
|
|
{
|
|
ASSERT(m_pNode != NULL);
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScCheckPointers(m_pNode->GetViewData(), E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CMultiSelection* pMS = m_pNode->GetViewData()->GetMultiSelection();
|
|
if (pMS != NULL)
|
|
{
|
|
IDataObjectPtr spIDataObject;
|
|
sc = pMS->GetMultiSelDataObject(&spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CSnapIn* pSI = m_pNode->GetPrimarySnapIn();
|
|
if (pSI != NULL &&
|
|
pMS->IsAnExtensionSnapIn(pSI->GetSnapInCLSID()) == TRUE)
|
|
{
|
|
sc = ScCheckPointers(m_pNode->GetPrimaryComponent(), E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IComponent* pIComponent = m_pNode->GetPrimaryComponent()->GetIComponent();
|
|
|
|
sc = AddPrimaryExtensionItems(pIComponent, spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = AddMultiSelectExtensionItems(reinterpret_cast<LONG_PTR>(pMS));
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForOCX
|
|
*
|
|
* PURPOSE: This method will be called if there is an OCX in
|
|
* Result pane and some thing is selected in OCX and
|
|
* the user clicked "Action" menu.
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForOCX()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForOCX"));
|
|
|
|
LPCOMPONENT pIComponent = NULL; // IComponent interface to the snap-in
|
|
CComponent* pComponent = NULL; // Internal component structure
|
|
MMC_COOKIE cookie;
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (IsVerbEnabled(MMC_VERB_OPEN) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0,
|
|
(m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// no Create New menu for result items
|
|
sc = ScAddSubmenu_Task();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItemsForVerbSets();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
LPDATAOBJECT lpDataObj = (m_pNode->GetViewData()->HasOCX()) ?
|
|
DOBJ_CUSTOMOCX : DOBJ_CUSTOMWEB;
|
|
|
|
// Item must be from primary component
|
|
pComponent = m_pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pComponent, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
pIComponent = pComponent->GetIComponent();
|
|
sc = ScCheckPointers(pIComponent, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddPrimaryExtensionItems(pIComponent, lpDataObj);
|
|
if(sc)
|
|
return sc;
|
|
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForLV
|
|
*
|
|
* PURPOSE: Add menu items for a list view item
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForLV()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForLV"));
|
|
|
|
LPCOMPONENT pIComponent; // IComponet interface to the snap-in
|
|
CComponent* pComponent; // Internal component structure
|
|
MMC_COOKIE cookie;
|
|
|
|
ASSERT(m_pNode != NULL);
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
// if virtual list
|
|
if (m_pNode->GetViewData()->IsVirtualList())
|
|
{
|
|
// ItemParam is the item index, use it as the cookie
|
|
cookie = PContextInfo()->m_resultItemParam;
|
|
|
|
// Item must be from primary component
|
|
pComponent = m_pNode->GetPrimaryComponent();
|
|
}
|
|
else
|
|
{
|
|
// ItemParam is list item data, get cookie and component ID from it
|
|
ASSERT(PContextInfo()->m_resultItemParam != 0);
|
|
CResultItem* pri = GetResultItem();
|
|
|
|
if (pri != NULL)
|
|
{
|
|
ASSERT(!pri->IsScopeItem());
|
|
|
|
cookie = pri->GetSnapinData();
|
|
pComponent = m_pNode->GetComponent(pri->GetOwnerID());
|
|
}
|
|
}
|
|
|
|
sc = ScCheckPointers(pComponent, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
pIComponent = pComponent->GetIComponent();
|
|
|
|
sc = ScCheckPointers(pIComponent);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Load the IDataObject for the snap-in's cookie
|
|
if (m_spIDataObject == NULL)
|
|
{
|
|
sc = pIComponent->QueryDataObject(cookie, CCT_RESULT, &m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (IsVerbEnabled(MMC_VERB_OPEN) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_OPEN, szOPEN, MID_OPEN, 0, (m_eDefaultVerb == MMC_VERB_OPEN) ? MF_DEFAULT : 0);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// no Create New menu for result items
|
|
sc = ScAddSubmenu_Task();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItemsForVerbSets();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddPrimaryExtensionItems(pIComponent, m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddThirdPartyExtensionItems(m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddMenuItemsForLVBackgnd
|
|
*
|
|
* PURPOSE: This handles a right mouse click on the result pane side (Assuming our listview)
|
|
* It displays also adds the currently selected folders context menu items
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItemsForLVBackgnd()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItemsForLVBackgnd"));
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = EmptyMenuList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TOP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSubmenu_CreateNew(m_pNode->IsStaticNode());
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSubmenu_Task();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add relevant standard verbs.
|
|
if (IsVerbEnabled(MMC_VERB_PASTE) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_PASTE, szPASTE, MID_PASTE);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
if (IsVerbEnabled(MMC_VERB_REFRESH) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_REFRESH, szREFRESH, MID_REFRESH);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
// Displays the save list icon if necessary
|
|
if ((PContextInfo()->m_pConsoleView != NULL) &&
|
|
(PContextInfo()->m_pConsoleView->GetListSize() > 0))
|
|
{
|
|
sc = ScAddMenuItem( IDS_SAVE_LIST, szSAVE_LIST, MID_LISTSAVE);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add view submenu
|
|
sc = ScAddMenuItemsForViewMenu(MENU_LEVEL_SUB);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Add Arrange Icons
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem( IDS_ARRANGE_ICONS, szARRANGE_ICONS, MID_ARRANGE_ICONS, 0, MF_POPUP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
long lStyle = 0;
|
|
if (PContextInfo()->m_spListView)
|
|
{
|
|
lStyle = PContextInfo()->m_spListView->GetListStyle();
|
|
ASSERT(lStyle != 0);
|
|
}
|
|
|
|
|
|
// auto arrange
|
|
sc = ScAddMenuItem( IDS_ARRANGE_AUTO, szARRANGE_AUTO, MID_ARRANGE_AUTO, MID_ARRANGE_ICONS,
|
|
((lStyle & LVS_AUTOARRANGE) ? MF_CHECKED : MF_UNCHECKED));
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddMenuItem( IDS_LINE_UP_ICONS, szLINE_UP_ICONS, MID_LINE_UP_ICONS);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Ask the node whether it will put up property pages. If so add the
|
|
// "Properties" menu item
|
|
if (IsVerbEnabled(MMC_VERB_PROPERTIES) == TRUE)
|
|
{
|
|
sc = ScAddMenuItem( IDS_PROPERTIES, szPROPERTIES, MID_PROPERTIES);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator();
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
|
|
// if there is a valid data object we would have gotten it when adding the
|
|
// view menu itmes, so we don't need to duplicate the code to get it here
|
|
if (m_spIDataObject != NULL)
|
|
{
|
|
CComponent* pCC = m_pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pCC, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IUnknownPtr spUnknown = pCC->GetIComponent();
|
|
sc = ScCheckPointers(spUnknown);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddPrimaryExtensionItems(spUnknown, m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = AddThirdPartyExtensionItems(m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
void OnCustomizeView(CViewData* pViewData)
|
|
{
|
|
CCustomizeViewDialog dlg(pViewData);
|
|
dlg.DoModal();
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::AddMenuItems
|
|
*
|
|
* PURPOSE: Unimplemented, but needed because this class implements
|
|
* IExtendContextMenu
|
|
*
|
|
* PARAMETERS:
|
|
* LPDATAOBJECT pDataObject :
|
|
* LPCONTEXTMENUCALLBACK pCallback :
|
|
* long * pInsertionAllowed :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddMenuItems( LPDATAOBJECT pDataObject, LPCONTEXTMENUCALLBACK pCallback, long * pInsertionAllowed)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddMenuItems"));
|
|
ASSERT(0 && "Should not come here!");
|
|
return sc = E_UNEXPECTED;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::Command
|
|
*
|
|
* PURPOSE: Handles the built- in menu item execution.
|
|
*
|
|
* PARAMETERS:
|
|
* long lCommandID :
|
|
* LPDATAOBJECT pDataObject :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScCommand(long lCommandID, LPDATAOBJECT pDataObject)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::Command"));
|
|
|
|
CNodeCallback * pNodeCallback=GetNodeCallback();
|
|
sc = ScCheckPointers(pNodeCallback, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
/*+-------------------------------------------------------------------------*/
|
|
// special case: MID_CONTEXTHELP: m_pNode can be NULL when help clicked on scope node background,
|
|
// so we handle this first.
|
|
if(MID_CONTEXTHELP == lCommandID)
|
|
{
|
|
sc = ScCheckPointers(PContextInfo());
|
|
if(sc)
|
|
return sc;
|
|
|
|
CConsoleView* pConsoleView = PContextInfo()->m_pConsoleView;
|
|
sc = ScCheckPointers(pConsoleView);
|
|
if(sc)
|
|
return sc;
|
|
|
|
if (PContextInfo()->m_bMultiSelect)
|
|
{
|
|
sc = pConsoleView->ScContextHelp ();
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else
|
|
{
|
|
sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_CONTEXTHELP,
|
|
((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
|
|
(PContextInfo()->m_bBackground == TRUE)),
|
|
PContextInfo()->m_resultItemParam);
|
|
|
|
// if snap-in did not handle the help request, show mmc topics
|
|
if (sc.ToHr() != S_OK)
|
|
sc = PContextInfo()->m_pConsoleView->ScHelpTopics ();
|
|
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
/*+-------------------------------------------------------------------------*/
|
|
|
|
|
|
// must have a non-null m_pNode.
|
|
sc = ScCheckPointers(m_pNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
HNODE hNode = CNode::ToHandle(m_pNode);
|
|
BOOL bModeChange = FALSE;
|
|
int nNewMode;
|
|
|
|
// some widely used objects
|
|
CViewData * pViewData = m_pNode->GetViewData();
|
|
sc = ScCheckPointers(pViewData);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CConsoleFrame* pFrame = pViewData->GetConsoleFrame();
|
|
CMTNode* pMTNode = m_pNode->GetMTNode();
|
|
CConsoleView* pConsoleView= pViewData->GetConsoleView();
|
|
|
|
sc = ScCheckPointers(pFrame, pMTNode, pConsoleView, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// handle the correct item
|
|
switch (lCommandID)
|
|
{
|
|
|
|
case MID_RENAME:
|
|
sc = pConsoleView->ScOnRename(PContextInfo());
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_REFRESH:
|
|
{
|
|
BOOL bScope = ( (PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
|
|
(PContextInfo()->m_bBackground == TRUE) );
|
|
|
|
sc = pConsoleView->ScOnRefresh(hNode, bScope, PContextInfo()->m_resultItemParam);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
break;
|
|
|
|
case MID_LINE_UP_ICONS:
|
|
sc = pConsoleView->ScLineUpIcons();
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_ARRANGE_AUTO:
|
|
sc = pConsoleView->ScAutoArrangeIcons();
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
|
|
case MID_ORGANIZE_FAVORITES:
|
|
sc = pConsoleView->ScOrganizeFavorites();
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
|
|
case MID_DELETE:
|
|
{
|
|
bool bScope = (CCT_SCOPE == PContextInfo()->m_eDataObjectType);
|
|
bool bScopeItemInResultPane = PContextInfo()->m_dwFlags & CMINFO_SCOPEITEM_IN_RES_PANE;
|
|
bool bScopeItemInScopePaneOrResultPane = bScope || bScopeItemInResultPane;
|
|
|
|
LPARAM lvData = PContextInfo()->m_resultItemParam;
|
|
|
|
if (PContextInfo()->m_bBackground)
|
|
lvData = LVDATA_BACKGROUND;
|
|
else if (PContextInfo()->m_bMultiSelect)
|
|
lvData = LVDATA_MULTISELECT;
|
|
|
|
sc = pNodeCallback->Notify(hNode, NCLBK_DELETE,
|
|
bScopeItemInScopePaneOrResultPane ,
|
|
lvData);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
}
|
|
|
|
|
|
case MID_NEW_TASKPAD_FROM_HERE:
|
|
sc = pNodeCallback->Notify(hNode, NCLBK_NEW_TASKPAD_FROM_HERE, 0, 0);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_EDIT_TASKPAD:
|
|
sc = pNodeCallback->Notify(hNode, NCLBK_EDIT_TASKPAD, 0, 0);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_DELETE_TASKPAD:
|
|
sc = pNodeCallback->Notify(hNode, NCLBK_DELETE_TASKPAD, 0, 0);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_EXPLORE: // New window from here
|
|
{
|
|
try
|
|
{
|
|
CreateNewViewStruct cnvs;
|
|
cnvs.idRootNode = pMTNode->GetID();
|
|
cnvs.lWindowOptions = MMC_NW_OPTION_NONE;
|
|
cnvs.fVisible = true;
|
|
|
|
sc = pFrame->ScCreateNewView(&cnvs);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
catch (...)
|
|
{
|
|
sc = E_FAIL;
|
|
ASSERT(0 && "NewWindow invalid scope item");
|
|
return sc;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case MID_OPEN:
|
|
{
|
|
sc = pConsoleView->ScSelectNode (pMTNode->GetID());
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
break;
|
|
|
|
case MID_PROPERTIES:
|
|
if (NULL == m_pNode)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
sc = ScDisplaySnapinPropertySheet();
|
|
if(sc)
|
|
return sc;
|
|
|
|
break;
|
|
|
|
case MID_VIEW_LARGE:
|
|
bModeChange = TRUE;
|
|
nNewMode = LVS_ICON;
|
|
break;
|
|
|
|
case MID_VIEW_SMALL:
|
|
bModeChange = TRUE;
|
|
nNewMode = LVS_SMALLICON;
|
|
break;
|
|
|
|
case MID_VIEW_LIST:
|
|
bModeChange = TRUE;
|
|
nNewMode = LVS_LIST;
|
|
break;
|
|
|
|
case MID_VIEW_DETAIL:
|
|
bModeChange = TRUE;
|
|
nNewMode = LVS_REPORT;
|
|
break;
|
|
|
|
case MID_VIEW_FILTERED:
|
|
bModeChange = TRUE;
|
|
nNewMode = MMCLV_VIEWSTYLE_FILTERED;
|
|
break;
|
|
|
|
case MID_CUT:
|
|
sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_CUT,
|
|
(PContextInfo()->m_eDataObjectType == CCT_SCOPE),
|
|
PContextInfo()->m_resultItemParam);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = pConsoleView->ScCut (PContextInfo()->m_htiRClicked);
|
|
if(sc)
|
|
return sc;
|
|
|
|
break;
|
|
|
|
case MID_COPY:
|
|
sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_COPY,
|
|
(PContextInfo()->m_eDataObjectType == CCT_SCOPE),
|
|
PContextInfo()->m_resultItemParam);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_PASTE:
|
|
sc = pNodeCallback->Paste(CNode::ToHandle(m_pNode),
|
|
((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
|
|
(PContextInfo()->m_bBackground == TRUE)),
|
|
PContextInfo()->m_resultItemParam);
|
|
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = pConsoleView->ScPaste ();
|
|
if(sc)
|
|
return sc;
|
|
|
|
break;
|
|
|
|
case MID_COLUMNS:
|
|
ASSERT(m_pNode);
|
|
if (m_pNode)
|
|
m_pNode->OnColumns();
|
|
break;
|
|
|
|
case MID_LISTSAVE:
|
|
// If the listsave menu item has been activated, then tell the view to
|
|
// save the active list
|
|
sc = pConsoleView->ScSaveList();
|
|
if(sc)
|
|
return sc;
|
|
|
|
break;
|
|
|
|
case MID_PRINT:
|
|
sc = pNodeCallback->Notify(CNode::ToHandle(m_pNode), NCLBK_PRINT,
|
|
((PContextInfo()->m_eDataObjectType == CCT_SCOPE) ||
|
|
(PContextInfo()->m_bBackground == TRUE)),
|
|
PContextInfo()->m_resultItemParam);
|
|
if(sc)
|
|
return sc;
|
|
break;
|
|
|
|
case MID_CUSTOMIZE:
|
|
if (pViewData)
|
|
OnCustomizeView(pViewData);
|
|
break;
|
|
|
|
|
|
default:
|
|
ASSERT(0 && "Should not come here");
|
|
break;
|
|
|
|
}
|
|
|
|
if (bModeChange)
|
|
{
|
|
sc = ScChangeListViewMode(nNewMode);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScChangeListViewMode
|
|
*
|
|
* PURPOSE: Changes the list view mode to the specified mode.
|
|
*
|
|
* PARAMETERS:
|
|
* int nNewMode : The mode to change to.
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScChangeListViewMode(int nNewMode)
|
|
{
|
|
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScChangeListViewMode"));
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// If switching from a snapin custom to a standard listview
|
|
// send snapin a notification command
|
|
if ((PContextInfo()->m_spListView == NULL))
|
|
{
|
|
sc = ScCheckPointers(m_spIDataObject.GetInterfacePtr(), E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CComponent* pCC = m_pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pCC, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IExtendContextMenuPtr spIExtendContextMenu = pCC->GetIComponent();
|
|
if(spIExtendContextMenu)
|
|
{
|
|
try
|
|
{
|
|
sc = spIExtendContextMenu->Command(MMCC_STANDARD_VIEW_SELECT, m_spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
catch ( std::bad_alloc )
|
|
{
|
|
return (sc = E_OUTOFMEMORY);
|
|
}
|
|
catch ( std::exception )
|
|
{
|
|
return (sc = E_UNEXPECTED);
|
|
}
|
|
}
|
|
}
|
|
|
|
CViewData *pViewData = m_pNode->GetViewData();
|
|
sc = ScCheckPointers(pViewData, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
// Persist the new mode.
|
|
sc = m_pNode->ScSetViewMode(nNewMode);
|
|
if (sc)
|
|
return sc;
|
|
|
|
// tell conui to change the list mode.
|
|
CConsoleView* pConsoleView = pViewData->GetConsoleView();
|
|
sc = ScCheckPointers(pConsoleView, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
sc = pConsoleView->ScChangeViewMode (nNewMode);
|
|
if (sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddSubmenu_Task
|
|
*
|
|
* PURPOSE: Adds the Task submenu
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddSubmenu_Task()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddSubmenu_Task"));
|
|
sc = ScAddMenuItem(IDS_TASK, szTASK, MID_TASK, 0, MF_POPUP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_TASK, MID_TASK);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator( MID_TASK );
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_3RDPARTY_TASK, MID_TASK);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator( MID_TASK);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScAddSubmenu_CreateNew
|
|
*
|
|
* PURPOSE: Adds the New submenu
|
|
*
|
|
* PARAMETERS:
|
|
* BOOL fStaticFolder :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScAddSubmenu_CreateNew(BOOL fStaticFolder)
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScAddSubmenu_CreateNew"));
|
|
|
|
sc = ScAddMenuItem(IDS_CREATE_NEW, szCREATE_NEW, MID_CREATE_NEW, 0, MF_POPUP);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_PRIMARY_NEW, MID_CREATE_NEW);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator( MID_CREATE_NEW);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddInsertionPoint(CCM_INSERTIONPOINTID_3RDPARTY_NEW, MID_CREATE_NEW);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScAddSeparator( MID_CREATE_NEW);
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* CContextMenu::ScDisplaySnapinPropertySheet
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* RETURNS:
|
|
* void
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
CContextMenu::ScDisplaySnapinPropertySheet()
|
|
{
|
|
DECLARE_SC(sc, TEXT("CContextMenu::ScDisplaySnapinPropertySheet"));
|
|
|
|
sc = ScCheckPointers(m_pNode, E_UNEXPECTED);
|
|
if (sc)
|
|
return sc;
|
|
|
|
if (CCT_SCOPE == PContextInfo()->m_eDataObjectType ||
|
|
PContextInfo()->m_bBackground == TRUE)
|
|
{
|
|
sc = ScDisplaySnapinNodePropertySheet(m_pNode);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else
|
|
{
|
|
// Get the view type.
|
|
ASSERT(m_pNode->GetViewData());
|
|
CViewData *pViewData = m_pNode->GetViewData();
|
|
|
|
if (PContextInfo()->m_bMultiSelect)
|
|
{
|
|
// Must be in the result pane.
|
|
sc = ScDisplayMultiSelPropertySheet(m_pNode);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else if (m_pNode->GetViewData()->IsVirtualList())
|
|
{
|
|
// if virtual list, must be leaf item and resultItemParam is the cookie
|
|
sc = ScDisplaySnapinLeafPropertySheet(m_pNode, PContextInfo()->m_resultItemParam);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else if( (pViewData->HasOCX()) || (pViewData->HasWebBrowser()) )
|
|
{
|
|
LPDATAOBJECT pdobj = (pViewData->HasOCX()) ? DOBJ_CUSTOMOCX
|
|
: DOBJ_CUSTOMWEB;
|
|
CComponent* pCC = m_pNode->GetPrimaryComponent();
|
|
ASSERT(pCC != NULL);
|
|
|
|
// The custom view was selected and "properties" was selected from "Action Menu".
|
|
// We dont know anything about the view, so we fake "Properties" button click.
|
|
pCC->Notify(pdobj, MMCN_BTN_CLICK, 0, MMC_VERB_PROPERTIES);
|
|
}
|
|
else
|
|
{
|
|
CResultItem* pri = GetResultItem();
|
|
|
|
if (pri != NULL)
|
|
{
|
|
if (pri->IsScopeItem())
|
|
{
|
|
sc = ScDisplaySnapinNodePropertySheet(m_pNode);
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
else
|
|
{
|
|
sc = ScDisplaySnapinLeafPropertySheet(m_pNode, pri->GetSnapinData());
|
|
if(sc)
|
|
return sc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return sc;
|
|
}
|
|
|
|
/************************************************************************
|
|
* -----------------------------------------
|
|
* Order: Calling function
|
|
* Called function 1
|
|
* Called function 2
|
|
* -----------------------------------------
|
|
*
|
|
*
|
|
* CContextMenu::ProcessSelection()
|
|
* CContextMenu::ScDisplaySnapinPropertySheet()
|
|
* ScDisplaySnapinNodePropertySheet(CNode* pNode)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
* ScDisplayMultiSelPropertySheet(CNode* pNode)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
* ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
*
|
|
* CNodeCallback::OnProperties(CNode* pNode, BOOL bScope, LPARAM lvData)
|
|
* ScDisplaySnapinNodePropertySheet(CNode* pNode)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
* ScDisplayMultiSelPropertySheet(CNode* pNode)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
* ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
|
|
* ScDisplaySnapinPropertySheet
|
|
* FindPropertySheet
|
|
************************************************************************/
|
|
|
|
|
|
SC ScDisplaySnapinPropertySheet(IComponent* pComponent,
|
|
IComponentData* pComponentData,
|
|
IDataObject* pDataObject,
|
|
EPropertySheetType type,
|
|
LPCWSTR pName,
|
|
LPARAM lUniqueID,
|
|
CMTNode* pMTNode);
|
|
//--------------------------------------------------------------------------
|
|
|
|
SC ScDisplaySnapinNodePropertySheet(CNode* pNode)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScDisplaySnapinNodePropertySheet"));
|
|
|
|
sc = ScCheckPointers(pNode, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScDisplayScopeNodePropertySheet(pNode->GetMTNode());
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScDisplayScopeNodePropertySheet
|
|
*
|
|
* PURPOSE: Displays a property sheet for a scope node.
|
|
*
|
|
* PARAMETERS:
|
|
* CMTNode * pMTNode : The scope node.
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
ScDisplayScopeNodePropertySheet(CMTNode *pMTNode)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScDisplayScopeNodePropertySheet"));
|
|
|
|
IDataObjectPtr spIDataObject;
|
|
sc = pMTNode->QueryDataObject(CCT_SCOPE, &spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CComponentData* pCCD = pMTNode->GetPrimaryComponentData();
|
|
sc = ScCheckPointers(pCCD);
|
|
if(sc)
|
|
return sc;
|
|
|
|
LPARAM lUniqueID = CMTNode::ToScopeItem(pMTNode);
|
|
tstring strName = pMTNode->GetDisplayName();
|
|
|
|
if (strName.empty())
|
|
strName = _T("");
|
|
|
|
USES_CONVERSION;
|
|
sc = ScDisplaySnapinPropertySheet(NULL, pCCD->GetIComponentData(),
|
|
spIDataObject,
|
|
epstScopeItem,
|
|
T2CW (strName.data()),
|
|
lUniqueID,
|
|
pMTNode);
|
|
|
|
return sc;
|
|
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScDisplayMultiSelPropertySheet
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CNode* pNode :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC ScDisplayMultiSelPropertySheet(CNode* pNode)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScDisplayMultiSelPropertySheet"));
|
|
|
|
USES_CONVERSION;
|
|
|
|
// check inputs
|
|
sc = ScCheckPointers(pNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScCheckPointers(pNode->GetViewData(), E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CMultiSelection* pMS = pNode->GetViewData()->GetMultiSelection();
|
|
sc = ScCheckPointers(pMS, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
ASSERT(pMS->IsSingleSnapinSelection());
|
|
if (pMS->IsSingleSnapinSelection() == false)
|
|
return (sc = E_UNEXPECTED);
|
|
|
|
IDataObjectPtr spIDataObject = pMS->GetSingleSnapinSelDataObject();
|
|
sc = ScCheckPointers(spIDataObject, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
CComponent* pCC = pMS->GetPrimarySnapinComponent();
|
|
sc = ScCheckPointers(pCC, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
LPARAM lUniqueID = reinterpret_cast<LPARAM>(pMS);
|
|
|
|
CStr strName;
|
|
strName.LoadString(GetStringModule(), IDS_PROP_ON_MULTIOBJ);
|
|
LPWSTR pwszDispName = T2W((LPTSTR)(LPCTSTR)strName);
|
|
|
|
sc = ScDisplaySnapinPropertySheet(pCC->GetIComponent(), NULL,
|
|
spIDataObject,
|
|
epstMultipleItems,
|
|
pwszDispName,
|
|
lUniqueID,
|
|
pNode->GetMTNode());
|
|
if(sc)
|
|
return sc;
|
|
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
*
|
|
* ScDisplaySnapinLeafPropertySheet
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
* PARAMETERS:
|
|
* CNode* pNode :
|
|
* LPARAM lParam :
|
|
*
|
|
* RETURNS:
|
|
* SC
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC
|
|
ScDisplaySnapinLeafPropertySheet(CNode* pNode, LPARAM lParam)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScDisplaySnapinLeafPropertySheet"));
|
|
|
|
ASSERT(!(IS_SPECIAL_COOKIE(lParam)));
|
|
|
|
sc = ScCheckPointers(pNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
sc = ScCheckPointers(pNode->GetViewData(), E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
ASSERT(lParam != 0 || pNode->GetViewData()->IsVirtualList());
|
|
|
|
CComponent* pCC = pNode->GetPrimaryComponent();
|
|
sc = ScCheckPointers(pCC, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IComponent* pIComponent = pCC->GetIComponent();
|
|
sc = ScCheckPointers(pIComponent, E_UNEXPECTED);
|
|
if(sc)
|
|
return sc;
|
|
|
|
// Get the IDataObject for the snap-in's cookie
|
|
IDataObjectPtr spIDataObject;
|
|
sc = pIComponent->QueryDataObject(lParam, CCT_RESULT, &spIDataObject);
|
|
if(sc)
|
|
return sc;
|
|
|
|
RESULTDATAITEM rdi;
|
|
ZeroMemory(&rdi, sizeof(rdi));
|
|
|
|
if (pNode->GetViewData()->IsVirtualList())
|
|
rdi.nIndex = lParam;
|
|
else
|
|
rdi.lParam = lParam;
|
|
|
|
rdi.mask = RDI_STR;
|
|
|
|
LPWSTR pName = L"";
|
|
sc = pIComponent->GetDisplayInfo(&rdi);
|
|
if (!sc.IsError() && rdi.str != NULL)
|
|
pName = rdi.str;
|
|
|
|
sc = ScDisplaySnapinPropertySheet(pIComponent, NULL,
|
|
spIDataObject,
|
|
epstResultItem,
|
|
pName,
|
|
0,
|
|
pNode->GetMTNode());
|
|
return sc;
|
|
}
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* ScDisplaySnapinPropertySheet
|
|
*
|
|
*
|
|
* PURPOSE:
|
|
*
|
|
*+-------------------------------------------------------------------------*/
|
|
SC ScDisplaySnapinPropertySheet(IComponent* pComponent,
|
|
IComponentData* pComponentData,
|
|
IDataObject* pDataObject,
|
|
EPropertySheetType type,
|
|
LPCWSTR pName,
|
|
LPARAM lUniqueID,
|
|
CMTNode* pMTNode)
|
|
{
|
|
DECLARE_SC(sc, TEXT("ScDisplaySnapinPropertySheet"));
|
|
|
|
// one of pComponent and pComponentData must be non-null
|
|
if(pComponentData == NULL && pComponent == NULL)
|
|
return (sc = E_INVALIDARG);
|
|
|
|
// check other parameters
|
|
sc = ScCheckPointers(pDataObject, pName, pMTNode);
|
|
if(sc)
|
|
return sc;
|
|
|
|
IUnknown *pUnknown = (pComponent != NULL) ? (IUnknown *)pComponent : (IUnknown *)pComponentData;
|
|
|
|
IPropertySheetProviderPrivatePtr spPropSheetProviderPrivate;
|
|
|
|
do
|
|
{
|
|
ASSERT(pDataObject != NULL);
|
|
ASSERT(pUnknown != NULL);
|
|
|
|
sc = spPropSheetProviderPrivate.CreateInstance(CLSID_NodeInit, NULL, MMC_CLSCTX_INPROC);
|
|
if(sc)
|
|
break;
|
|
|
|
|
|
sc = ScCheckPointers(spPropSheetProviderPrivate, E_UNEXPECTED);
|
|
if(sc)
|
|
break;
|
|
|
|
// See if the prop page for this is already up
|
|
sc = spPropSheetProviderPrivate->FindPropertySheetEx(lUniqueID, pComponent, pComponentData, pDataObject);
|
|
if (sc == S_OK)
|
|
break;
|
|
|
|
// No it is not present. So create a property sheet.
|
|
DWORD dwOptions = (type == epstMultipleItems) ? MMC_PSO_NO_PROPTITLE : 0;
|
|
sc = spPropSheetProviderPrivate->CreatePropertySheet(pName, TRUE, lUniqueID, pDataObject, dwOptions);
|
|
if(sc)
|
|
break;
|
|
|
|
// This data is used to get path to property sheet owner for tooltips
|
|
spPropSheetProviderPrivate->SetPropertySheetData(type, CMTNode::ToHandle(pMTNode));
|
|
|
|
sc = spPropSheetProviderPrivate->AddPrimaryPages(pUnknown, TRUE, NULL,
|
|
(type == epstScopeItem));
|
|
|
|
//#ifdef EXTENSIONS_CANNOT_ADD_PAGES_IF_PRIMARY_DOESNT
|
|
// note that only S_OK continues execution, S_FALSE breaks out
|
|
if (!(sc == S_OK) ) // ie if sc != S_OK
|
|
break;
|
|
//#endif
|
|
|
|
// Enable adding extensions
|
|
if (type == epstMultipleItems)
|
|
{
|
|
IPropertySheetProviderPrivatePtr spPSPPrivate = spPropSheetProviderPrivate;
|
|
sc = spPSPPrivate->AddMultiSelectionExtensionPages(lUniqueID);
|
|
}
|
|
else
|
|
{
|
|
sc = spPropSheetProviderPrivate->AddExtensionPages();
|
|
}
|
|
|
|
// any errors from extensions are thrown away.
|
|
|
|
CWindow w(CScopeTree::GetScopeTree()->GetMainWindow());
|
|
sc = spPropSheetProviderPrivate->Show((LONG_PTR)w.m_hWnd, 0);
|
|
|
|
} while (0);
|
|
|
|
// Clean up the 'Created' property sheet if there was an error
|
|
if (spPropSheetProviderPrivate != NULL && sc.IsError())
|
|
spPropSheetProviderPrivate->Show(-1, 0);
|
|
|
|
return sc;
|
|
}
|
|
|
|
|
|
/*+-------------------------------------------------------------------------*
|
|
* CContextMenu::GetResultItem
|
|
*
|
|
* Returns the CResultItem pointer for the result item represented by the
|
|
* context info.
|
|
*
|
|
* This function is out-of-line to eliminate coupling between oncmenu.h and
|
|
* rsltitem.h.
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
CResultItem* CContextMenu::GetResultItem () const
|
|
{
|
|
return (CResultItem::FromHandle (PContextInfo()->m_resultItemParam));
|
|
}
|
|
|
|
|