/*======================================================================================// | Process Control // | // |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. // | // |File Name: Component.cpp // | // |Description: // | // |Created: Paul Skoglund 07-1998 // | // |Rev History: // | // |=======================================================================================*/ #include "StdAfx.h" #include "ProcCon.h" #include "Component.h" #include "BaseNode.h" #include "DataObj.h" ///////////////////////////////////////////////////////////////////////////// // CComponent CComponent::CComponent() { ATLTRACE( _T("Component::Component\n")); m_ipConsole2 = NULL; m_ipHeaderCtrl2 = NULL; m_ipResultData = NULL; m_ipConsoleVerb = NULL; m_ipConsoleNameSpace2 = NULL; m_ipDisplayHelp = NULL; m_pCompData = NULL; // Points to parent object not an interface m_hbmp16x16 = NULL; m_hbmp32x32 = NULL; m_hSelectedScope = NULL; m_bInitializedAndNotDestroyed = FALSE; } // end Constructor() //--------------------------------------------------------------------------- // CComponent::~CComponent() { ATLTRACE( _T("Component::~Component\n") ); } // end Destructor() ///////////////////////////////////////////////////////////////////////////// // IComponent implementation // //--------------------------------------------------------------------------- // IComponent::Initialize is called when a snap-in is being created and // has items in the result pane to enumerate. The pointer to IConsole that // is passed in is used to make QueryInterface calls to the console for // interfaces such as IResultData. // STDMETHODIMP CComponent::Initialize ( LPCONSOLE ipConsole // [in] Pointer to IConsole's IUnknown interface ) { ATLTRACE( _T("Component::Initialize()\n") ); ASSERT( NULL != ipConsole ); HRESULT hr = S_OK; // Save away all the interfaces we'll need. // Fail if we can't QI the required interfaces. hr = ipConsole->QueryInterface( IID_IConsole2, (VOID**)&m_ipConsole2 ); if( FAILED(hr) ) return hr; hr = m_ipConsole2->QueryInterface( IID_IResultData, (VOID**)&m_ipResultData ); if( FAILED(hr) ) return hr; hr = m_ipConsole2->QueryInterface( IID_IHeaderCtrl2, (VOID**)&m_ipHeaderCtrl2 ); if( FAILED(hr) ) return hr; // Console needs the header else // control pointer m_ipConsole2->SetHeader( m_ipHeaderCtrl2 ); hr = m_ipConsole2->QueryConsoleVerb( &m_ipConsoleVerb ); if( FAILED(hr) ) return hr; hr = m_ipConsole2->QueryInterface( IID_IConsoleNameSpace2, (VOID**)&m_ipConsoleNameSpace2 ); if( FAILED(hr) ) return hr; hr = m_ipConsole2->QueryInterface( IID_IDisplayHelp, (VOID**)&m_ipDisplayHelp ); if( FAILED(hr) ) return hr; // Load the bitmaps from the dll for the results pane m_hbmp16x16 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_16x16)); ASSERT( m_hbmp16x16 ); m_hbmp32x32 = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDB_NODES_32x32)); ASSERT( m_hbmp32x32 ); m_bInitializedAndNotDestroyed = TRUE; return hr; } // end Initialize() //--------------------------------------------------------------------------- // Store the parent CComponetData object. // void CComponent::SetComponentData ( CComponentData* pCompData // [in] Parent CComponentData object ) { ATLTRACE( _T("Component::SetComponentData\n") ); ASSERT( NULL != pCompData ); ASSERT( NULL == m_pCompData ); // Can't do this twice m_pCompData = pCompData; // Cache a way to get to the // parent CComponentData } // end SetComponentData() //--------------------------------------------------------------------------- // Releases all references to the console. // Only the console should call this method. // STDMETHODIMP CComponent::Destroy ( MMC_COOKIE Cookie // Reserved, not in use at this time ) { ATLTRACE( _T("Component::Destroy\n") ); m_bInitializedAndNotDestroyed = FALSE; // Release the interfaces that we QI'ed m_ipConsole2->SetHeader(NULL); SAFE_RELEASE( m_ipHeaderCtrl2 ); SAFE_RELEASE( m_ipResultData ); SAFE_RELEASE( m_ipConsoleVerb ); SAFE_RELEASE( m_ipConsoleNameSpace2 ); SAFE_RELEASE( m_ipConsole2 ); SAFE_RELEASE( m_ipDisplayHelp ); if( NULL != m_hbmp16x16 ) DeleteObject(m_hbmp16x16); if( NULL != m_hbmp32x32 ) DeleteObject(m_hbmp32x32); return S_OK; } // end Destroy() //--------------------------------------------------------------------------- // Returns a data object that can be used to retrieve context information // for the specified cookie. //ok, now believe this interface is only queried about items added to the result pane. STDMETHODIMP CComponent::QueryDataObject ( MMC_COOKIE Cookie, // [in] Specifies the unique identifier DATA_OBJECT_TYPES Context, // [in] Type of data object LPDATAOBJECT* ppDataObject // [out] Points to address of returned data ) { if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } // check for magic multi-select cookie if (IS_SPECIAL_COOKIE(Cookie) ) { if (Cookie == MMC_MULTI_SELECT_COOKIE) ATLTRACE( _T("Component::QueryDataObject: MMC_MULTI_SELECT_COOKIE unimplemented\n") ); else ATLTRACE( _T("Component::QueryDataObject: special cookie %p unimplemented\n"), Cookie ); return E_UNEXPECTED; } ASSERT( CCT_SCOPE == Context || // Must have a context CCT_RESULT == Context || // we understand CCT_SNAPIN_MANAGER == Context ); if (Context == CCT_SCOPE) { ASSERT(FALSE); ATLTRACE( _T("Component::QueryDataObject: asking for CCT_SCOPE Context??\n") ); return m_pCompData->QueryDataObject(Cookie, Context, ppDataObject); } else if (Context == CCT_RESULT) { ATLTRACE( _T("Component::QueryDataObject: CCT_RESULT \n") ); CComObject* pDataObj; CComObject::CreateInstance( &pDataObj ); if( ! pDataObj ) // DataObject was not created { ASSERT(pDataObj); return E_OUTOFMEMORY; } // use selected node to get, "parent" folder SCOPEDATAITEM Item; memset(&Item, 0, sizeof(Item)); Item.mask = SDI_PARAM; Item.ID = m_hSelectedScope; if ( S_OK != m_ipConsoleNameSpace2->GetItem(&Item) ) return E_UNEXPECTED; CBaseNode *pFolder = reinterpret_cast(Item.lParam); pDataObj->SetDataObject( Context, pFolder, Cookie ); //ATLTRACE( _T("%s-Component::QueryDataObject: CCT_RESULT \n"), pFolder->GetNodeName() ); return pDataObj->QueryInterface( IID_IDataObject, reinterpret_cast(ppDataObject) ); } // else ... // CCT_SNAPIN_MANAGER // CCT_UNITIALIZED ASSERT( Context == 0); // return E_UNEXPECTED; } // end QueryDataObject() //--------------------------------------------------------------------------- // STDMETHODIMP CComponent::GetDisplayInfo ( LPRESULTDATAITEM pResultItem // [in,out] Type of info required ) { ASSERT( NULL != pResultItem ); if( NULL == pResultItem) return E_UNEXPECTED; if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } HRESULT hr = S_OK; // the RDI_PARAM flag does not have to be set on input to indicate that the LPARAM is valid //if (!(pResultItem->mask & RDI_PARAM)) // return E_UNEXPECTED; if (pResultItem->bScopeItem) { ASSERT(pResultItem->lParam); CBaseNode *pData= reinterpret_cast(pResultItem->lParam); if (!pData) return E_UNEXPECTED; hr = pData->GetDisplayInfo(*pResultItem); } else { SCOPEDATAITEM Item; memset(&Item, 0, sizeof(Item)); Item.mask = SDI_PARAM; Item.ID = m_hSelectedScope; if ( !m_hSelectedScope || S_OK != m_ipConsoleNameSpace2->GetItem(&Item) || !Item.lParam) return E_UNEXPECTED; CBaseNode *pData = reinterpret_cast(Item.lParam); hr = pData->GetDisplayInfo(*pResultItem); } return hr; } // end GetDisplayInfo() //--------------------------------------------------------------------------- // Determines what the result pane view should be // STDMETHODIMP CComponent::GetResultViewType ( MMC_COOKIE Cookie, // [in] Specifies the unique identifier BSTR* ppViewType, // [out] Points to address of the returned view type long* pViewOptions // [out] Pointer to the MMC_VIEW_OPTIONS enumeration ) { ATLTRACE(_T("Component::GetResultViewType Cookie 0x%lX\n"), Cookie); if (!Cookie) // root node *pViewOptions = MMC_VIEW_OPTIONS_NONE; else *pViewOptions = MMC_VIEW_OPTIONS_NOLISTVIEWS; return S_FALSE; // Ask for default listview. } // end GetResultViewType() //--------------------------------------------------------------------------- // // HRESULT CComponent::CompareObjects ( LPDATAOBJECT ipDataObjectA, // [in] First data object to compare LPDATAOBJECT ipDataObjectB // [in] Second data object to compare ) { ATLTRACE(_T("Component::CompareObjects\n")); if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } CDataObject *pdoA; CDataObject *pdoB; pdoA = ExtractOwnDataObject( ipDataObjectA ); pdoB = ExtractOwnDataObject( ipDataObjectB ); ASSERT( pdoA || pdoB ); // If extraction failed for one of them, then that one is foreign and // can't be equal to the other one. (Or else ExtractOwnDataObject // returned NULL because it ran out of memory, but the most conservative // thing to do in that case is say they're not equal.) if( !pdoA || !pdoB ) { ATLTRACE(_T("Component::CompareObjects() - FALSE one or both objects not recognized\n") ); return S_FALSE; } // If they differ then the objects refer to different things. CBaseNode *pNodeA = pdoA->GetBaseObject(); CBaseNode *pNodeB = pdoB->GetBaseObject(); if( pNodeA && pNodeB && pNodeA->GetNodeType() == pNodeB->GetNodeType() ) { if (!pdoA->IsResultItem() && !pdoB->IsResultItem()) { ATLTRACE(_T("Component::CompareObjects() - TRUE both nodes %s\n"), pNodeA->GetNodeName() ); return S_OK; } if ( pdoA->GetResultItemCookie() == pdoB->GetResultItemCookie() ) { ATLTRACE(_T("Component::CompareObjects() - TRUE both %s\n"), pNodeA->GetNodeName() ); return S_OK; } ATLTRACE(_T("Component::CompareObjects() - FALSE both %s\n"), pNodeA->GetNodeName() ); } else { ATLTRACE(_T("Component::CompareObjects() - FALSE\n") ); } return S_FALSE; } // end CompareObjects() //--------------------------------------------------------------------------- // Handle notifications from the console // STDMETHODIMP CComponent::Notify ( LPDATAOBJECT ipDataObject, // [in] Points to data object MMC_NOTIFY_TYPE Event, // [in] Identifies action taken by user LPARAM Arg, // [in] Depends on the notification type LPARAM Param // [in] Depends on the notification type ) { ATLTRACE( _T("Component::Notify %p 0x%X %p %p\n"), ipDataObject, Event, Arg, Param ); if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } HRESULT hr = S_OK; /* // not all notifies set ipDataObject... MMCN_ACTIVATE MMCN_BTN_CLICK //MMCN_CLICK MMCN_COLUMN_CLICK //MMCN_CONTEXTMENU MMCN_CUTORMOVE MMCN_DELETE MMCN_EXPAND //MMCN_HELP MMCN_MENU_BTNCLICK MMCN_PASTE MMCN_QUERY_PASTE MMCN_REMOVE_CHILDREN MMCN_RENAME MMCN_SELECT MMCN_SHOW MMCN_VIEW_CHANGE MMCN_SNAPINHELP MMCN_CONTEXTHELP MMCN_INITOCX MMCN_FILTER_CHANGE MMCN_FILTERBTN_CLICK MMCN_RESTORE_VIEW MMCN_PRINT MMCN_PRELOAD MMCN_LISTPAD */ CDataObject* pDO = NULL; CBaseNode *pNode = NULL; MMC_NOTIFY_TYPE NeedDataObject[] = { MMCN_VIEW_CHANGE, MMCN_SHOW, MMCN_DBLCLICK, MMCN_SELECT, MMCN_REFRESH, MMCN_DELETE, MMCN_CONTEXTHELP }; for(int i = 0; i < ARRAY_SIZE(NeedDataObject); i++) { if (Event == NeedDataObject[i]) { pDO = ExtractOwnDataObject(ipDataObject); pNode = ExtractBaseObject(ipDataObject); if (!pDO || !pNode) { ASSERT(FALSE); return E_UNEXPECTED; } break; } } switch( Event ) { case MMCN_ADD_IMAGES: //ok hr = OnAddImages( ipDataObject, (IImageList *) Arg, Param ); break; case MMCN_SHOW: //ok //ATLTRACE( _T("Component::Notify: MMCN_SHOW\n") ); hr = OnShow( ipDataObject, (BOOL) Arg, Param ); break; case MMCN_SELECT: //fair //ATLTRACE( _T("Component::Notify: MMCN_SELECT\n") ); hr = OnSelect( ipDataObject, Arg, Param ); break; case MMCN_REFRESH: //ATLTRACE( _T("Component::Notify: MMCN_REFRESH\n") ); hr = OnRefresh( ipDataObject ); break; case MMCN_DELETE: // Arg and Param have no meaning if (pNode && pDO->IsResultItem() ) hr = pNode->OnDelete(m_ipConsole2, pDO->GetResultItemCookie()); else hr = E_UNEXPECTED; break; case MMCN_VIEW_CHANGE: ATLTRACE( _T("Component::Notify: MMCN_VIEW_CHANGE\n") ); if (m_hSelectedScope == pNode->GetID() ) hr = pNode->OnViewChange(m_ipResultData, Arg, Param); break; case MMCN_PROPERTY_CHANGE: ATLTRACE( _T("Component::Notify: MMCN_PROPERTY_CHANGE\n") ); hr = OnPropertyChange( (BOOL) Arg, Param); break; case MMCN_HELP: // obsolete ATLTRACE( _T("Component::Notify: MMCN_HELP unimplemented\n") ); hr = S_FALSE; break; case MMCN_SNAPINHELP: // obsolete // 11/1998 // nolonger used: implement ISnapinHelp interface, then MMC will merge the snapin's help and MMC help ATLTRACE( _T("Component::Notify: MMCN_SNAPINHELP unimplemented\n") ); hr = S_FALSE; break; case MMCN_CONTEXTHELP: // return S_FALSE for default behavior... actually, any return value other than S_OK // invokes HTMLHelp with MMC overview topic. ATLTRACE( _T("Component::Notify: MMCN_CONTEXTHELP\n") ); if (pNode) hr = pNode->OnHelpCmd(m_ipDisplayHelp ); else hr = E_UNEXPECTED; break; case MMCN_CLICK: ATLTRACE( _T("Component::Notify: MMCN_CLICK unimplemented\n") ); break; case MMCN_DBLCLICK: // return S_FALSE to have MMC do the default verb action... if (pNode && pDO->IsResultItem() ) hr = pNode->OnDblClick(m_ipConsole2, pDO->GetResultItemCookie()); else hr = S_FALSE; break; case MMCN_ACTIVATE: ATLTRACE( _T("Component::Notify: MMCN_ACTIVATE (%s) unimplemented\n"), Arg ? _T("activate") : _T("deactivate") ); break; case MMCN_MINIMIZED: ATLTRACE( _T("Component::Notify: MMCN_MINIMIZED unimplemented\n") ); break; case MMCN_BTN_CLICK: ATLTRACE( _T("Component::Notify: MMCN_BTN_CLICK unimplemented\n") ); break; case MMCN_COLUMN_CLICK: ATLTRACE( _T("Component::Notify: MMCN_COLUMN_CLICK col: %p %s\n"), Arg, (Param == RSI_DESCENDING ) ? _T("Descending") : _T("Ascending") ); break; case MMCN_COLUMNS_CHANGED: ATLTRACE( _T("Component::Notify: MMCN_COLUMNS_CHANGED Arg: %p, Param: %p\n"), Arg, Param ); hr = S_OK; break; default: ATLTRACE( _T("Component::Notify: unhandled notify event 0x%X\n"), Event ); hr = S_OK; break; } return hr; } // end Notify() ///////////////////////////////////////////////////////////////////////////// // Support methods // //--------------------------------------------------------------------------- // handle the MMCN_SHOW message. // HRESULT CComponent::OnShow ( LPDATAOBJECT ipDataObject, // [in] Points to data object BOOL bSelected, // [in] selected/deselected scope HSCOPEITEM hScopeID // [in] HSCOPEITEM ) { ASSERT( NULL != ipDataObject ); ASSERT( NULL != m_ipResultData ); CBaseNode *pNode = ExtractBaseObject( ipDataObject) ; ASSERT(pNode); if (!pNode) { m_hSelectedScope = NULL; return S_FALSE; } ATLTRACE(_T("%s-MMCN_SHOW Selected=%s\n"), pNode->GetNodeName(), (bSelected ? _T("true") : _T("false")) ); if (!bSelected) // deselected scope pane item m_hSelectedScope = NULL; else // selected scope pane item { VERIFY(S_OK == m_ipResultData->SetViewMode( MMCLV_VIEWSTYLE_REPORT ) ); m_hSelectedScope = hScopeID; } CJobFolder *pJobFolder = dynamic_cast (pNode); if (pJobFolder) return pJobFolder->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2, m_ipConsoleNameSpace2); CJobItemFolder *pJobItemFolder = dynamic_cast (pNode); if (pJobItemFolder) return pJobItemFolder->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2, m_ipConsoleNameSpace2); return pNode->OnShow(bSelected, hScopeID, m_ipHeaderCtrl2, m_ipConsole2); } // end OnShow() //--------------------------------------------------------------------------- // HRESULT CComponent::OnAddImages ( LPDATAOBJECT ipDataObject, // [in] Points to the data object IImageList *ipImageList, // [in] Interface pointer to IImageList HSCOPEITEM hID // [in] HSCOPEITEM of item currently selected or deselected ) { ASSERT( ipImageList ); if (!ipImageList) return E_UNEXPECTED; HRESULT hr = ipImageList->ImageListSetStrip( (LONG_PTR *) m_hbmp16x16, (LONG_PTR *) m_hbmp32x32, 0, RGB(255,0, 255) ); ASSERT( S_OK == hr ); return hr; } // end OnAddImages() //--------------------------------------------------------------------------- // This is a handler for the MMCN_SELECT notification. // MMC 1.1 documentation for IComponent::Notify MMCN_SELECT // claims the LPDATAOBJECT is for the scope item but // in reality appears to be the dataobject for whatever item/node is selected // HRESULT CComponent::OnSelect ( LPDATAOBJECT ipDataObject, // [in] Points to the data object LPARAM Arg, // [in] Contains flags about the selected item LPARAM Param // [in] Not used ) { CDataObject *pDO = ExtractOwnDataObject( ipDataObject ); CBaseNode *pNode = ExtractBaseObject( ipDataObject); if( !m_ipConsoleVerb || !pDO || !pNode) return E_UNEXPECTED; ATLTRACE(_T("%s-MMCN_SELECT: Scope=%s, Select=%s, ResultItem=%s\n"), pNode->GetNodeName(), (LOWORD(Arg) ? _T("true") : _T("false")), (HIWORD(Arg) ? _T("true") : _T("false")), pDO->IsResultItem() ? _T("yes") : _T("no")); ASSERT(!(pDO->IsResultItem()) == (BOOL) LOWORD(Arg) ); if (pDO->IsResultItem()) return pNode->OnSelect(LOWORD(Arg), HIWORD(Arg), m_ipConsoleVerb, pDO->GetResultItemCookie()); else return pNode->OnSelect(LOWORD(Arg), HIWORD(Arg), m_ipConsoleVerb); } // end OnSelect() //--------------------------------------------------------------------------- // MMCN_REFRESH notification // HRESULT CComponent::OnRefresh ( LPDATAOBJECT ipDataObject // [in] Points to the data object ) { CBaseNode* pNode = ExtractBaseObject( ipDataObject ); ASSERT(pNode); if (!pNode ) return E_UNEXPECTED; ATLTRACE( _T("%s-Component::Notify: MMCN_REFRESH\n"), pNode->GetNodeName() ); if (m_hSelectedScope != pNode->GetID() ) { ATLTRACE( _T("Attempt patch of framework!\n")); //OnShow(ipDataObject, TRUE, pNode->GetID()); m_ipConsole2->SelectScopeItem(pNode->GetID()); } CJobFolder *pJobFolder = dynamic_cast (pNode); if (pJobFolder) return pJobFolder->OnRefresh(m_ipConsole2, m_ipConsoleNameSpace2); return pNode->OnRefresh(m_ipConsole2); } // end OnRefresh() //--------------------------------------------------------------------------- // MMCN_PROPERTY_CHANGE notification // HRESULT CComponent::OnPropertyChange ( BOOL bScopeItem, LPARAM Param ) { if (bScopeItem) { ASSERT(FALSE); // what is this path being used by? return S_OK; } PROPERTY_CHANGE_HDR *pUpdate = reinterpret_cast(Param); if (pUpdate ) { if (pUpdate->pFolder && !pUpdate->bScopeItem) { SCOPEDATAITEM Item; memset(&Item, 0, sizeof(Item)); Item.mask = SDI_PARAM; Item.ID = m_hSelectedScope; if ( m_hSelectedScope && S_OK == m_ipConsoleNameSpace2->GetItem(&Item) && reinterpret_cast(Item.lParam) == pUpdate->pFolder ) { pUpdate->pFolder->OnPropertyChange(pUpdate, m_ipConsole2); } } pUpdate = FreePropChangeInfo(pUpdate); } return S_OK; } // end OnPropertyChange() #ifdef USE_IRESULTDATACOMPARE ///////////////////////////////////////////////////////////////////////////// // IResultDataCompare method implementations // STDMETHODIMP CComponent::Compare(LPARAM lUserParam, MMC_COOKIE cookieA, MMC_COOKIE cookieB, int * pnResult ) { ATLTRACE( _T("Component::Compare %p %p %p\n"), lUserParam, cookieA, cookieB ); SCOPEDATAITEM Item; memset(&Item, 0, sizeof(Item)); Item.mask = SDI_PARAM; Item.ID = m_hSelectedScope; if ( S_OK != m_ipConsoleNameSpace2->GetItem(&Item) ) return E_UNEXPECTED; CBaseNode *pFolder = reinterpret_cast(Item.lParam); if (!pFolder) return E_UNEXPECTED; return pFolder->ResultDataCompare(lUserParam, cookieA, cookieB, pnResult); } #endif ///////////////////////////////////////////////////////////////////////////// // IExtendContextMenu method implementations // STDMETHODIMP CComponent::AddMenuItems ( LPDATAOBJECT ipDataObject, // [in] Points to data object LPCONTEXTMENUCALLBACK piCallback, // [in] Pointer to IContextMenuCallback long* pInsertionAllowed // [in,out] Insertion flags ) { ASSERT( NULL != ipDataObject ); if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } if (IsMMCMultiSelectDataObject(ipDataObject)) return E_UNEXPECTED; CDataObject *pDO; CBaseNode *pNode; VERIFY(pDO = ExtractOwnDataObject( ipDataObject )); VERIFY(pNode = ExtractBaseObject( ipDataObject )); if (!pDO || !pNode) return E_UNEXPECTED; if (pDO->IsResultItem()) return pNode->AddMenuItems(piCallback, pInsertionAllowed, pDO->GetResultItemCookie() ); else return pNode->AddMenuItems(piCallback, pInsertionAllowed ); } // end AddMenuItems() ///////////////////////////////////////////////////////////////////////////// // IExtendContextMenu method implementations // STDMETHODIMP CComponent::Command ( long nCommandID, // [in] Command to handle LPDATAOBJECT ipDataObject // [in] Points to data object, pass through ) { if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } HRESULT hr = S_FALSE; CDataObject *pDO = ExtractOwnDataObject( ipDataObject ); CBaseNode *pNode = ExtractBaseObject( ipDataObject); if (!pDO || !pNode) return S_FALSE; if ( pDO->IsResultItem() ) hr = pNode->OnMenuCommand(m_ipConsole2, nCommandID, pDO->GetResultItemCookie() ); else { CJobFolder *pJobFolder = dynamic_cast (pNode); if (pJobFolder) hr = pJobFolder->OnMenuCommand(m_ipConsole2, m_ipConsoleNameSpace2, nCommandID); else hr = pNode->OnMenuCommand(m_ipConsole2, nCommandID ); } if (hr == S_OK) // already successfully handled return hr; ATLTRACE(_T("Component::Command - unrecognized or failed command %d\n"), nCommandID); return hr; } // end Command() ///////////////////////////////////////////////////////////////////////////// // IExtendPropertySheet2 implementation // //--------------------------------------------------------------------------- // The console calls this method to determine whether the Properties menu // item should be added to the context menu. We added the Properties item // by enabling the verb. So long as we have a vaild DataObject we // can return OK. // HRESULT CComponent::QueryPagesFor ( LPDATAOBJECT ipDataObject // [in] Points to IDataObject for selected node ) { if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } CDataObject *pDO = ExtractOwnDataObject( ipDataObject ); CBaseNode *pNode = ExtractBaseObject( ipDataObject); if (!pDO || !pNode) return S_FALSE; if (pDO->IsResultItem()) return pNode->QueryPagesFor(pDO->GetResultItemCookie()); else return pNode->QueryPagesFor(); } // end QueryPagesFor() HRESULT CComponent::CreatePropertyPages ( LPPROPERTYSHEETCALLBACK lpProvider, // Pointer to the callback interface LONG_PTR handle, // Handle for routing notification LPDATAOBJECT ipDataObject // Pointer to the data object ) { ASSERT( NULL != lpProvider ); if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } CDataObject *pDO = ExtractOwnDataObject( ipDataObject ); CBaseNode *pNode = ExtractBaseObject( ipDataObject); if (!pDO || !pNode) return S_FALSE; if (pDO->IsResultItem()) return pNode->OnCreatePropertyPages(lpProvider, handle, pDO->GetContext(), pDO->GetResultItemCookie()); else return pNode->OnCreatePropertyPages(lpProvider, handle, pDO->GetContext()); } // end CreatePropertyPages() HRESULT CComponent::GetWatermarks ( LPDATAOBJECT lpIDataObject, HBITMAP *lphWatermark, HBITMAP * lphHeader, HPALETTE * lphPalette, BOOL* bStretch ) { ATLTRACE(_T("\n\nComponent::GetWatermarks\n\n")); if (!m_bInitializedAndNotDestroyed) { ASSERT(FALSE); return E_UNEXPECTED; } // no indication this method has ever been invoked *lphWatermark = NULL; *lphHeader = NULL; *lphPalette = NULL; *bStretch = FALSE; return S_OK; } // end GetWatermarks()