|
|
// stdcmpnt.cpp : Implementation of CComponent
#include "guidhelp.h" // ExtractData
// Note that m_pComponentData is still NULL during construction
CComponent::CComponent() : m_pConsole( NULL ), m_pConsoleVerb( NULL ), m_pHeader( NULL ), m_pResultData( NULL ), m_pConsoleNameSpace( NULL ), m_pRsltImageList( NULL ), m_pComponentData( NULL ) { }
CComponent::~CComponent() { VERIFY( SUCCEEDED(ReleaseAll()) ); }
/////////////////////////////////////////////////////////////////////
// CComponent::SetComponentDataPtr()
void CComponent::SetComponentDataPtr( CComponentData* pComponentData) { ASSERT(NULL != pComponentData && NULL == m_pComponentData); (void) ((IComponentData*)pComponentData)->AddRef(); m_pComponentData = pComponentData; }
/////////////////////////////////////////////////////////////////////
// CComponent::IComponent::QueryDataObject()
STDMETHODIMP CComponent::QueryDataObject(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject) { HRESULT hr = S_OK; MFC_TRY; // Delegate it to the IComponentData
hr = QueryBaseComponentDataRef().QueryDataObject(cookie, type, ppDataObject); MFC_CATCH; return hr; }
/////////////////////////////////////////////////////////////////////
// CComponent::IComponent::CompareObjects()
STDMETHODIMP CComponent::CompareObjects( LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB) { return QueryBaseComponentDataRef().CompareObjects( lpDataObjectA, lpDataObjectB ); }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_PROPERTY_CHANGE)
// OnPropertyChange() is generated by MMCPropertyChangeNotify( param )
HRESULT CComponent::OnPropertyChange( LPARAM /*param*/) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_SELECT)
HRESULT CComponent::OnNotifySelect( LPDATAOBJECT /*lpDataObject*/, BOOL /*fSelected*/ ) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_ACTIVATE)
HRESULT CComponent::OnNotifyActivate( LPDATAOBJECT /*lpDataObject*/, BOOL /*fActivated*/ ) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_CLICK)
HRESULT CComponent::OnNotifyClick( LPDATAOBJECT /*lpDataObject*/ ) { TRACE0("CComponent::OnNotifyClick().\n"); return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_DBLCLICK)
HRESULT CComponent::OnNotifyDblClick( LPDATAOBJECT /*lpDataObject*/ ) { // Returning S_FALSE allows MMC to do the default verb.
return S_FALSE; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_ADD_IMAGES)
HRESULT CComponent::OnNotifyAddImages( LPDATAOBJECT /*lpDataObject*/, LPIMAGELIST /*lpImageList*/, HSCOPEITEM /*hSelectedItem*/ ) { ASSERT(FALSE); // this should be redefined by all snapins
return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_VIEW_CHANGE)
// OnViewChange is generated by UpdateAllViews( lpDataObject, data, hint )
HRESULT CComponent::OnViewChange( LPDATAOBJECT /*lpDataObject*/, LPARAM /*data*/, LPARAM /*hint*/ ) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_REFRESH)
// OnNotifyRefresh is generated by enabling the verb MMC_VERB_REFRESH.
// Typically this routine will be overriden.
HRESULT CComponent::OnNotifyRefresh( LPDATAOBJECT /*lpDataObject*/ ) { TRACE0("CComponent::OnNotifyRefresh() - You must implement your own refresh routine.\n"); return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_DELETE)
HRESULT CComponent::OnNotifyDelete( LPDATAOBJECT /*lpDataObject*/ ) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// Virtual function called by CComponent::IComponent::Notify(MMCN_COLUMN_CLICK)
HRESULT CComponent::OnNotifyColumnClick( LPDATAOBJECT /*lpDataObject*/, LPARAM /*iColumn*/, LPARAM /*uFlags*/ ) { return S_OK; }
/////////////////////////////////////////////////////////////////////
// CComponent::ReleaseAll()
HRESULT CComponent::ReleaseAll() { MFC_TRY; TRACE_METHOD(CComponent,Destructor);
if (NULL != m_pHeader) m_pConsole->SetHeader(NULL);
SAFE_RELEASE(m_pHeader);
SAFE_RELEASE(m_pResultData); SAFE_RELEASE(m_pConsoleNameSpace); SAFE_RELEASE(m_pRsltImageList); SAFE_RELEASE(m_pConsole); SAFE_RELEASE(m_pConsoleVerb);
if ( NULL != m_pComponentData ) { ((IComponentData*)m_pComponentData)->Release(); m_pComponentData = NULL; }
MFC_CATCH; return S_OK; }
/////////////////////////////////////////////////////////////////////////////
// CComponent::IComponent::Initialize()
STDMETHODIMP CComponent::Initialize(LPCONSOLE lpConsole) { MFC_TRY; TRACE_METHOD(CComponent,Create); TEST_NONNULL_PTR_PARAM(lpConsole);
if (NULL == lpConsole) { ASSERT(FALSE); return E_POINTER; }
ASSERT( NULL == m_pConsole ); SAFE_RELEASE( m_pConsole ); // just in case
lpConsole->AddRef(); m_pConsole = lpConsole;
HRESULT hr = m_pConsole->QueryInterface(IID_IHeaderCtrl, (void**)&m_pHeader);
ASSERT(hr == S_OK); if (FAILED(hr)) return E_FAIL;
m_pConsole->SetHeader(m_pHeader);
hr = m_pConsole->QueryConsoleVerb(OUT &m_pConsoleVerb); ASSERT(hr == S_OK); if (FAILED(hr)) return hr; ASSERT(NULL != m_pConsoleVerb);
hr = m_pConsole->QueryInterface(IID_IResultData, (void**)&m_pResultData); if (FAILED(hr)) return hr;
hr = m_pConsole->QueryInterface(IID_IConsoleNameSpace, (void**)&m_pConsoleNameSpace); if (FAILED(hr)) return hr;
hr = m_pConsole->QueryInterface(IID_IImageList, (void**)&m_pRsltImageList); if (FAILED(hr)) return hr;
// Load icons for the scope pane
LPIMAGELIST pImageList; hr = m_pConsole->QueryScopeImageList(&pImageList); ASSERT(SUCCEEDED(hr)); // LoadIconsIntoImageList(pImageList, FALSE);
pImageList->Release();
MFC_CATCH; return S_OK; } // CComponent::Initialize()
/////////////////////////////////////////////////////////////////////////////
// CComponent::IComponent::Notify()
// Entry point for all the MMCN_ notification messages.
// The routine will then call virtual functions of the CComponent object.
STDMETHODIMP CComponent::Notify(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param) { HRESULT hr = S_OK; // MFC_TRY;
TRACE_METHOD(CComponent,Notify);
switch (event) { case MMCN_SHOW: // CODEWORK this is hacked together quickly
{ CCookie* pcookie = NULL; hr = ExtractData( lpDataObject, CDataObject::m_CFRawCookie, (PBYTE)&pcookie, sizeof(pcookie) ); ASSERT( SUCCEEDED(hr) ); CCookie* pActiveCookie = ActiveBaseCookie (pcookie); // Save the scope item handle in the cookie
pActiveCookie->m_hScopeItem = (HSCOPEITEM) param; hr = Show (pActiveCookie, arg, (HSCOPEITEM) param); } break;
case MMCN_MINIMIZED: break;
case MMCN_SELECT: hr = OnNotifySelect( lpDataObject, (BOOL)(HIWORD(arg)) ); break;
case MMCN_ACTIVATE: hr = OnNotifyActivate( lpDataObject, (BOOL)arg ); break;
case MMCN_ADD_IMAGES: hr = OnNotifyAddImages( lpDataObject, reinterpret_cast<IImageList*>(arg), (HSCOPEITEM)param ); break;
case MMCN_CLICK: hr = OnNotifyClick( lpDataObject ); break;
case MMCN_DBLCLICK: hr = OnNotifyDblClick( lpDataObject ); break;
case MMCN_PROPERTY_CHANGE: // CODEWORK arg is "fScopePane", should this be passed on?
hr = OnPropertyChange( param ); break;
case MMCN_VIEW_CHANGE: hr = OnViewChange( lpDataObject, arg, param ); break;
case MMCN_REFRESH: hr = OnNotifyRefresh( lpDataObject ); break;
case MMCN_DELETE: hr = OnNotifyDelete( lpDataObject ); break;
case MMCN_COLUMN_CLICK: hr = OnNotifyColumnClick( lpDataObject, arg, param ); break;
case MMCN_CONTEXTHELP: hr = OnNotifyContextHelp( lpDataObject ); break;
case MMCN_SNAPINHELP: hr = OnNotifySnapinHelp( lpDataObject ); break;
default: TRACE1("INFO: CComponent::Notify() - Unknown Event %d.\n", event); break; }
// MFC_CATCH;
return hr; } // CComponent::Notify()
// parameter "MMC_COOKIE cookie" is reserved per MSDN
STDMETHODIMP CComponent::Destroy(MMC_COOKIE /*cookie*/) { MFC_TRY; TRACE_METHOD(CComponent,Destroy);
VERIFY( SUCCEEDED( ReleaseAll() ) );
MFC_CATCH; return S_OK; }
HRESULT CComponent::InsertResultCookies( CCookie& refparentcookie ) { ASSERT( NULL != m_pResultData );
RESULTDATAITEM tRDItem; ::ZeroMemory( &tRDItem, sizeof(tRDItem) ); tRDItem.nCol = 0; tRDItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; tRDItem.str = MMC_CALLBACK; // CODEWORK should use MMC_ICON_CALLBACK here
HRESULT hr = S_OK; POSITION pos = refparentcookie.m_listResultCookieBlocks.GetHeadPosition(); while (NULL != pos) { CBaseCookieBlock* pblock = refparentcookie.m_listResultCookieBlocks.GetNext( pos ); ASSERT( NULL != pblock ); for (INT i = 0; i < pblock->QueryNumCookies(); i++) { CCookie* pbasecookie = pblock->QueryBaseCookie(i); tRDItem.nImage = QueryBaseComponentDataRef().QueryImage( *pbasecookie, FALSE ); // WARNING cookie cast
tRDItem.lParam = reinterpret_cast<LPARAM>(pbasecookie); hr = m_pResultData->InsertItem(&tRDItem); if ( FAILED(hr) ) { ASSERT(FALSE); break; } } } return hr; }
STDMETHODIMP CComponent::GetResultViewType(MMC_COOKIE /*cookie*/, BSTR* ppViewType, long* pViewOptions) { // ISSUE-2002/03/28-JonN check for NULL
*ppViewType = NULL; *pViewOptions = MMC_VIEW_OPTIONS_NONE; return S_FALSE; }
STDMETHODIMP CComponent::GetDisplayInfo(RESULTDATAITEM* pResultDataItem) { MFC_TRY; CCookie* pcookie = ActiveBaseCookie( reinterpret_cast<CCookie*>(pResultDataItem->lParam)); // ISSUE-2002/03/28-JonN handle NULL parameter
ASSERT( NULL != pResultDataItem ); // result items never have NULL cookie
if (RDI_STR & pResultDataItem->mask) { pResultDataItem->str = QueryBaseComponentDataRef().QueryResultColumnText( *pcookie, pResultDataItem->nCol ); if ( NULL == pResultDataItem->str ) pResultDataItem->str = L""; // just in case
} if ( RDI_IMAGE & pResultDataItem->mask ) { pResultDataItem->nImage = QueryBaseComponentDataRef().QueryImage( *pcookie, FALSE ); } MFC_CATCH; return S_OK; }
// CODEWORK These should be parameters rather than globals
// CODEWORK figure out correct const'ing
extern UINT** g_aColumns; extern int** g_aColumnWidths;
HRESULT CComponent::LoadColumnsFromArrays( INT objecttype ) { ASSERT( NULL != m_pHeader );
CString str; // ISSUE-2002/03/28-JonN check objecttype parameter
// ISSUE-2002/03/28-JonN should invoke AFX_MANAGE_STATE
const UINT* pColumns = g_aColumns[objecttype]; const int* pColumnWidths = g_aColumnWidths[objecttype]; ASSERT( NULL != pColumns && NULL != pColumnWidths ); for ( INT i = 0; 0 != pColumns[i]; i++) { VERIFY( str.LoadString( pColumns[i] ) ); m_pHeader->InsertColumn(i, const_cast<LPTSTR>((LPCTSTR)str), LVCFMT_LEFT, pColumnWidths[i]); }
return S_OK; }
HRESULT CComponent::OnNotifySnapinHelp (LPDATAOBJECT /*pDataObject*/) { return ShowHelpTopic( NULL ); // snapins should redefine this
}
HRESULT CComponent::OnNotifyContextHelp (LPDATAOBJECT pDataObject) { return OnNotifySnapinHelp( pDataObject ); // snapins should redefine this
}
HRESULT CComponent::ShowHelpTopic( LPCWSTR lpcwszHelpTopic ) { HRESULT hr = S_OK; MFC_TRY; CComQIPtr<IDisplayHelp,&IID_IDisplayHelp> spDisplayHelp = m_pConsole; if ( !spDisplayHelp ) { ASSERT(FALSE); return E_UNEXPECTED; }
CString strHelpTopic; hr = QueryBaseComponentDataRef().GetHtmlHelpFilePath( strHelpTopic ); if ( FAILED(hr) ) return hr; if (NULL != lpcwszHelpTopic && L'\0' != *lpcwszHelpTopic) { strHelpTopic += L"::/"; strHelpTopic += lpcwszHelpTopic; } hr = spDisplayHelp->ShowTopic (T2OLE ((LPWSTR)(LPCWSTR) strHelpTopic)); ASSERT (SUCCEEDED (hr));
MFC_CATCH; return hr; }
|