390 lines
8.9 KiB
C++
390 lines
8.9 KiB
C++
|
/*++
|
|||
|
|
|||
|
<EFBFBD> 1998 Seagate Software, Inc. All rights reserved.
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
SakMenu.cpp
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Implements all the context menu interface to the individual nodes,
|
|||
|
including getting menu resources and turning into MMC menus, and
|
|||
|
forwarding on command messages.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Rohde Wakefield [rohde] 09-Dec-1996
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
|
|||
|
#include "stdafx.h"
|
|||
|
#include "CSakData.h"
|
|||
|
#include "CSakSnap.h"
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Mask for a long value out of a short value's range
|
|||
|
//
|
|||
|
|
|||
|
#define SHORT_VALUE_RANGE (MAXULONG ^ ((unsigned short)MAXSHORT))
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static HRESULT
|
|||
|
AddMmcMenuItems (
|
|||
|
IN CMenu * pMenu,
|
|||
|
IN LONG lInsertionPointID,
|
|||
|
IN ISakNode * pNode,
|
|||
|
IN IContextMenuCallback * pContextMenuCallback
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called for any node clicked on with right mouse. Goes to the
|
|||
|
node object to construct the MMC menu.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pDataObject - identifies the node to be worked on.
|
|||
|
|
|||
|
pContextMenuCallback - The MMC menu interface to use.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - All added fine - continue.
|
|||
|
|
|||
|
E_UNEXPECTED - Some error occurred.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WsbTraceIn( L"AddMmcMenuItems", L"lInsertionPointID = <0x%p>, pNode = <0x%p>", lInsertionPointID, pNode );
|
|||
|
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
//
|
|||
|
// It is ok to pass a NULL pMenu - means do not add
|
|||
|
// any entries
|
|||
|
//
|
|||
|
|
|||
|
if ( 0 != pMenu ) {
|
|||
|
|
|||
|
CString menuText;
|
|||
|
CString statusText;
|
|||
|
|
|||
|
BSTR bstr;
|
|||
|
|
|||
|
CONTEXTMENUITEM menuItem;
|
|||
|
memset ( (void*)&menuItem, 0, sizeof ( menuItem ) );
|
|||
|
menuItem.lInsertionPointID = lInsertionPointID;
|
|||
|
|
|||
|
UINT menuCount = pMenu->GetMenuItemCount ( );
|
|||
|
|
|||
|
for ( UINT index = 0; index < menuCount; index++ ) {
|
|||
|
|
|||
|
//
|
|||
|
// For each menu item, fill out MMC's CONTEXTMENUITEM struct
|
|||
|
// appropriately and call AddItem
|
|||
|
//
|
|||
|
|
|||
|
menuItem.lCommandID = pMenu->GetMenuItemID ( index );
|
|||
|
|
|||
|
pMenu->GetMenuString ( index, menuText, MF_BYPOSITION );
|
|||
|
menuItem.strName = (LPTSTR)(LPCTSTR)menuText;
|
|||
|
|
|||
|
WsbAffirmHr ( pNode->GetMenuHelp ( menuItem.lCommandID, &bstr ) );
|
|||
|
if ( 0 != bstr ) {
|
|||
|
|
|||
|
statusText = bstr;
|
|||
|
SysFreeString ( bstr );
|
|||
|
menuItem.strStatusBarText = (LPTSTR)(LPCTSTR)statusText;
|
|||
|
|
|||
|
} else {
|
|||
|
|
|||
|
menuItem.strStatusBarText = 0;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
menuItem.fFlags = pMenu->GetMenuState ( index, MF_BYPOSITION );
|
|||
|
menuItem.fSpecialFlags = 0;
|
|||
|
|
|||
|
//
|
|||
|
// Since AppStudio does not make available the MFS_DEFUALT flag,
|
|||
|
// we will use the MF_HELP flag for default entry.
|
|||
|
//
|
|||
|
|
|||
|
if ( 0 != ( menuItem.fFlags & MF_HELP ) ) {
|
|||
|
|
|||
|
menuItem.fFlags &= ~MF_HELP;
|
|||
|
menuItem.fSpecialFlags |= CCM_SPECIAL_DEFAULT_ITEM;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
pContextMenuCallback->AddItem ( &menuItem );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} WsbCatch ( hr );
|
|||
|
|
|||
|
WsbTraceOut( L"AddMmcMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
|
|||
|
return ( hr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
STDMETHODIMP
|
|||
|
CSakData::AddMenuItems (
|
|||
|
IN LPDATAOBJECT pDataObject,
|
|||
|
IN LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|||
|
OUT LONG* pInsertionAllowed
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called for any node clicked on with right mouse. Goes to the
|
|||
|
node object to construct the MMC menu.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pDataObject - identifies the node to be worked on.
|
|||
|
|
|||
|
pContextMenuCallback - The MMC menu interface to use.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - All added fine - continue.
|
|||
|
|
|||
|
E_UNEXPECTED - Some error occurred.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WsbTraceIn( L"CSakData::AddMenuItems", L"pDataObject = <0x%p>", pDataObject );
|
|||
|
|
|||
|
HRESULT hr = S_OK;
|
|||
|
BOOL bMultiSelect;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
//
|
|||
|
// Note - snap-ins need to look at the data object and determine
|
|||
|
// in what context, menu items need to be added.
|
|||
|
|
|||
|
// We should be expecting either single data object or Multi-Select
|
|||
|
// data object. Not Object Types data object.
|
|||
|
//
|
|||
|
|
|||
|
CComPtr<ISakNode> pNode;
|
|||
|
CComPtr<IEnumGUID> pEnumObjectId;
|
|||
|
WsbAffirmHr( GetBaseHsmFromDataObject( pDataObject, &pNode, &pEnumObjectId ) );
|
|||
|
bMultiSelect = pEnumObjectId ? TRUE : FALSE;
|
|||
|
|
|||
|
CMenu menu;
|
|||
|
HMENU hMenu;
|
|||
|
WsbAffirmHr( pNode->GetContextMenu ( bMultiSelect, &hMenu ) );
|
|||
|
|
|||
|
menu.Attach( hMenu );
|
|||
|
|
|||
|
//
|
|||
|
// Any menu returned by GetContextMenu should have three
|
|||
|
// top-level popups for the following portions of the
|
|||
|
// MMC context menu:
|
|||
|
//
|
|||
|
// 1. Root (Above all other items)
|
|||
|
// 2. Create New
|
|||
|
// 3. Task
|
|||
|
//
|
|||
|
// If any of these should not have any items added for them,
|
|||
|
// the top-level item should not be a pop (sans MF_POPUP)
|
|||
|
//
|
|||
|
|
|||
|
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TOP ) {
|
|||
|
|
|||
|
WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_ROOT ),
|
|||
|
CCM_INSERTIONPOINTID_PRIMARY_TOP, pNode, pContextMenuCallback ) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_NEW ) {
|
|||
|
|
|||
|
WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_NEW ),
|
|||
|
CCM_INSERTIONPOINTID_PRIMARY_NEW, pNode, pContextMenuCallback ) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
if( *pInsertionAllowed & CCM_INSERTIONALLOWED_TASK ) {
|
|||
|
|
|||
|
WsbAffirmHr ( AddMmcMenuItems ( menu.GetSubMenu ( MENU_INDEX_TASK ),
|
|||
|
CCM_INSERTIONPOINTID_PRIMARY_TASK, pNode, pContextMenuCallback ) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} WsbCatch ( hr );
|
|||
|
|
|||
|
WsbTraceOut( L"CSakData::AddMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
|
|||
|
return ( hr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
STDMETHODIMP
|
|||
|
CSakData::Command (
|
|||
|
IN long nCommandID,
|
|||
|
IN LPDATAOBJECT pDataObject
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called for any node receiving a menu command. Goes to the
|
|||
|
node object to handle the command, and allows general
|
|||
|
(not node-specific) commands to be handled centrally.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
nCommandID - ID of command.
|
|||
|
|
|||
|
pDataObject - Data object representing the node.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Handled.
|
|||
|
|
|||
|
E_UNEXPECTED - Some error occurred.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WsbTraceIn( L"CSakData::Command", L"nCommandID = <%ld>, pDataObject = <0x%p>", nCommandID, pDataObject );
|
|||
|
|
|||
|
HRESULT hr = S_OK;
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
HRESULT resultCommand = S_FALSE;
|
|||
|
|
|||
|
//
|
|||
|
// All node commands are SHORT values. Check range first.
|
|||
|
//
|
|||
|
|
|||
|
if ( 0 == ( nCommandID & SHORT_VALUE_RANGE ) ) {
|
|||
|
|
|||
|
//
|
|||
|
// We start by getting the corresponding ISakNode interface
|
|||
|
// to the node
|
|||
|
//
|
|||
|
|
|||
|
CComPtr<ISakNode> pNode;
|
|||
|
CComPtr<IEnumGUID> pEnumObjectId;
|
|||
|
WsbAffirmHr( GetBaseHsmFromDataObject ( pDataObject, &pNode, &pEnumObjectId ) );
|
|||
|
|
|||
|
//
|
|||
|
// Then see if it wants to handle the command
|
|||
|
//
|
|||
|
|
|||
|
WsbAffirmHr( ( resultCommand = pNode->InvokeCommand ( (SHORT)nCommandID, pDataObject ) ) );
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
} WsbCatch ( hr )
|
|||
|
|
|||
|
WsbTraceOut( L"CSakData::Command", L"hr = <%ls>", WsbHrAsString( hr ) );
|
|||
|
return ( hr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
STDMETHODIMP
|
|||
|
CSakSnap::AddMenuItems (
|
|||
|
IN LPDATAOBJECT pDataObject,
|
|||
|
IN LPCONTEXTMENUCALLBACK pContextMenuCallback,
|
|||
|
OUT LONG* pInsertionAllowed
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called for any node clicked on with right mouse in result pane.
|
|||
|
Delegates to CSakData.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
pDataObject - identifies the node to be worked on.
|
|||
|
|
|||
|
pContextMenuCallback - The MMC menu interface to use.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - All added fine - continue.
|
|||
|
|
|||
|
E_UNEXPECTED - Some error occurred.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WsbTraceIn( L"CSakSnap::AddMenuItems", L"pDataObject = <0x%p>", pDataObject );
|
|||
|
HRESULT hr = S_OK;
|
|||
|
try {
|
|||
|
|
|||
|
WsbAffirmHr( m_pSakData->AddMenuItems( pDataObject, pContextMenuCallback, pInsertionAllowed ) );
|
|||
|
|
|||
|
} WsbCatch( hr );
|
|||
|
|
|||
|
WsbTraceOut( L"CSakSnap::AddMenuItems", L"hr = <%ls>", WsbHrAsString( hr ) );
|
|||
|
return( hr );
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
STDMETHODIMP
|
|||
|
CSakSnap::Command (
|
|||
|
IN long nCommandID,
|
|||
|
IN LPDATAOBJECT pDataObject
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
Called for any node receiving a menu command.
|
|||
|
Delegated to CSakData.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
nCommandID - ID of command.
|
|||
|
|
|||
|
pDataObject - Data object representing the node.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
S_OK - Handled.
|
|||
|
|
|||
|
E_UNEXPECTED - Some error occurred.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
WsbTraceIn( L"CSakSnap::Command", L"nCommandID = <%ld>, pDataObject = <0x%p>", nCommandID, pDataObject );
|
|||
|
HRESULT hr;
|
|||
|
try {
|
|||
|
|
|||
|
hr = m_pSakData->Command( nCommandID, pDataObject );
|
|||
|
|
|||
|
} WsbCatch( hr );
|
|||
|
|
|||
|
WsbTraceOut( L"CSakSnap::Command", L"hr = <%ls>", WsbHrAsString( hr ) );
|
|||
|
return( hr );
|
|||
|
}
|
|||
|
|