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.
 
 
 
 
 
 

968 lines
32 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: compbase.h
//
//--------------------------------------------------------------------------
#ifndef _COMPBASE_H
#define _COMPBASE_H
// We do not want to force snapins using the framework to go and replace all
// of their unsafe functions.
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
///////////////////////////////////////////////////////////////////////////////
// Base classes implementing the IComponent and IComponentData interfaces
///////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// IConsole::UpdateAllViews() : values for the Hint argument
#define ADD_RESULT_ITEM ( 0x00000001 )
#define DELETE_RESULT_ITEM ( 0x00000002 )
#define CHANGE_RESULT_ITEM_DATA ( 0x00000004 )
#define CHANGE_RESULT_ITEM_ICON ( 0x00000008 )
#define CHANGE_RESULT_ITEM ( CHANGE_RESULT_ITEM_DATA | CHANGE_RESULT_ITEM_ICON )
#define REPAINT_RESULT_PANE ( 0x00000010 )
#define DELETE_ALL_RESULT_ITEMS ( 0x00000011 )
#define UPDATE_VERB_STATE ( 0x00000012 )
#define SORT_RESULT_PANE ( 0x00000013 )
#define UPDATE_DESCRIPTION_BAR ( 0x00000100 )
#define UPDATE_RESULT_PANE_VIEW ( 0x00000200 )
#define DELETE_MULTIPLE_RESULT_ITEMS ( 0x00000400)
///////////////////////////////////////////////////////////////////////////////
// DATA STRUCTURES
extern DWORD _MainThreadId;
extern CString LOGFILE_NAME;
///////////////////////////////////////////////////////////////////////////////
// FORWARD DECLARATIONS
class CComponentDataObject;
class CComponentObject;
class CRootData;
class CTreeNode;
class CContainerNode;
class CMTContainerNode;
class CLeafNode;
class CPropertyPageHolderTable;
///////////////////////////////////////////////////////////////////////////////
// global functions
struct _NODE_TYPE_INFO_ENTRY
{
const GUID* m_pNodeGUID;
LPCTSTR m_lpszNodeDescription;
};
HRESULT RegisterSnapin(const GUID* pSnapinCLSID,
const GUID* pStaticNodeGUID,
const GUID* pAboutGUID,
LPCTSTR lpszNameString, LPCTSTR lpszVersion, LPCTSTR lpszProvider,
BOOL bExtension, _NODE_TYPE_INFO_ENTRY* pNodeTypeInfoEntryArray,
UINT nSnapinNameID = 0);
HRESULT UnregisterSnapin(const GUID* pSnapinCLSID);
HRESULT RegisterNodeType(const GUID* pGuid, LPCTSTR lpszNodeDescription);
HRESULT UnregisterNodeType(const GUID* pGuid);
HRESULT RegisterNodeExtension(const GUID* pNodeGuid, LPCTSTR lpszExtensionType,
const GUID* pExtensionSnapinCLSID, LPCTSTR lpszDescription, BOOL bDynamic);
HRESULT UnregisterNodeExtension(const GUID* pNodeGuid, LPCTSTR lpszExtensionType,
const GUID* pExtensionSnapinCLSID, BOOL bDynamic);
/////////////////////////////////////////////////////////////////////////////
// CTimerThread
class CTimerThread : public CWinThread
{
public:
CTimerThread() { m_bAutoDelete = FALSE; m_hWnd = 0;}
BOOL Start(HWND hWnd);
virtual BOOL InitInstance() { return TRUE; } // MFC override
virtual int Run() { return -1;} // MFC override
protected:
BOOL PostMessageToWnd(WPARAM wParam, LPARAM lParam);
private:
HWND m_hWnd;
};
/////////////////////////////////////////////////////////////////////////////
// CWorkerThread
class CWorkerThread : public CWinThread
{
public:
CWorkerThread();
virtual ~CWorkerThread();
BOOL Start(HWND hWnd);
virtual BOOL InitInstance() { return TRUE; } // MFC override
virtual int Run() { return -1;} // MFC override
// REVIEWED-2002/03/08-JeffJon-There appears to be no danger
// of getting stuck in the critical section
void Lock() { ::EnterCriticalSection(&m_cs); }
void Unlock() { ::LeaveCriticalSection(&m_cs); }
void Abandon();
BOOL IsAbandoned();
void AcknowledgeExiting() { VERIFY(0 != ::SetEvent(m_hEventHandle));}
protected:
virtual void OnAbandon() {}
protected:
BOOL PostMessageToWnd(UINT Msg, WPARAM wParam, LPARAM lParam);
void WaitForExitAcknowledge();
private:
CRITICAL_SECTION m_cs;
HANDLE m_hEventHandle;
HWND m_hWnd;
BOOL m_bAbandoned;
};
////////////////////////////////////////////////////////////////////
// CHiddenWnd : Hidden window to syncronize threads and CComponentData object
class CHiddenWnd : public CHiddenWndBase
{
public:
CHiddenWnd(CComponentDataObject* pComponentDataObject);
static const UINT s_NodeThreadHaveDataNotificationMessage;
static const UINT s_NodeThreadErrorNotificationMessage;
static const UINT s_NodeThreadExitingNotificationMessage;
static const UINT s_NodePropertySheetCreateMessage;
static const UINT s_NodePropertySheetDeleteMessage;
static const UINT s_ExecCommandMessage;
static const UINT s_ForceEnumerationMessage;
static const UINT s_TimerThreadMessage;
UINT_PTR m_nTimerID;
private:
CComponentDataObject* m_pComponentDataObject; // back pointer
public:
BEGIN_MSG_MAP(CHiddenWnd)
MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadHaveDataNotificationMessage, OnNodeThreadHaveDataNotification )
MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadErrorNotificationMessage, OnNodeThreadErrorNotification )
MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadExitingNotificationMessage, OnNodeThreadExitingNotification )
MESSAGE_HANDLER( CHiddenWnd::s_NodePropertySheetCreateMessage, OnNodePropertySheetCreate )
MESSAGE_HANDLER( CHiddenWnd::s_NodePropertySheetDeleteMessage, OnNodePropertySheetDelete )
MESSAGE_HANDLER( CHiddenWnd::s_ExecCommandMessage, OnExecCommand )
MESSAGE_HANDLER( CHiddenWnd::s_ForceEnumerationMessage, OnForceEnumeration )
MESSAGE_HANDLER( CHiddenWnd::s_TimerThreadMessage, OnTimerThread )
MESSAGE_HANDLER( WM_TIMER, OnTimer )
CHAIN_MSG_MAP(CHiddenWndBase)
END_MSG_MAP()
LRESULT OnNodeThreadHaveDataNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnNodeThreadErrorNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnNodeThreadExitingNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnNodePropertySheetCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnNodePropertySheetDelete(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnExecCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnForceEnumeration(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnTimerThread(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnTimer(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};
////////////////////////////////////////////////////////////////////////////////////
// CRunningThreadTable
// all CMTContainerNode with running refresh/enumerate background threads will
// register/unregister in this table to allow proper thread abandoning at shutdown
class CRunningThreadTable
{
public:
CRunningThreadTable(CComponentDataObject* pComponentData);
~CRunningThreadTable();
void Add(CMTContainerNode* pNode);
void Remove(CMTContainerNode* pNode);
void RemoveAll();
BOOL IsPresent(CMTContainerNode* pNode);
private:
CComponentDataObject* m_pComponentData; // back pointer
CMTContainerNode** m_pEntries;
int m_nSize;
};
////////////////////////////////////////////////////////////////////////////////////
// CExecContext
class CExecContext
{
public:
CExecContext();
~CExecContext();
virtual void Execute(LPARAM arg) = 0; // code to be executed from main thread
virtual void Wait(); // secondary thread waits on this call
virtual void Done(); // called when main thread done executing
protected:
HANDLE m_hEventHandle;
};
////////////////////////////////////////////////////////////////////////////////////
// CNotificationSinkBase
class CNotificationSinkBase
{
public:
virtual void OnNotify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2) = 0;
};
////////////////////////////////////////////////////////////////////////////////////
// CNotificationSinkEvent
class CNotificationSinkEvent : public CNotificationSinkBase
{
public:
CNotificationSinkEvent();
~CNotificationSinkEvent();
public:
void OnNotify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2);
virtual void Wait();
private:
HANDLE m_hEventHandle;
};
////////////////////////////////////////////////////////////////////////////////////
// CNotificationSinkTable
class CNotificationSinkTable
{
public:
CNotificationSinkTable();
~CNotificationSinkTable();
void Advise(CNotificationSinkBase* p);
void Unadvise(CNotificationSinkBase* p);
void Notify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2);
private:
void Lock()
{
TRACE(_T("CNotificationSinkTable::Lock()\n"));
// REVIEWED-2002/03/08-JeffJon-There appears to be no danger
// of getting stuck in the critical section
::EnterCriticalSection(&m_cs);
}
void Unlock()
{
TRACE(_T("CNotificationSinkTable::Unlock()\n"));
::LeaveCriticalSection(&m_cs);
}
CRITICAL_SECTION m_cs;
CNotificationSinkBase** m_pEntries;
int m_nSize;
};
////////////////////////////////////////////////////////////////////////////////////
// CPersistStreamImpl
class CPersistStreamImpl : public IPersistStream
{
public:
HRESULT STDMETHODCALLTYPE GetClassID(CLSID* pClassID) = 0;
HRESULT STDMETHODCALLTYPE IsDirty() = 0;
HRESULT STDMETHODCALLTYPE Load(IStream __RPC_FAR *pStm) = 0;
HRESULT STDMETHODCALLTYPE Save(IStream __RPC_FAR *pStm, BOOL fClearDirty) = 0;
HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize)
{
ASSERT(FALSE);
//
// arbitrary value, do we ever get called?
//
pcbSize->LowPart = 0xffff;
pcbSize->HighPart= 0x0;
return S_OK;
}
};
///////////////////////////////////////////////////////////////////////////////
// CWatermarkInfo
class CWatermarkInfo
{
public:
CWatermarkInfo()
{
m_nIDBanner = 0;
m_nIDWatermark = 0;
m_hPalette = NULL;
m_bStretch = TRUE;
}
UINT m_nIDBanner;
UINT m_nIDWatermark;
HPALETTE m_hPalette;
BOOL m_bStretch;
};
////////////////////////////////////////////////////////////////////////////////
// CColumn
class CColumn
{
public:
CColumn(LPCWSTR lpszColumnHeader,
int nFormat,
int nWidth,
UINT nColumnNum)
{
m_lpszColumnHeader = NULL;
SetHeader(lpszColumnHeader);
m_nFormat = nFormat;
m_nWidth = nWidth;
m_nColumnNum = nColumnNum;
}
~CColumn()
{
free(m_lpszColumnHeader);
}
LPCWSTR GetHeader() { return (LPCWSTR)m_lpszColumnHeader; }
void SetHeader(LPCWSTR lpszColumnHeader)
{
if (m_lpszColumnHeader != NULL)
{
free(m_lpszColumnHeader);
}
// We are assuming the column header is NULL terminated. Since this is usually
// pulled from the resource and there is no good way to verify that it is NULL
// terminated this usage should be fine.
size_t iLen = wcslen(lpszColumnHeader);
m_lpszColumnHeader = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
if (m_lpszColumnHeader != NULL)
{
HRESULT hr = StringCchCopyW(m_lpszColumnHeader, iLen + 1, lpszColumnHeader);
ASSERT(SUCCEEDED(hr));
}
}
int GetFormat() { return m_nFormat; }
void SetFormat(int nFormat) { m_nFormat = nFormat; }
int GetWidth() { return m_nWidth; }
void SetWidth(int nWidth) { m_nWidth = nWidth; }
UINT GetColumnNum() { return m_nColumnNum; }
void SetColumnNum(UINT nColumnNum) { m_nColumnNum = nColumnNum; }
protected:
LPWSTR m_lpszColumnHeader;
int m_nFormat;
int m_nWidth;
UINT m_nColumnNum;
};
////////////////////////////////////////////////////////////////////////////////
// CColumnSet
class CColumnSet : public CList<CColumn*, CColumn*>
{
public :
CColumnSet(LPCWSTR lpszColumnID)
{
// We are assuming the columnID is NULL terminated. Since this is usually
// hardcoded and there is no good way to verify that it is NULL terminated
// this usage should be fine.
size_t iLen = wcslen(lpszColumnID);
m_lpszColumnID = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
if (m_lpszColumnID != NULL)
{
// Make a copy of the column set ID
HRESULT hr = StringCchCopyW(m_lpszColumnID, iLen + 1, lpszColumnID);
ASSERT(SUCCEEDED(hr));
}
}
CColumnSet(LPCWSTR lpszColumnID, CList<CColumn*, CColumn*>&)
{
// We are assuming the columnID is NULL terminated. Since this is usually
// hardcoded and there is no good way to verify that it is NULL terminated
// this usage should be fine.
size_t iLen = wcslen(lpszColumnID);
m_lpszColumnID = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
if (m_lpszColumnID)
{
// Make a copy of the column set ID
HRESULT hr = StringCchCopyW(m_lpszColumnID, iLen + 1, lpszColumnID);
ASSERT(SUCCEEDED(hr));
}
}
~CColumnSet()
{
while(!IsEmpty())
{
CColumn* pColumn = RemoveTail();
delete pColumn;
}
free(m_lpszColumnID);
}
void AddColumn(LPCWSTR lpszHeader, int nFormat, int nWidth, UINT nCol)
{
CColumn* pNewColumn = new CColumn(lpszHeader, nFormat, nWidth, nCol);
AddTail(pNewColumn);
}
LPCWSTR GetColumnID() { return (LPCWSTR)m_lpszColumnID; }
UINT GetNumCols() { return static_cast<UINT>(GetCount()); }
private :
LPWSTR m_lpszColumnID;
};
////////////////////////////////////////////////////////////////////////////////
// CColumnSetList
class CColumnSetList : public CList<CColumnSet*, CColumnSet*>
{
public :
// Find the column set given a column set ID
CColumnSet* FindColumnSet(LPCWSTR lpszColumnID)
{
POSITION pos = GetHeadPosition();
while (pos != NULL)
{
CColumnSet* pTempSet = GetNext(pos);
ASSERT(pTempSet != NULL);
LPCWSTR lpszTempNodeID = pTempSet->GetColumnID();
if (wcscmp(lpszTempNodeID, lpszColumnID) == 0)
{
return pTempSet;
}
}
return NULL;
}
void RemoveAndDeleteAllColumnSets()
{
while (!IsEmpty())
{
CColumnSet* pTempSet = RemoveTail();
delete pTempSet;
}
}
};
///////////////////////////////////////////////////////////////////////////////
// CComponentDataObject
// * this class contains the master tree data (i.e. the "document")
// * base class, have to derive from it
class CWatermarkInfoState; // fwd decl of private class
class CComponentDataObject:
public IComponentData,
public IExtendPropertySheet2,
public IExtendContextMenu,
public CPersistStreamImpl,
public ISnapinHelp2,
public IRequiredExtensions,
public CComObjectRoot
{
BEGIN_COM_MAP(CComponentDataObject)
COM_INTERFACE_ENTRY(IComponentData)
COM_INTERFACE_ENTRY(IExtendPropertySheet2)
COM_INTERFACE_ENTRY(IExtendContextMenu)
COM_INTERFACE_ENTRY(IPersistStream)
COM_INTERFACE_ENTRY(ISnapinHelp2)
COM_INTERFACE_ENTRY(IRequiredExtensions)
END_COM_MAP()
#ifdef _DEBUG_REFCOUNT
static unsigned int m_nOustandingObjects; // # of objects created
int dbg_cRef;
ULONG InternalAddRef()
{
++dbg_cRef;
TRACE(_T("CComponentDataObject::InternalAddRef() refCount = %d\n"), dbg_cRef);
return CComObjectRoot::InternalAddRef();
}
ULONG InternalRelease()
{
--dbg_cRef;
TRACE(_T("CComponentDataObject::InternalRelease() refCount = %d\n"), dbg_cRef);
return CComObjectRoot::InternalRelease();
}
#endif // _DEBUG_REFCOUNT
CComponentDataObject();
virtual ~CComponentDataObject();
HRESULT FinalConstruct();
void FinalRelease();
public:
// IComponentData interface members
STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
STDMETHOD(CreateComponent)(LPCOMPONENT* ppComponent) = 0; // must override
STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param);
STDMETHOD(Destroy)();
STDMETHOD(QueryDataObject)(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject);
STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM* pScopeDataItem);
STDMETHOD(CompareObjects)(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB);
// IExtendPropertySheet2 interface members
public:
STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
LPDATAOBJECT lpIDataObject);
STDMETHOD(QueryPagesFor)(LPDATAOBJECT lpDataObject);
STDMETHOD(GetWatermarks)(LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader,
HPALETTE* lphPalette, BOOL* pbStretch);
HRESULT CreatePropertySheet(CTreeNode* pNode, HWND hWndParent, LPCWSTR lpszTitle);
public:
//
// IExtendContextMenu interface members
//
STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pCallbackUnknown,
long *pInsertionAllowed);
STDMETHOD(Command)(long nCommandID, LPDATAOBJECT pDataObject);
//
// IPersistStream interface members
//
STDMETHOD(IsDirty)();
STDMETHOD(Load)(IStream __RPC_FAR *pStm);
STDMETHOD(Save)(IStream __RPC_FAR *pStm, BOOL fClearDirty);
//
// ISnapinHelp2 interface members
//
STDMETHOD(GetHelpTopic)(LPOLESTR* lpCompiledHelpFile);
STDMETHOD(GetLinkedTopics)(LPOLESTR* lpCompiledHelpFile);
//
// IRequiredExtensions interface members
//
STDMETHOD(EnableAllExtensions)() { return S_OK;} // load all always
STDMETHOD(GetFirstExtension)(LPCLSID) { return S_FALSE;} // should not be called
STDMETHOD(GetNextExtension)(LPCLSID) { return S_FALSE;} // should not be called
// virtual functions
protected:
virtual HRESULT OnSetImages(LPIMAGELIST lpScopeImage) = 0; // must override
virtual HRESULT OnExtensionExpand(LPDATAOBJECT, LPARAM)
{ return E_FAIL;}
virtual HRESULT OnRemoveChildren(LPDATAOBJECT lpDataObject, LPARAM arg);
// Notify handler declarations
private:
HRESULT OnAdd(CTreeNode* cookie, LPARAM arg, LPARAM param);
HRESULT OnRename(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT OnExpand(CInternalFormatCracker& ifc,
LPARAM arg,
LPARAM param,
BOOL bAsync = TRUE);
HRESULT OnSelect(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT OnContextMenu(CTreeNode* cookie, LPARAM arg, LPARAM param);
HRESULT OnPropertyChange(LPARAM param, long fScopePane);
// Scope item creation helpers
private:
void EnumerateScopePane(CTreeNode* cookie,
HSCOPEITEM pParent,
BOOL bAsync = TRUE);
BOOL IsScopePaneNode(LPDATAOBJECT lpDataObject);
// Helpers
public:
LPCONSOLE GetConsole() { return m_pConsole;}
HRESULT OnDeleteVerbHandler(CInternalFormatCracker& ifc, CComponentObject* pComponentObject);
HRESULT OnRefreshVerbHandler(CInternalFormatCracker& ifc);
HRESULT OnHelpHandler(CInternalFormatCracker& ifc, CComponentObject* pComponentObject);
HRESULT AddNode(CTreeNode* pNodeToAdd);
HRESULT AddNodeSorted(CTreeNode* pNodeToAdd);
HRESULT DeleteNode(CTreeNode* pNodeToDelete);
HRESULT DeleteMultipleNodes(CNodeList* pNodeList);
HRESULT ChangeNode(CTreeNode* pNodeToChange, long changeMask);
HRESULT UpdateVerbState(CTreeNode* pNodeToChange);
HRESULT RemoveAllChildren(CContainerNode* pNode);
HRESULT RepaintSelectedFolderInResultPane();
HRESULT RepaintResultPane(CContainerNode* pNode);
HRESULT DeleteAllResultPaneItems(CContainerNode* pNode);
HRESULT SortResultPane(CContainerNode* pContainerNode);
HRESULT UpdateResultPaneView(CContainerNode* pContainerNode);
CPropertyPageHolderTable* GetPropertyPageHolderTable() { return &m_PPHTable; }
CRunningThreadTable* GetRunningThreadTable() { return &m_RTTable; }
CNotificationSinkTable* GetNotificationSinkTable() { return &m_NSTable; }
void WaitForThreadExitMessage(CMTContainerNode* pNode);
CWatermarkInfo* SetWatermarkInfo(CWatermarkInfo* pWatermarkInfo);
BOOL IsExtensionSnapin() { return m_bExtensionSnapin; }
void SetLogFileName(PCWSTR pszLogName) { LOGFILE_NAME = pszLogName; }
protected:
void SetExtensionSnapin(BOOL bExtensionSnapin)
{ m_bExtensionSnapin = bExtensionSnapin;}
private:
HRESULT UpdateAllViewsHelper(LPARAM data, LONG_PTR hint);
void HandleStandardVerbsHelper(CComponentObject* pComponentObj,
LPCONSOLEVERB pConsoleVerb,
BOOL bScope, BOOL bSelect,
LPDATAOBJECT lpDataObject);
protected:
virtual HRESULT SnapinManagerCreatePropertyPages(LPPROPERTYSHEETCALLBACK,
LONG_PTR) {return S_FALSE; }
virtual BOOL HasPropertyPages(DATA_OBJECT_TYPES) {return FALSE; }
virtual void OnInitialize();
virtual void OnDestroy();
// help handling
virtual LPCWSTR GetHTMLHelpFileName() { return NULL; }
BOOL WinHelp(LPCTSTR lpszHelpFileName, UINT uCommand, DWORD dwData);
virtual void OnNodeContextHelp(CTreeNode*){}
virtual void OnNodeContextHelp(CNodeList*) {}
public:
virtual void OnDialogContextHelp(UINT, HELPINFO*) {}
virtual BOOL IsMultiSelect() { return FALSE; }
// Scope pane helpers
public:
protected:
HRESULT AddContainerNode(CContainerNode* pNodeToInsert, HSCOPEITEM pParentScopeItem);
HRESULT AddContainerNodeSorted(CContainerNode* pNodeToInsert, HSCOPEITEM pParentScopeItem);
private:
HRESULT DeleteContainerNode(CContainerNode* pNodeToDelete);
HRESULT ChangeContainerNode(CContainerNode* pNodeToChange, long changeMask);
void InitializeScopeDataItem(LPSCOPEDATAITEM pScopeDataItem, HSCOPEITEM pParentScopeItem, LPARAM lParam,
int nImage, int nOpenImage, BOOL bHasChildren);
// Column Set helpers
public:
CColumnSetList* GetColumnSetList() { return &m_ColList; }
private:
CColumnSetList m_ColList;
// Result pane helpers
public:
protected:
private:
HRESULT AddLeafNode(CLeafNode* pNodeToAdd);
HRESULT DeleteLeafNode(CLeafNode* pNodeToDelete);
HRESULT ChangeLeafNode(CLeafNode* pNodeToChange, long changeMask);
// Attributes
private:
LPCONSOLE m_pConsole; // IConsole interface pointer
LPCONSOLENAMESPACE2 m_pConsoleNameSpace; // IConsoleNameSpace interface pointer
CPropertyPageHolderTable m_PPHTable; // property page holder table
CRunningThreadTable m_RTTable; // table of running MT nodes
CNotificationSinkTable m_NSTable; // notification sink table, for advise in events
CWatermarkInfoState* m_pWatermarkInfoState; // internal watermark info for Wizards
BOOL m_bExtensionSnapin; // is this an extension?
// critical section (Serialization of calls to console)
public:
// REVIEWED-2002/03/08-JeffJon-There appears to be no danger
// of getting stuck in the critical section
void Lock() { ::EnterCriticalSection(&m_cs); }
void Unlock() { ::LeaveCriticalSection(&m_cs); }
private:
CRITICAL_SECTION m_cs; // general purpose critical section
// RootData
protected:
CRootData* m_pRootData; // root node for the cache
virtual CRootData* OnCreateRootData() = 0; // must override
public:
CRootData* GetRootData() { ASSERT(m_pRootData != NULL); return m_pRootData;}
// Hidden window
private:
CHiddenWnd m_hiddenWnd; // syncronization with background threads
CTimerThread* m_pTimerThreadObj; // timer thread object
HWND m_hWnd; // thread safe HWND (gotten from the MFC CWnd)
public:
BOOL PostExecMessage(CExecContext* pExec, LPARAM arg); // call from secondary thread
BOOL PostForceEnumeration(CMTContainerNode* pContainerNode); // call from secondary thread
HWND GetHiddenWindow() { ASSERT(m_hWnd != NULL); return m_hWnd;}
BOOL OnCreateSheet(CPropertyPageHolderBase* pPPHolder, HWND hWnd);
BOOL OnDeleteSheet(CPropertyPageHolderBase* pPPHolder, CTreeNode* pNode);
HRESULT SetDescriptionBarText(CTreeNode* pTreeNode);
// Timer and Background Thread
public:
BOOL StartTimerThread();
void ShutDownTimerThread();
BOOL PostMessageToTimerThread(UINT Msg, WPARAM wparam, LPARAM lParam);
DWORD GetTimerInterval() { return m_dwTimerInterval;}
protected:
DWORD m_dwTimerTime; // sec
// overrides that MUST be implemented
virtual void OnTimer() { ASSERT(FALSE); }
virtual void OnTimerThread(WPARAM, LPARAM) { ASSERT(FALSE); }
virtual CTimerThread* OnCreateTimerThread() { return NULL; }
private:
BOOL SetTimer();
void KillTimer();
void WaitForTimerThreadStartAck();
DWORD m_nTimerThreadID;
BOOL m_bTimerThreadStarted;
DWORD m_dwTimerInterval; // sec
// friend class declarations
friend class CDataObject; // for the GetRootData() member
friend class CComponentObject; // for the FindObject() and OnPropertyChange() members
friend class CHiddenWnd;
};
///////////////////////////////////////////////////////////////////////////////
// CComponentObject
// * this class is the view on the data contained in the "document"
// * base class, have to derive from it
class CComponentObject :
public IComponent,
public IExtendPropertySheet2,
public IExtendContextMenu,
public IExtendControlbar,
public IResultDataCompareEx,
public CComObjectRoot
{
public:
#ifdef _DEBUG_REFCOUNT
static unsigned int m_nOustandingObjects; // # of objects created
int dbg_cRef;
ULONG InternalAddRef()
{
++dbg_cRef;
return CComObjectRoot::InternalAddRef();
}
ULONG InternalRelease()
{
--dbg_cRef;
return CComObjectRoot::InternalRelease();
}
#endif // _DEBUG_REFCOUNT
CComponentObject();
virtual ~CComponentObject();
BEGIN_COM_MAP(CComponentObject)
COM_INTERFACE_ENTRY(IComponent)
COM_INTERFACE_ENTRY(IExtendPropertySheet2)
COM_INTERFACE_ENTRY(IExtendContextMenu)
COM_INTERFACE_ENTRY(IExtendControlbar)
COM_INTERFACE_ENTRY(IResultDataCompareEx)
END_COM_MAP()
public:
//
// IComponent interface members
//
STDMETHOD(Initialize)(LPCONSOLE lpConsole);
STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param);
STDMETHOD(Destroy)(MMC_COOKIE cookie);
STDMETHOD(GetResultViewType)(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions);
STDMETHOD(QueryDataObject)(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
LPDATAOBJECT* ppDataObject);
STDMETHOD(GetDisplayInfo)(LPRESULTDATAITEM pResultDataItem);
STDMETHOD(CompareObjects)( LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB);
//
// IExtendPropertySheet2 interface members
//
STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
LONG_PTR handle,
LPDATAOBJECT lpIDataObject);
STDMETHOD(QueryPagesFor)(LPDATAOBJECT lpDataObject);
STDMETHOD(GetWatermarks)(LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader,
HPALETTE* lphPalette, BOOL* pbStretch);
//
// IExtendContextMenu interface members
//
STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
LPCONTEXTMENUCALLBACK pCallbackUnknown,
long *pInsertionAllowed);
STDMETHOD(Command)(long nCommandID, LPDATAOBJECT pDataObject);
//
// IExtendControlbar interface memebers
//
STDMETHOD(SetControlbar)(LPCONTROLBAR pControlbar);
STDMETHOD(ControlbarNotify)(MMC_NOTIFY_TYPE type, LPARAM arg, LPARAM param);
//
// IResultDataCompare
//
STDMETHOD(Compare)(RDCOMPARE* prdc, int* pnResult);
// Helpers for CComponentObject
public:
void SetIComponentData(CComponentDataObject* pData);
void SetSelectedNode(CTreeNode* pSelectedNode, DATA_OBJECT_TYPES selectedType)
{ m_pSelectedNode = pSelectedNode; m_selectedType = selectedType; }
// Notify event handlers
protected:
HRESULT OnFolder(CTreeNode* cookie, LPARAM arg, LPARAM param);
HRESULT OnShow(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT OnActivate(CTreeNode* cookie, LPARAM arg, LPARAM param);
HRESULT OnResultItemClk(CInternalFormatCracker& ifc, BOOL fDblClick);
HRESULT OnMinimize(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT OnPropertyChange(LPARAM param, long fScopePane);
HRESULT OnUpdateView(LPDATAOBJECT lpDataObject, LPARAM data, LONG_PTR hint);
HRESULT OnAddImages(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT SetDescriptionBarText(CTreeNode* pTreeNode);
// Added by JEFFJON : response to MMCN_COLUMNS_CHANGED
HRESULT OnColumnsChanged(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
HRESULT OnColumnSortChanged(LPARAM arg, LPARAM param);
// Helper functions
protected:
BOOL IsEnumerating(LPDATAOBJECT lpDataObject);
void Construct();
void LoadResources();
virtual HRESULT InitializeHeaders(CContainerNode* pContainerNode) = 0;
virtual HRESULT InitializeToolbar(IToolbar*) { return E_NOTIMPL; }
public:
HRESULT ForceSort(UINT iCol, DWORD dwDirection);
protected:
void EnumerateResultPane(CContainerNode* pContainerNode);
// Result pane helpers
virtual HRESULT InitializeBitmaps(CTreeNode* cookie) = 0;
void HandleStandardVerbs(BOOL bScope, BOOL bSelect, LPDATAOBJECT lpDataObject);
HRESULT AddResultPaneItem(CLeafNode* pNodeToInsert);
HRESULT DeleteResultPaneItem(CLeafNode* pNodeToDelete);
HRESULT ChangeResultPaneItem(CLeafNode* pNodeToChange, LONG_PTR changeMask);
HRESULT FindResultPaneItemID(CLeafNode* pNode, HRESULTITEM* pItemID);
// Interface pointers
protected:
LPCONSOLE m_pConsole; // IConsole interface pointer
LPHEADERCTRL m_pHeader; // Result pane's header control interface
LPRESULTDATA m_pResult; // My interface pointer to the result pane
LPIMAGELIST m_pImageResult; // My interface pointer to the result pane image list
LPTOOLBAR m_pToolbar; // Toolbar for view
LPCONTROLBAR m_pControlbar; // control bar to hold my tool bars
LPCONSOLEVERB m_pConsoleVerb; // pointer the console verb
LPCOMPONENTDATA m_pComponentData; // Pointer to the IComponentData this object belongs to
// state variables for this window
CContainerNode* m_pSelectedContainerNode; // scope item selection (MMCN_SHOW)
CTreeNode* m_pSelectedNode; // item selection (MMC_SELECT)
DATA_OBJECT_TYPES m_selectedType; // matching m_pSelectedNode
};
inline void CComponentObject::SetIComponentData(CComponentDataObject* pData)
{
TRACE(_T("CComponentObject::SetIComponentData()\n"));
ASSERT(pData);
ASSERT(m_pComponentData == NULL);
LPUNKNOWN pUnk = pData->GetUnknown(); // does not addref
HRESULT hr;
hr = pUnk->QueryInterface(IID_IComponentData, reinterpret_cast<void**>(&m_pComponentData));
ASSERT(hr == S_OK);
}
#define FREE_INTERNAL(pInternal) \
ASSERT(pInternal != NULL); \
do { if (pInternal != NULL) \
GlobalFree(pInternal); } \
while(0);
// This wrapper function required to make prefast shut up when we are
// initializing a critical section in a constructor.
void ExceptionPropagatingInitializeCriticalSection(LPCRITICAL_SECTION critsec);
#endif //_COMPBASE_H