Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1028 lines
26 KiB

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1998 **/
/**********************************************************************/
/*
ccompont.cpp
base classes for IComponent and IComponentData
FILE HISTORY:
*/
#include "stdafx.h"
#include "extract.h"
#include "compdata.h"
#include "proppage.h"
#include "tregkey.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*!--------------------------------------------------------------------------
FUseTaskpadsByDefault
See comments in header file.
Author: KennT
---------------------------------------------------------------------------*/
BOOL FUseTaskpadsByDefault(LPCTSTR pszMachineName)
{
static DWORD s_dwStopTheInsanity = 42;
RegKey regkeyMMC;
DWORD dwErr;
if (s_dwStopTheInsanity == 42)
{
// Set the default to FALSE (i.e. use taskpads by default)
// ------------------------------------------------------------
s_dwStopTheInsanity = 0;
dwErr = regkeyMMC.Open(HKEY_LOCAL_MACHINE,
_T("Software\\Microsoft\\MMC"),
KEY_READ, pszMachineName);
if (dwErr == ERROR_SUCCESS)
{
regkeyMMC.QueryValue(_T("TFSCore_StopTheInsanity"), s_dwStopTheInsanity);
}
}
return !s_dwStopTheInsanity;
}
/*!--------------------------------------------------------------------------
IComponentData implementation
---------------------------------------------------------------------------*/
DEBUG_DECLARE_INSTANCE_COUNTER(TFSComponentData);
/*!--------------------------------------------------------------------------
TFSComponentData::TFSComponentData
Constructor.
Author: KennT
---------------------------------------------------------------------------*/
TFSComponentData::TFSComponentData()
: m_cRef(1),
m_pWatermarkInfo(NULL)
{
DEBUG_INCREMENT_INSTANCE_COUNTER(TFSComponentData);
m_hWnd = NULL;
m_bFirstTimeRun = FALSE;
m_fTaskpadInitialized = FALSE;
}
/*!--------------------------------------------------------------------------
TFSComponentData::~TFSComponentData
Destructor
Author: KennT
---------------------------------------------------------------------------*/
TFSComponentData::~TFSComponentData()
{
DEBUG_DECREMENT_INSTANCE_COUNTER(TFSComponentData);
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (m_hiddenWnd.GetSafeHwnd())
::DestroyWindow(m_hiddenWnd.GetSafeHwnd());
Assert(m_cRef == 0);
}
/*!--------------------------------------------------------------------------
TFSComponentData::Construct
Call this to fully initialize this object.
Author: KennT
---------------------------------------------------------------------------*/
HRESULT TFSComponentData::Construct(ITFSCompDataCallback *pCallback)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
m_spCallback.Set(pCallback);
// Create the node mgr
CORg( CreateTFSNodeMgr(&m_spNodeMgr,
(IComponentData *) this,
m_spConsole,
m_spConsoleNameSpace));
// Initialize the node manager by pasing the ptr to ourselves
// in
CORg( m_spCallback->OnInitializeNodeMgr(
static_cast<ITFSComponentData *>(this),
m_spNodeMgr) );
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
IMPLEMENT_ADDREF_RELEASE(TFSComponentData)
/*!--------------------------------------------------------------------------
TFSComponentData::QueryInterface
Implementation of IUnknown::QueryInterface
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::QueryInterface(REFIID riid, LPVOID *ppv)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// Is the pointer bad?
if (ppv == NULL)
return E_INVALIDARG;
// Place NULL in *ppv in case of failure
*ppv = NULL;
// This is the non-delegating IUnknown implementation
if (riid == IID_IUnknown)
*ppv = (LPVOID) this;
else if (riid == IID_IComponentData)
*ppv = (IComponentData *) this;
else if (riid == IID_IExtendPropertySheet)
*ppv = (IExtendPropertySheet *) this;
else if (riid == IID_IExtendPropertySheet2)
*ppv = (IExtendPropertySheet2 *) this;
else if (riid == IID_IExtendContextMenu)
*ppv = (IExtendContextMenu *) this;
else if (riid == IID_IPersistStreamInit)
*ppv = (IPersistStreamInit *) this;
else if (riid == IID_ISnapinHelp)
*ppv = (ISnapinHelp *) this;
else if (riid == IID_ITFSComponentData)
*ppv = (ITFSComponentData *) this;
// If we're going to return an interface, AddRef it first
if (*ppv)
{
((LPUNKNOWN) *ppv)->AddRef();
return hrOK;
}
else
return E_NOINTERFACE;
}
TFSCORE_API(HRESULT) ExtractNodeFromDataObject(ITFSNodeMgr *pNodeMgr,
const CLSID *pClsid,
LPDATAOBJECT pDataObject,
BOOL fCheckForCreate,
ITFSNode **ppNode,
DWORD *pdwType,
INTERNAL **ppInternal)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(pNodeMgr);
Assert(pClsid);
Assert(ppNode);
SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
BOOL bExtension;
MMC_COOKIE cookie;
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
HRESULT hr = hrOK;
// Set the default value
if (pdwType)
*pdwType |= TFS_COMPDATA_NORMAL;
if (ppInternal)
*ppInternal = NULL;
//
// No pInternal means that we are an extension and this is
// our root node... translate by calling find object
//
// Check the CLSID for a match (because we are in shared code
// multiple snapins are using the SNAPIN_INTERNAL format). Thus
// we need to do an extra check to make sure that this is really us.
//
if ((spInternal == NULL) || (*pClsid != spInternal->m_clsid) )
{
CORg( pNodeMgr->GetRootNode(&spNode) );
if (pdwType)
{
*pdwType |= (TFS_COMPDATA_EXTENSION | TFS_COMPDATA_UNKNOWN_DATAOBJECT);
}
}
else
{
DATA_OBJECT_TYPES type = spInternal->m_type;
if (fCheckForCreate && type == CCT_SNAPIN_MANAGER)
{
CORg( pNodeMgr->GetRootNode(&spNode) );
//$ Review (kennt): is this always true, can we always
// depend on a create node being available?
Assert(spNode);
if (pdwType)
*pdwType |= TFS_COMPDATA_CREATE;
}
else
{
if (pdwType && (spInternal->m_clsid != *pClsid))
*pdwType |= TFS_COMPDATA_EXTENSION;
cookie = spInternal->m_cookie;
CORg( pNodeMgr->FindNode(cookie, &spNode) );
Assert((MMC_COOKIE) spNode->GetData(TFS_DATA_COOKIE) == cookie);
}
}
if (ppInternal)
*ppInternal = spInternal.Transfer();
*ppNode = spNode.Transfer();
Error:
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::Initialize
Implementation of IComponentData::Initialize
MMC calls this to initialize the IComponentData interface
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::Initialize
(
LPUNKNOWN pUnk
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(pUnk != NULL);
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
// MMC should only call ::Initialize once!
Assert(m_spConsoleNameSpace == NULL);
pUnk->QueryInterface(IID_IConsoleNameSpace2,
reinterpret_cast<void**>(&m_spConsoleNameSpace));
Assert(m_spConsoleNameSpace);
// add the images for the scope tree
SPIImageList spScopeImageList;
CORg( pUnk->QueryInterface(IID_IConsole2,
reinterpret_cast<void**>(&m_spConsole)) );
CORg( m_spConsole->QueryScopeImageList(&spScopeImageList) );
// call the derived class
Assert(m_spCallback);
CORg( m_spCallback->OnInitialize(spScopeImageList) );
// Create the utility members
if (!m_hiddenWnd.GetSafeHwnd())
{
if (!m_hiddenWnd.Create())
{
Trace0("Failed to create hidden window\n");
CORg( E_FAIL );
}
m_hWnd = m_hiddenWnd.GetSafeHwnd();
}
Assert(m_hWnd);
// Setup the node mgr
// As strange as it seems, the Initialize() method is not
// necessarily the first function called.
Assert(m_spNodeMgr);
m_spNodeMgr->SetConsole(m_spConsoleNameSpace, m_spConsole);
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
if (!FHrSucceeded(hr))
{
m_spNodeMgr.Release();
m_spConsoleNameSpace.Release();
m_spConsole.Release();
}
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::CreateComponent
Implementation of IComponentData::CreateComponent
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::CreateComponent(LPCOMPONENT *ppComponent)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
return m_spCallback->OnCreateComponent(ppComponent);
}
/*!--------------------------------------------------------------------------
TFSComponentData::Notify
Implementation of IComponentData::Notify
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::Notify(LPDATAOBJECT lpDataObject,
MMC_NOTIFY_TYPE event,
LPARAM arg, LPARAM lParam)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
Assert(m_spConsoleNameSpace != NULL);
HRESULT hr = hrOK;
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
DWORD dwType = 0;
COM_PROTECT_TRY
{
if (event == MMCN_PROPERTY_CHANGE)
{
hr = m_spCallback->OnNotifyPropertyChange(lpDataObject, event, arg, lParam);
if (hr != E_NOTIMPL)
{
return hr;
}
CPropertyPageHolderBase * pHolder =
reinterpret_cast<CPropertyPageHolderBase *>(lParam);
spNode = pHolder->GetNode();
}
else
{
//
// Since it's my folder it has an internal format.
// Design Note: for extension. I can use the fact, that the
// data object doesn't have my internal format and I should
// look at the node type and see how to extend it.
//
CORg( ExtractNodeFromDataObject(m_spNodeMgr,
m_spCallback->GetCoClassID(),
lpDataObject,
FALSE,
&spNode,
&dwType,
NULL) );
}
// pass the event to the event handler
Assert(spNode);
CORg( spNode->GetHandler(&spNodeHandler) );
CORg( spNodeHandler->Notify(spNode, lpDataObject, dwType, event, arg, lParam) );
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::Destroy
Implementation of IComponentData::Destroy
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::Destroy()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SPITFSNode spNode;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
if (m_spCallback)
m_spCallback->OnDestroy();
m_spConsole.Release();
m_spConsoleNameSpace.Release();
if (m_spNodeMgr)
{
m_spNodeMgr->GetRootNode(&spNode);
if (spNode)
{
spNode->DeleteAllChildren(FALSE);
spNode->Destroy();
}
spNode.Release();
m_spNodeMgr->SetRootNode(NULL);
}
m_spNodeMgr.Release();
m_spCallback.Release();
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::QueryDataObject
Implementation of IComponentData::QueryDataObject
MMC calls this to get a data object from us to hand us data in
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::QueryDataObject(MMC_COOKIE cookie,
DATA_OBJECT_TYPES type,
LPDATAOBJECT *ppDataObject)
{
return m_spCallback->OnCreateDataObject(cookie, type, ppDataObject);
}
/*!--------------------------------------------------------------------------
TFSComponentData::CompareObjects
Implementation of IComponentData::CompareObject
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::CompareObjects(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (lpDataObjectA == NULL || lpDataObjectB == NULL)
return E_POINTER;
// Make sure both data object are mine
SPINTERNAL spA;
SPINTERNAL spB;
HRESULT hr = S_FALSE;
COM_PROTECT_TRY
{
spA = ExtractInternalFormat(lpDataObjectA);
spB = ExtractInternalFormat(lpDataObjectA);
if (spA != NULL && spB != NULL)
hr = (*spA == *spB) ? S_OK : S_FALSE;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::GetDisplayInfo
Implementation of IComponentData::GetDisplayInfo
MMC calls this to get the display string for scope items
Author: KennT
---------------------------------------------------------------------------*/
STDMETHODIMP TFSComponentData::GetDisplayInfo(LPSCOPEDATAITEM pScopeDataItem)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
wchar_t* pswzString = NULL;
Assert(pScopeDataItem != NULL);
SPITFSNode spNode;
MMC_COOKIE cookie = pScopeDataItem->lParam;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
m_spNodeMgr->FindNode(cookie, &spNode);
pswzString = const_cast<LPTSTR>(spNode->GetString(0));
Assert(pswzString != NULL);
//$ Review (kennt) : will need to convert string to Wide from Tchar
//$ Review (kennt) : when do we free this string up?
if (*pswzString != NULL)
pScopeDataItem->displayname = pswzString;
}
COM_PROTECT_CATCH;
return hr;
}
/*---------------------------------------------------------------------------
IExtendPropertySheet Implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
TFSComponentData::CreatePropertyPages
Implementation of IExtendPropertySheet::CreatePropertyPages
Called for a node to put up property pages
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::CreatePropertyPages
(
LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
LPDATAOBJECT pDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
HRESULT hr = hrOK;
DWORD dwType = 0;
SPINTERNAL spInternal;
COM_PROTECT_TRY
{
spInternal = ExtractInternalFormat(pDataObject);
// this was an object created by the modal wizard, do nothing
if (spInternal && spInternal->m_type == CCT_UNINITIALIZED)
{
return hr;
}
CORg( ExtractNodeFromDataObject(m_spNodeMgr,
m_spCallback->GetCoClassID(),
pDataObject,
TRUE, &spNode, &dwType, NULL) );
//
// Create the property page for a particular node
//
CORg( spNode->GetHandler(&spNodeHandler) );
CORg( spNodeHandler->CreatePropertyPages(spNode, lpProvider,
pDataObject,
handle, dwType) );
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::QueryPagesFor
Implementation of IExtendPropertySheet::QueryPagesFor
MMC calls this to see if a node has property pages
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::QueryPagesFor
(
LPDATAOBJECT pDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
DATA_OBJECT_TYPES type;
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
DWORD dwType = 0;
SPINTERNAL spInternal;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
spInternal = ExtractInternalFormat(pDataObject);
// this was an object created by the modal wizard, do nothing
if (spInternal && spInternal->m_type == CCT_UNINITIALIZED)
{
return hr;
}
CORg( ExtractNodeFromDataObject(m_spNodeMgr,
m_spCallback->GetCoClassID(),
pDataObject,
TRUE, &spNode, &dwType, NULL) );
if (spInternal)
type = spInternal->m_type;
else
type = CCT_SCOPE;
CORg( spNode->GetHandler(&spNodeHandler) );
CORg( spNodeHandler->HasPropertyPages(spNode, pDataObject,
type, dwType) );
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::GetWatermarks
Implementation of IExtendPropertySheet::Watermarks
MMC calls this for wizard 97 info
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::GetWatermarks
(
LPDATAOBJECT pDataObject,
HBITMAP * lphWatermark,
HBITMAP * lphHeader,
HPALETTE * lphPalette,
BOOL * bStretch
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
// set some defaults
*lphWatermark = NULL;
*lphHeader = NULL;
*lphPalette = NULL;
*bStretch = FALSE;
if (m_pWatermarkInfo)
{
*lphWatermark = m_pWatermarkInfo->hWatermark;
*lphHeader = m_pWatermarkInfo->hHeader;
*lphPalette = m_pWatermarkInfo->hPalette;
*bStretch = m_pWatermarkInfo->bStretch;
}
}
COM_PROTECT_CATCH;
return hr;
}
/*---------------------------------------------------------------------------
IExtendContextMenu implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
TFSComponentData::AddMenuItems
Implementation of IExtendContextMenu::AddMenuItems
MMC calls this so that a node can add menu items to a context menu
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::AddMenuItems
(
LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pContextMenuCallback,
long * pInsertionAllowed
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
SPINTERNAL spInternal;
DATA_OBJECT_TYPES type;
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
DWORD dwType;
COM_PROTECT_TRY
{
CORg( ExtractNodeFromDataObject(m_spNodeMgr,
m_spCallback->GetCoClassID(),
pDataObject,
FALSE, &spNode, &dwType,
&spInternal) );
type = (spInternal ? spInternal->m_type : CCT_SCOPE);
// Note - snap-ins need to look at the data object and determine
// in what context, menu items need to be added. They must also
// observe the insertion allowed flags to see what items can be
// added.
CORg( spNode->GetHandler(&spNodeHandler) );
hr = spNodeHandler->OnAddMenuItems(spNode, pContextMenuCallback,
pDataObject,
type,
dwType,
pInsertionAllowed);
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*!--------------------------------------------------------------------------
TFSComponentData::Command
Implemenation of IExtendContextMenu::Command
Command handler for any items added to a context menu
Author:
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::Command
(
long nCommandID,
LPDATAOBJECT pDataObject
)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HRESULT hr = S_OK;
SPINTERNAL spInternal;
DATA_OBJECT_TYPES type;
SPITFSNode spNode;
SPITFSNodeHandler spNodeHandler;
DWORD dwType;
COM_PROTECT_TRY
{
CORg( ExtractNodeFromDataObject(m_spNodeMgr,
m_spCallback->GetCoClassID(),
pDataObject,
FALSE, &spNode, &dwType,
&spInternal) );
type = (spInternal ? spInternal->m_type : CCT_SCOPE);
CORg( spNode->GetHandler(&spNodeHandler) );
hr = spNodeHandler->OnCommand(spNode, nCommandID,
type,
pDataObject,
dwType);
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
return hr;
}
/*---------------------------------------------------------------------------
ISnapinHelp implementation
---------------------------------------------------------------------------*/
/*!--------------------------------------------------------------------------
TFSComponentData::GetHelpTopic
Implementation of ISnapinHelp::GetHelpTopic
MMC calls this so that a snapin can add it's .chm file to the main index
Author: EricDav
---------------------------------------------------------------------------*/
STDMETHODIMP
TFSComponentData::GetHelpTopic
(
LPOLESTR* lpCompiledHelpFile
)
{
HRESULT hr = S_OK;
if (lpCompiledHelpFile == NULL)
return E_INVALIDARG;
LPCWSTR lpszHelpFileName = GetHTMLHelpFileName();
if (lpszHelpFileName == NULL)
{
*lpCompiledHelpFile = NULL;
return E_NOTIMPL;
}
CString szHelpFilePath;
UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
if (nLen == 0)
return E_FAIL;
szHelpFilePath.ReleaseBuffer();
szHelpFilePath += L"\\help\\";
szHelpFilePath += lpszHelpFileName;
UINT nBytes = (szHelpFilePath.GetLength() + 1) * sizeof(WCHAR);
*lpCompiledHelpFile = (LPOLESTR)::CoTaskMemAlloc(nBytes);
if (*lpCompiledHelpFile)
{
memcpy(*lpCompiledHelpFile, (LPCWSTR)szHelpFilePath, nBytes);
}
else
{
hr = E_OUTOFMEMORY;
}
return hr;
}
STDMETHODIMP TFSComponentData::GetNodeMgr(ITFSNodeMgr **ppNodeMgr)
{
Assert(ppNodeMgr);
SetI((LPUNKNOWN *) ppNodeMgr, m_spNodeMgr);
return hrOK;
}
STDMETHODIMP TFSComponentData::GetConsole(IConsole2 **ppConsole)
{
Assert(ppConsole);
SetI((LPUNKNOWN *) ppConsole, m_spConsole);
return hrOK;
}
STDMETHODIMP TFSComponentData::GetConsoleNameSpace(IConsoleNameSpace2 **ppConsoleNS)
{
Assert(ppConsoleNS);
SetI((LPUNKNOWN *) ppConsoleNS, m_spConsoleNameSpace);
return hrOK;
}
STDMETHODIMP TFSComponentData::GetRootNode(ITFSNode **ppNode)
{
return m_spNodeMgr->GetRootNode(ppNode);
}
STDMETHODIMP_(const CLSID *) TFSComponentData::GetCoClassID()
{
Assert(m_spCallback);
return m_spCallback->GetCoClassID();
}
STDMETHODIMP_(HWND) TFSComponentData::GetHiddenWnd()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
if (!m_hiddenWnd.GetSafeHwnd())
{
m_hiddenWnd.Create();
m_hWnd = m_hiddenWnd.GetSafeHwnd();
}
Assert(m_hWnd);
return m_hWnd;
}
STDMETHODIMP_(LPWATERMARKINFO) TFSComponentData::SetWatermarkInfo(LPWATERMARKINFO pNewWatermarkInfo)
{
LPWATERMARKINFO pOldWatermarkInfo = m_pWatermarkInfo;
m_pWatermarkInfo = pNewWatermarkInfo;
return pOldWatermarkInfo;
}
STDMETHODIMP TFSComponentData::GetClassID(LPCLSID lpClassID)
{
Assert(m_spCallback);
return m_spCallback->GetClassID(lpClassID);
}
STDMETHODIMP TFSComponentData::IsDirty()
{
Assert(m_spCallback);
return m_spCallback->IsDirty();
}
STDMETHODIMP TFSComponentData::Load(LPSTREAM pStm)
{
Assert(m_spCallback);
return m_spCallback->Load(pStm);
}
STDMETHODIMP TFSComponentData::Save(LPSTREAM pStm, BOOL fClearDirty)
{
Assert(m_spCallback);
return m_spCallback->Save(pStm, fClearDirty);
}
STDMETHODIMP TFSComponentData::GetSizeMax(ULARGE_INTEGER FAR *pcbSize)
{
Assert(m_spCallback);
return m_spCallback->GetSizeMax(pcbSize);
}
STDMETHODIMP TFSComponentData::InitNew()
{
Assert(m_spCallback);
return m_spCallback->InitNew();
}
STDMETHODIMP
TFSComponentData::SetTaskpadState(int nIndex, BOOL fEnable)
{
DWORD dwMask = 0x00000001 << nIndex;
if (!m_fTaskpadInitialized)
{
// this will initialize the states to the deafult value
GetTaskpadState(0);
}
if (fEnable)
m_dwTaskpadStates |= dwMask;
else
m_dwTaskpadStates &= ~dwMask;
return hrOK;
}
// taskpad states are kept track of on a pernode basis.
// we can store up to 32 (DWORD) different node states here
// if you don't want taskpads on a per node basis, always
// pass an index of 0
STDMETHODIMP_(BOOL)
TFSComponentData::GetTaskpadState(int nIndex)
{
DWORD dwMask = 0x00000001 << nIndex;
if (!m_fTaskpadInitialized)
{
// assume taskpads on
BOOL fDefault = TRUE;
m_fTaskpadInitialized = TRUE;
// get the default state from MMC
if (m_spConsole)
fDefault = (m_spConsole->IsTaskpadViewPreferred() == S_OK) ? TRUE : FALSE;
if (fDefault)
{
// now check our private override
fDefault = FUseTaskpadsByDefault(NULL);
}
if (fDefault)
m_dwTaskpadStates = 0xFFFFFFFF;
else
m_dwTaskpadStates = 0;
}
return m_dwTaskpadStates & dwMask;
}
STDMETHODIMP_(LPCTSTR)
TFSComponentData::GetHTMLHelpFileName()
{
if (m_strHTMLHelpFileName.IsEmpty())
return NULL;
else
return (LPCTSTR) m_strHTMLHelpFileName;
}
STDMETHODIMP
TFSComponentData::SetHTMLHelpFileName(LPCTSTR pszHelpFileName)
{
m_strHTMLHelpFileName = pszHelpFileName;
return S_OK;
}
TFSCORE_API(HRESULT) CreateTFSComponentData(IComponentData **ppCompData,
ITFSCompDataCallback *pCallback)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
TFSComponentData * pCompData = NULL;
HRESULT hr = hrOK;
COM_PROTECT_TRY
{
*ppCompData = NULL;
pCompData = new TFSComponentData;
CORg( pCompData->Construct(pCallback) );
*ppCompData = static_cast<IComponentData *>(pCompData);
(*ppCompData)->AddRef();
COM_PROTECT_ERROR_LABEL;
}
COM_PROTECT_CATCH;
// Note: to balance the AddRef()/Release() we Release() this pointer
// even in the success case
if (pCompData)
pCompData->Release();
return hr;
}