/*++ © 1998 Seagate Software, Inc. All rights reserved. Module Name: evntsnap.cpp Abstract: This module is responsible for handling the notification calls from MMC for CSakSnap. Author: Rohde Wakefield [rohde] 06-Mar-1997 Revision History: --*/ #include "stdafx.h" #include "CSakSnap.h" #include "CSakData.h" HRESULT CSakSnap::OnShow( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: The result view is just about to be shown. Set the headers for the result view. Param is the unique identifier (an HSCOPEITEM) of the selected or deselected item. Arguments: pDataObject - The node which is showing. arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnShow", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); HRESULT hr = S_OK; try { CComPtr pNode; // // We've got a regular data object (single select) // WsbAffirmHr( m_pSakData->GetBaseHsmFromDataObject( pDataObject, &pNode, NULL ) ); // // Arg is TRUE when it is time to enumerate // if( arg ) { // // Initialize child node list prior to graphically enumerating them // WsbAffirmHr( m_pSakData->EnsureChildrenAreCreated( pNode ) ); // // Show the the node's children column headers in the result view. // WsbAffirmHr( InitResultPaneHeaders( pNode ) ); // // Enumerate both the scope and result views. "Param" contains the // HSCOPEITEM of the node being shown. // WsbAffirmHr( EnumResultPane( pNode ) ); } else { // // The node is being contracted - save the result pane configuration // // // Save them in CSakSnap for this node // WsbAffirmHr( SaveColumnWidths( pNode ) ); // // Free data associated with the result pane items, because // your node is no longer being displayed. // Note: The console will remove the items from the result pane // } } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::OnShow", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::OnChange( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: Update the scope and result panes from the already existing objects. Arguments: pNode - The node which is showing. arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnChange", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); HRESULT hr = S_OK; try { CComPtr pNode; MMC_COOKIE cookie; // // We've got a regular data object (single select) // WsbAffirmHr( m_pSakData->GetBaseHsmFromDataObject( pDataObject, &pNode, NULL ) ); WsbAffirmHr( m_pSakData->GetCookieFromBaseHsm( pNode, &cookie ) ); // // Find out if object is still valid // if( S_OK == pNode->IsValid( ) ) { // // Refresh the object itself // pNode->RefreshObject( ); // // If this node's children are currently enumerated in the result pane, // delete and recreate all children // if( pNode == m_pEnumeratedNode ) { // // Re-show the the node's children column headers in the result view. // We do this because some views may change the number of columns they show // // // Save the current configuration // WsbAffirmHr( SaveColumnWidths( pNode ) ); // // Clear out the MMC Result Pane // WsbAffirmHr( ClearResultPane() ); // // Recreate the headers // WsbAffirmHr( InitResultPaneHeaders( pNode ) ); // // Refresh the children // MMC_COOKIE cookie; WsbAffirmHr( m_pSakData->GetCookieFromBaseHsm( pNode, &cookie ) ); WsbAffirmHr( m_pSakData->InternalRefreshNode( cookie ) ); // // Redisplay children in the result pane // WsbAffirmHr( EnumResultPane( pNode ) ); } else { // // If this is the active node (but not displayed in the result pane, // destroy and recreate it's child nodes // if( cookie == m_ActiveNodeCookie) { // // This node's children are not currently in the result pane. // Refresh the children // WsbAffirmHr( m_pSakData->RefreshNode( pNode ) ); } } // // Is this a leaf node? // if( pNode->IsContainer() != S_OK ) { // // Redisplay in the result pane // Tell MMC to update the item // // Get the cookie for the node // if( cookie > 0 ) { HRESULTITEM itemID; WsbAffirmHr( m_pResultData->FindItemByLParam( cookie, &itemID ) ); // // Force the result pane to udpate this item // Note that we have to force an icon update ourselves // RESULTDATAITEM resultItem; memset( &resultItem, 0, sizeof(RESULTDATAITEM) ); resultItem.itemID = itemID; WsbAffirmHr( pNode->GetResultIcon( m_pSakData->m_State, &resultItem.nImage ) ); resultItem.mask |= RDI_IMAGE; WsbAffirmHr( m_pResultData->SetItem( &resultItem ) ); WsbAffirmHr( m_pResultData->UpdateItem( itemID ) ); } } } else { // // Not valid - have parent update // CComPtr pParentNode; WsbAffirmHr( pNode->GetParent( &pParentNode ) ); WsbAffirmHr( m_pSakData->UpdateAllViews( pParentNode ) ); } } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::OnChange", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::OnRefresh( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: Arguments: pNode - The node arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnRefresh", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); HRESULT hr = S_OK; try { CComPtr pNode; // // We've got a regular data object (single select) // WsbAffirmHr( m_pSakData->GetBaseHsmFromDataObject( pDataObject, &pNode, NULL ) ); WsbAffirmHr( m_pSakData->UpdateAllViews( pNode ) ); } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::OnRefresh", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::OnDelete( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: Arguments: pDataObject - The node arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnDelete", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); HRESULT hr = S_OK; CComPtr pNode; try { // // We've got a regular data object (single select) // WsbAffirmHr( m_pSakData->GetBaseHsmFromDataObject( pDataObject, &pNode, NULL ) ); WsbAffirmHr ( pNode->DeleteObject() ); } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::OnDelete", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::OnSelect( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: Called when a node is selected. If the node is in the scope pane, save it as the currently active node. Arguments: pNode - The arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnSelect", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); BOOL bState; BOOL bMultiSelect; MMC_CONSOLE_VERB defaultVerb = MMC_VERB_NONE; HRESULT hr = S_OK; try { CComPtr pEnumObjectId; CComPtr pNode; WsbAffirmHr( m_pSakData->GetBaseHsmFromDataObject( pDataObject, &pNode, &pEnumObjectId ) ); // If we got back an enumeration, we're doing multi-select bMultiSelect = pEnumObjectId ? TRUE : FALSE; bState = ( m_pSakData->GetState() == S_OK ); // // Set the verb state for the node // if( pNode->SupportsProperties( bMultiSelect ) == S_OK ) { if( bState || ( pNode->SupportsPropertiesNoEngine() == S_OK) ) { // // Engine OK - enable // WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, HIDDEN, FALSE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE ) ); defaultVerb = MMC_VERB_PROPERTIES; } else { // // Engine down - set to disabled // WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, HIDDEN, FALSE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, FALSE ) ); } } else { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, HIDDEN, TRUE) ); } if( pNode->SupportsRefresh( bMultiSelect ) == S_OK ) { if( bState || ( pNode->SupportsRefreshNoEngine() == S_OK ) ) { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, HIDDEN, FALSE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) ); } else { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, HIDDEN, TRUE ) ); } } else { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, HIDDEN, TRUE ) ); } if( pNode->SupportsDelete( bMultiSelect ) == S_OK ) { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_DELETE, HIDDEN, FALSE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_DELETE, ENABLED, bState ) ); } else { WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_DELETE, HIDDEN, TRUE ) ); } // // If container, default action should be to open, regardless // of any previous work // if( S_OK == pNode->IsContainer( ) ) { defaultVerb = MMC_VERB_OPEN; } WsbAffirmHr( m_pConsoleVerb->SetDefaultVerb( defaultVerb ) ); // Standard functionality NOT support by all items WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_RENAME, HIDDEN, TRUE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_COPY, HIDDEN, TRUE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PASTE, HIDDEN, TRUE ) ); WsbAffirmHr( m_pConsoleVerb->SetVerbState( MMC_VERB_PRINT, HIDDEN, TRUE ) ); // Extract data from the arg BOOL bScope = (BOOL) LOWORD(arg); BOOL bSelect = (BOOL) HIWORD(arg); if( bScope && bSelect ) { WsbAffirmHr( m_pSakData->GetCookieFromBaseHsm( pNode, &m_ActiveNodeCookie ) ); } } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::OnSelect", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::OnMinimize( IN IDataObject* pDataObject, IN LPARAM arg, IN LPARAM param ) /*++ Routine Description: Arguments: pNode - The node arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::OnMinimize", L"pDataObject = <0x%p>, arg = <%ld><0x%p>, param = <%ld><0x%p>", pDataObject, arg, arg, param, param ); HRESULT hr = S_OK; WsbTraceOut( L"CSakSnap::OnMinimize", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } HRESULT CSakSnap::EnumResultPane( IN ISakNode* pNode ) /*++ Routine Description: Insert the child items into the result pane. Arguments: pNode - The node which is expanding. arg - param - Return Value: S_OK - Created successfully. E_xxxxxxxxxxx - Failure occurred. --*/ { WsbTraceIn( L"CSakSnap::EnumResultPane", L"pNode = <0x%p>", pNode ); HRESULT hr = S_OK; try { WsbAffirmPointer( pNode ); CComPtr pResult; WsbAffirmHr( m_pConsole->QueryInterface( IID_IResultData, (void**)&pResult ) ); // // Clear the result pane // WsbAffirmHr( ClearResultPane() ); // // allocate and initialize a result item. // RESULTDATAITEM resultItem; memset( &resultItem, 0, sizeof(RESULTDATAITEM) ); // // Loop through this node's children (just one level deep). // if( pNode->IsContainer( ) == S_OK ) { CComPtr pEnum; // child enumerator CComPtr pNodeChild; // ISakNode pointer for the child // // Force a fresh list to be used - this way list is updated // WRT added or deleted nodes // if( S_OK == pNode->HasDynamicChildren( ) ) { WsbAffirmHr( m_pSakData->FreeEnumChildren( pNode ) ); WsbAffirmHr( pNode->InvalidateChildren() ) WsbAffirmHr( pNode->RefreshObject( ) ); } // // Enumerate and add in order // WsbAffirmHr( pNode->EnumChildren( &pEnum ) ); CComPtr pUnk; int virtIndex = 0; HRESULT hrEnum = S_OK; while( S_OK == hrEnum ) { // // Clear these from previous iterations // pUnk.Release( ); pNodeChild.Release( ); // // Get the next // hrEnum = pEnum->Next( 1, &pUnk, NULL ); WsbAffirmHr( hrEnum ); // // Did we just hit the end of the list? // if( S_FALSE == hrEnum ) { continue; } WsbAffirmHr( RsQueryInterface( pUnk, ISakNode, pNodeChild ) ); // // MMC will automatically put in items from the scope // pane so do not put these up. // if( pNodeChild->IsContainer( ) == S_OK ) { continue; } // // Put the first column of info into the result view. // memset( &resultItem, 0, sizeof(RESULTDATAITEM) ); resultItem.str = MMC_CALLBACK; resultItem.mask |= RDI_STR; // // stuff the child BaseHsm interface in the RESULTDATAITEM lParam. // WsbAffirmHr( m_pSakData->GetCookieFromBaseHsm( pNodeChild, (MMC_COOKIE*)( &resultItem.lParam ) ) ); resultItem.mask |= RDI_PARAM; WsbAffirmHr( pNodeChild->GetResultIcon( m_pSakData->m_State, &resultItem.nImage ) ); resultItem.mask |= RDI_IMAGE; pResult->InsertItem( &resultItem ); } } // Record the fact that this node is showing in the result pane m_pEnumeratedNode = pNode; } WsbCatch( hr ); WsbTraceOut( L"CSakSnap::EnumResultPane", L"hr = <%ls>", WsbHrAsString( hr ) ); return( hr ); } /*++ Routine Description: Calls MMC to clear out the result pane. Arguments: Return Value: S_OK - OK E_xxxxxxxxxxx - Failure occurred. --*/ HRESULT CSakSnap::ClearResultPane() { WsbTraceIn( L"CSakSnap::ClearResultPane", L""); HRESULT hr = S_OK; try { CComPtr pResult; WsbAffirmHr( m_pConsole->QueryInterface( IID_IResultData, (void**)&pResult ) ); WsbAffirmHr( pResult->DeleteAllRsltItems( ) ); m_pEnumeratedNode = NULL; } WsbCatch (hr); WsbTraceOut( L"CSakSnap::ClearResultPane", L"hr = <%ls>", WsbHrAsString( hr ) ); return hr; }