windows-nt/Source/XPSP1/NT/admin/snapin/framewrk/inc/stdcmpnt.cpp
2020-09-26 16:20:57 +08:00

454 lines
12 KiB
C++

// 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;
HRESULT 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)
{
*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));
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;
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;
}