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

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1998 - 1999
  6. //
  7. // File: compbase.h
  8. //
  9. //--------------------------------------------------------------------------
  10. #ifndef _COMPBASE_H
  11. #define _COMPBASE_H
  12. // We do not want to force snapins using the framework to go and replace all
  13. // of their unsafe functions.
  14. #define STRSAFE_NO_DEPRECATE
  15. #include <strsafe.h>
  16. ///////////////////////////////////////////////////////////////////////////////
  17. // Base classes implementing the IComponent and IComponentData interfaces
  18. ///////////////////////////////////////////////////////////////////////////////
  19. ////////////////////////////////////////////////////////////////////////
  20. // IConsole::UpdateAllViews() : values for the Hint argument
  21. #define ADD_RESULT_ITEM ( 0x00000001 )
  22. #define DELETE_RESULT_ITEM ( 0x00000002 )
  23. #define CHANGE_RESULT_ITEM_DATA ( 0x00000004 )
  24. #define CHANGE_RESULT_ITEM_ICON ( 0x00000008 )
  25. #define CHANGE_RESULT_ITEM ( CHANGE_RESULT_ITEM_DATA | CHANGE_RESULT_ITEM_ICON )
  26. #define REPAINT_RESULT_PANE ( 0x00000010 )
  27. #define DELETE_ALL_RESULT_ITEMS ( 0x00000011 )
  28. #define UPDATE_VERB_STATE ( 0x00000012 )
  29. #define SORT_RESULT_PANE ( 0x00000013 )
  30. #define UPDATE_DESCRIPTION_BAR ( 0x00000100 )
  31. #define UPDATE_RESULT_PANE_VIEW ( 0x00000200 )
  32. #define DELETE_MULTIPLE_RESULT_ITEMS ( 0x00000400)
  33. ///////////////////////////////////////////////////////////////////////////////
  34. // DATA STRUCTURES
  35. extern DWORD _MainThreadId;
  36. extern CString LOGFILE_NAME;
  37. ///////////////////////////////////////////////////////////////////////////////
  38. // FORWARD DECLARATIONS
  39. class CComponentDataObject;
  40. class CComponentObject;
  41. class CRootData;
  42. class CTreeNode;
  43. class CContainerNode;
  44. class CMTContainerNode;
  45. class CLeafNode;
  46. class CPropertyPageHolderTable;
  47. ///////////////////////////////////////////////////////////////////////////////
  48. // global functions
  49. struct _NODE_TYPE_INFO_ENTRY
  50. {
  51. const GUID* m_pNodeGUID;
  52. LPCTSTR m_lpszNodeDescription;
  53. };
  54. HRESULT RegisterSnapin(const GUID* pSnapinCLSID,
  55. const GUID* pStaticNodeGUID,
  56. const GUID* pAboutGUID,
  57. LPCTSTR lpszNameString, LPCTSTR lpszVersion, LPCTSTR lpszProvider,
  58. BOOL bExtension, _NODE_TYPE_INFO_ENTRY* pNodeTypeInfoEntryArray,
  59. UINT nSnapinNameID = 0);
  60. HRESULT UnregisterSnapin(const GUID* pSnapinCLSID);
  61. HRESULT RegisterNodeType(const GUID* pGuid, LPCTSTR lpszNodeDescription);
  62. HRESULT UnregisterNodeType(const GUID* pGuid);
  63. HRESULT RegisterNodeExtension(const GUID* pNodeGuid, LPCTSTR lpszExtensionType,
  64. const GUID* pExtensionSnapinCLSID, LPCTSTR lpszDescription, BOOL bDynamic);
  65. HRESULT UnregisterNodeExtension(const GUID* pNodeGuid, LPCTSTR lpszExtensionType,
  66. const GUID* pExtensionSnapinCLSID, BOOL bDynamic);
  67. /////////////////////////////////////////////////////////////////////////////
  68. // CTimerThread
  69. class CTimerThread : public CWinThread
  70. {
  71. public:
  72. CTimerThread() { m_bAutoDelete = FALSE; m_hWnd = 0;}
  73. BOOL Start(HWND hWnd);
  74. virtual BOOL InitInstance() { return TRUE; } // MFC override
  75. virtual int Run() { return -1;} // MFC override
  76. protected:
  77. BOOL PostMessageToWnd(WPARAM wParam, LPARAM lParam);
  78. private:
  79. HWND m_hWnd;
  80. };
  81. /////////////////////////////////////////////////////////////////////////////
  82. // CWorkerThread
  83. class CWorkerThread : public CWinThread
  84. {
  85. public:
  86. CWorkerThread();
  87. virtual ~CWorkerThread();
  88. BOOL Start(HWND hWnd);
  89. virtual BOOL InitInstance() { return TRUE; } // MFC override
  90. virtual int Run() { return -1;} // MFC override
  91. // REVIEWED-2002/03/08-JeffJon-There appears to be no danger
  92. // of getting stuck in the critical section
  93. void Lock() { ::EnterCriticalSection(&m_cs); }
  94. void Unlock() { ::LeaveCriticalSection(&m_cs); }
  95. void Abandon();
  96. BOOL IsAbandoned();
  97. void AcknowledgeExiting() { VERIFY(0 != ::SetEvent(m_hEventHandle));}
  98. protected:
  99. virtual void OnAbandon() {}
  100. protected:
  101. BOOL PostMessageToWnd(UINT Msg, WPARAM wParam, LPARAM lParam);
  102. void WaitForExitAcknowledge();
  103. private:
  104. CRITICAL_SECTION m_cs;
  105. HANDLE m_hEventHandle;
  106. HWND m_hWnd;
  107. BOOL m_bAbandoned;
  108. };
  109. ////////////////////////////////////////////////////////////////////
  110. // CHiddenWnd : Hidden window to syncronize threads and CComponentData object
  111. class CHiddenWnd : public CHiddenWndBase
  112. {
  113. public:
  114. CHiddenWnd(CComponentDataObject* pComponentDataObject);
  115. static const UINT s_NodeThreadHaveDataNotificationMessage;
  116. static const UINT s_NodeThreadErrorNotificationMessage;
  117. static const UINT s_NodeThreadExitingNotificationMessage;
  118. static const UINT s_NodePropertySheetCreateMessage;
  119. static const UINT s_NodePropertySheetDeleteMessage;
  120. static const UINT s_ExecCommandMessage;
  121. static const UINT s_ForceEnumerationMessage;
  122. static const UINT s_TimerThreadMessage;
  123. UINT_PTR m_nTimerID;
  124. private:
  125. CComponentDataObject* m_pComponentDataObject; // back pointer
  126. public:
  127. BEGIN_MSG_MAP(CHiddenWnd)
  128. MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadHaveDataNotificationMessage, OnNodeThreadHaveDataNotification )
  129. MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadErrorNotificationMessage, OnNodeThreadErrorNotification )
  130. MESSAGE_HANDLER( CHiddenWnd::s_NodeThreadExitingNotificationMessage, OnNodeThreadExitingNotification )
  131. MESSAGE_HANDLER( CHiddenWnd::s_NodePropertySheetCreateMessage, OnNodePropertySheetCreate )
  132. MESSAGE_HANDLER( CHiddenWnd::s_NodePropertySheetDeleteMessage, OnNodePropertySheetDelete )
  133. MESSAGE_HANDLER( CHiddenWnd::s_ExecCommandMessage, OnExecCommand )
  134. MESSAGE_HANDLER( CHiddenWnd::s_ForceEnumerationMessage, OnForceEnumeration )
  135. MESSAGE_HANDLER( CHiddenWnd::s_TimerThreadMessage, OnTimerThread )
  136. MESSAGE_HANDLER( WM_TIMER, OnTimer )
  137. CHAIN_MSG_MAP(CHiddenWndBase)
  138. END_MSG_MAP()
  139. LRESULT OnNodeThreadHaveDataNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  140. LRESULT OnNodeThreadErrorNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  141. LRESULT OnNodeThreadExitingNotification(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  142. LRESULT OnNodePropertySheetCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  143. LRESULT OnNodePropertySheetDelete(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  144. LRESULT OnExecCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  145. LRESULT OnForceEnumeration(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  146. LRESULT OnTimerThread(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  147. LRESULT OnTimer(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
  148. };
  149. ////////////////////////////////////////////////////////////////////////////////////
  150. // CRunningThreadTable
  151. // all CMTContainerNode with running refresh/enumerate background threads will
  152. // register/unregister in this table to allow proper thread abandoning at shutdown
  153. class CRunningThreadTable
  154. {
  155. public:
  156. CRunningThreadTable(CComponentDataObject* pComponentData);
  157. ~CRunningThreadTable();
  158. void Add(CMTContainerNode* pNode);
  159. void Remove(CMTContainerNode* pNode);
  160. void RemoveAll();
  161. BOOL IsPresent(CMTContainerNode* pNode);
  162. private:
  163. CComponentDataObject* m_pComponentData; // back pointer
  164. CMTContainerNode** m_pEntries;
  165. int m_nSize;
  166. };
  167. ////////////////////////////////////////////////////////////////////////////////////
  168. // CExecContext
  169. class CExecContext
  170. {
  171. public:
  172. CExecContext();
  173. ~CExecContext();
  174. virtual void Execute(LPARAM arg) = 0; // code to be executed from main thread
  175. virtual void Wait(); // secondary thread waits on this call
  176. virtual void Done(); // called when main thread done executing
  177. protected:
  178. HANDLE m_hEventHandle;
  179. };
  180. ////////////////////////////////////////////////////////////////////////////////////
  181. // CNotificationSinkBase
  182. class CNotificationSinkBase
  183. {
  184. public:
  185. virtual void OnNotify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2) = 0;
  186. };
  187. ////////////////////////////////////////////////////////////////////////////////////
  188. // CNotificationSinkEvent
  189. class CNotificationSinkEvent : public CNotificationSinkBase
  190. {
  191. public:
  192. CNotificationSinkEvent();
  193. ~CNotificationSinkEvent();
  194. public:
  195. void OnNotify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2);
  196. virtual void Wait();
  197. private:
  198. HANDLE m_hEventHandle;
  199. };
  200. ////////////////////////////////////////////////////////////////////////////////////
  201. // CNotificationSinkTable
  202. class CNotificationSinkTable
  203. {
  204. public:
  205. CNotificationSinkTable();
  206. ~CNotificationSinkTable();
  207. void Advise(CNotificationSinkBase* p);
  208. void Unadvise(CNotificationSinkBase* p);
  209. void Notify(DWORD dwEvent, WPARAM dwArg1, LPARAM dwArg2);
  210. private:
  211. void Lock()
  212. {
  213. TRACE(_T("CNotificationSinkTable::Lock()\n"));
  214. // REVIEWED-2002/03/08-JeffJon-There appears to be no danger
  215. // of getting stuck in the critical section
  216. ::EnterCriticalSection(&m_cs);
  217. }
  218. void Unlock()
  219. {
  220. TRACE(_T("CNotificationSinkTable::Unlock()\n"));
  221. ::LeaveCriticalSection(&m_cs);
  222. }
  223. CRITICAL_SECTION m_cs;
  224. CNotificationSinkBase** m_pEntries;
  225. int m_nSize;
  226. };
  227. ////////////////////////////////////////////////////////////////////////////////////
  228. // CPersistStreamImpl
  229. class CPersistStreamImpl : public IPersistStream
  230. {
  231. public:
  232. HRESULT STDMETHODCALLTYPE GetClassID(CLSID* pClassID) = 0;
  233. HRESULT STDMETHODCALLTYPE IsDirty() = 0;
  234. HRESULT STDMETHODCALLTYPE Load(IStream __RPC_FAR *pStm) = 0;
  235. HRESULT STDMETHODCALLTYPE Save(IStream __RPC_FAR *pStm, BOOL fClearDirty) = 0;
  236. HRESULT STDMETHODCALLTYPE GetSizeMax(ULARGE_INTEGER *pcbSize)
  237. {
  238. ASSERT(FALSE);
  239. //
  240. // arbitrary value, do we ever get called?
  241. //
  242. pcbSize->LowPart = 0xffff;
  243. pcbSize->HighPart= 0x0;
  244. return S_OK;
  245. }
  246. };
  247. ///////////////////////////////////////////////////////////////////////////////
  248. // CWatermarkInfo
  249. class CWatermarkInfo
  250. {
  251. public:
  252. CWatermarkInfo()
  253. {
  254. m_nIDBanner = 0;
  255. m_nIDWatermark = 0;
  256. m_hPalette = NULL;
  257. m_bStretch = TRUE;
  258. }
  259. UINT m_nIDBanner;
  260. UINT m_nIDWatermark;
  261. HPALETTE m_hPalette;
  262. BOOL m_bStretch;
  263. };
  264. ////////////////////////////////////////////////////////////////////////////////
  265. // CColumn
  266. class CColumn
  267. {
  268. public:
  269. CColumn(LPCWSTR lpszColumnHeader,
  270. int nFormat,
  271. int nWidth,
  272. UINT nColumnNum)
  273. {
  274. m_lpszColumnHeader = NULL;
  275. SetHeader(lpszColumnHeader);
  276. m_nFormat = nFormat;
  277. m_nWidth = nWidth;
  278. m_nColumnNum = nColumnNum;
  279. }
  280. ~CColumn()
  281. {
  282. free(m_lpszColumnHeader);
  283. }
  284. LPCWSTR GetHeader() { return (LPCWSTR)m_lpszColumnHeader; }
  285. void SetHeader(LPCWSTR lpszColumnHeader)
  286. {
  287. if (m_lpszColumnHeader != NULL)
  288. {
  289. free(m_lpszColumnHeader);
  290. }
  291. // We are assuming the column header is NULL terminated. Since this is usually
  292. // pulled from the resource and there is no good way to verify that it is NULL
  293. // terminated this usage should be fine.
  294. size_t iLen = wcslen(lpszColumnHeader);
  295. m_lpszColumnHeader = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
  296. if (m_lpszColumnHeader != NULL)
  297. {
  298. HRESULT hr = StringCchCopyW(m_lpszColumnHeader, iLen + 1, lpszColumnHeader);
  299. ASSERT(SUCCEEDED(hr));
  300. }
  301. }
  302. int GetFormat() { return m_nFormat; }
  303. void SetFormat(int nFormat) { m_nFormat = nFormat; }
  304. int GetWidth() { return m_nWidth; }
  305. void SetWidth(int nWidth) { m_nWidth = nWidth; }
  306. UINT GetColumnNum() { return m_nColumnNum; }
  307. void SetColumnNum(UINT nColumnNum) { m_nColumnNum = nColumnNum; }
  308. protected:
  309. LPWSTR m_lpszColumnHeader;
  310. int m_nFormat;
  311. int m_nWidth;
  312. UINT m_nColumnNum;
  313. };
  314. ////////////////////////////////////////////////////////////////////////////////
  315. // CColumnSet
  316. class CColumnSet : public CList<CColumn*, CColumn*>
  317. {
  318. public :
  319. CColumnSet(LPCWSTR lpszColumnID)
  320. {
  321. // We are assuming the columnID is NULL terminated. Since this is usually
  322. // hardcoded and there is no good way to verify that it is NULL terminated
  323. // this usage should be fine.
  324. size_t iLen = wcslen(lpszColumnID);
  325. m_lpszColumnID = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
  326. if (m_lpszColumnID != NULL)
  327. {
  328. // Make a copy of the column set ID
  329. HRESULT hr = StringCchCopyW(m_lpszColumnID, iLen + 1, lpszColumnID);
  330. ASSERT(SUCCEEDED(hr));
  331. }
  332. }
  333. CColumnSet(LPCWSTR lpszColumnID, CList<CColumn*, CColumn*>&)
  334. {
  335. // We are assuming the columnID is NULL terminated. Since this is usually
  336. // hardcoded and there is no good way to verify that it is NULL terminated
  337. // this usage should be fine.
  338. size_t iLen = wcslen(lpszColumnID);
  339. m_lpszColumnID = (LPWSTR)malloc(sizeof(WCHAR) * (iLen + 1));
  340. if (m_lpszColumnID)
  341. {
  342. // Make a copy of the column set ID
  343. HRESULT hr = StringCchCopyW(m_lpszColumnID, iLen + 1, lpszColumnID);
  344. ASSERT(SUCCEEDED(hr));
  345. }
  346. }
  347. ~CColumnSet()
  348. {
  349. while(!IsEmpty())
  350. {
  351. CColumn* pColumn = RemoveTail();
  352. delete pColumn;
  353. }
  354. free(m_lpszColumnID);
  355. }
  356. void AddColumn(LPCWSTR lpszHeader, int nFormat, int nWidth, UINT nCol)
  357. {
  358. CColumn* pNewColumn = new CColumn(lpszHeader, nFormat, nWidth, nCol);
  359. AddTail(pNewColumn);
  360. }
  361. LPCWSTR GetColumnID() { return (LPCWSTR)m_lpszColumnID; }
  362. UINT GetNumCols() { return static_cast<UINT>(GetCount()); }
  363. private :
  364. LPWSTR m_lpszColumnID;
  365. };
  366. ////////////////////////////////////////////////////////////////////////////////
  367. // CColumnSetList
  368. class CColumnSetList : public CList<CColumnSet*, CColumnSet*>
  369. {
  370. public :
  371. // Find the column set given a column set ID
  372. CColumnSet* FindColumnSet(LPCWSTR lpszColumnID)
  373. {
  374. POSITION pos = GetHeadPosition();
  375. while (pos != NULL)
  376. {
  377. CColumnSet* pTempSet = GetNext(pos);
  378. ASSERT(pTempSet != NULL);
  379. LPCWSTR lpszTempNodeID = pTempSet->GetColumnID();
  380. if (wcscmp(lpszTempNodeID, lpszColumnID) == 0)
  381. {
  382. return pTempSet;
  383. }
  384. }
  385. return NULL;
  386. }
  387. void RemoveAndDeleteAllColumnSets()
  388. {
  389. while (!IsEmpty())
  390. {
  391. CColumnSet* pTempSet = RemoveTail();
  392. delete pTempSet;
  393. }
  394. }
  395. };
  396. ///////////////////////////////////////////////////////////////////////////////
  397. // CComponentDataObject
  398. // * this class contains the master tree data (i.e. the "document")
  399. // * base class, have to derive from it
  400. class CWatermarkInfoState; // fwd decl of private class
  401. class CComponentDataObject:
  402. public IComponentData,
  403. public IExtendPropertySheet2,
  404. public IExtendContextMenu,
  405. public CPersistStreamImpl,
  406. public ISnapinHelp2,
  407. public IRequiredExtensions,
  408. public CComObjectRoot
  409. {
  410. BEGIN_COM_MAP(CComponentDataObject)
  411. COM_INTERFACE_ENTRY(IComponentData)
  412. COM_INTERFACE_ENTRY(IExtendPropertySheet2)
  413. COM_INTERFACE_ENTRY(IExtendContextMenu)
  414. COM_INTERFACE_ENTRY(IPersistStream)
  415. COM_INTERFACE_ENTRY(ISnapinHelp2)
  416. COM_INTERFACE_ENTRY(IRequiredExtensions)
  417. END_COM_MAP()
  418. #ifdef _DEBUG_REFCOUNT
  419. static unsigned int m_nOustandingObjects; // # of objects created
  420. int dbg_cRef;
  421. ULONG InternalAddRef()
  422. {
  423. ++dbg_cRef;
  424. TRACE(_T("CComponentDataObject::InternalAddRef() refCount = %d\n"), dbg_cRef);
  425. return CComObjectRoot::InternalAddRef();
  426. }
  427. ULONG InternalRelease()
  428. {
  429. --dbg_cRef;
  430. TRACE(_T("CComponentDataObject::InternalRelease() refCount = %d\n"), dbg_cRef);
  431. return CComObjectRoot::InternalRelease();
  432. }
  433. #endif // _DEBUG_REFCOUNT
  434. CComponentDataObject();
  435. virtual ~CComponentDataObject();
  436. HRESULT FinalConstruct();
  437. void FinalRelease();
  438. public:
  439. // IComponentData interface members
  440. STDMETHOD(Initialize)(LPUNKNOWN pUnknown);
  441. STDMETHOD(CreateComponent)(LPCOMPONENT* ppComponent) = 0; // must override
  442. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param);
  443. STDMETHOD(Destroy)();
  444. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie, DATA_OBJECT_TYPES type, LPDATAOBJECT* ppDataObject);
  445. STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM* pScopeDataItem);
  446. STDMETHOD(CompareObjects)(LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB);
  447. // IExtendPropertySheet2 interface members
  448. public:
  449. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  450. LONG_PTR handle,
  451. LPDATAOBJECT lpIDataObject);
  452. STDMETHOD(QueryPagesFor)(LPDATAOBJECT lpDataObject);
  453. STDMETHOD(GetWatermarks)(LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader,
  454. HPALETTE* lphPalette, BOOL* pbStretch);
  455. HRESULT CreatePropertySheet(CTreeNode* pNode, HWND hWndParent, LPCWSTR lpszTitle);
  456. public:
  457. //
  458. // IExtendContextMenu interface members
  459. //
  460. STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
  461. LPCONTEXTMENUCALLBACK pCallbackUnknown,
  462. long *pInsertionAllowed);
  463. STDMETHOD(Command)(long nCommandID, LPDATAOBJECT pDataObject);
  464. //
  465. // IPersistStream interface members
  466. //
  467. STDMETHOD(IsDirty)();
  468. STDMETHOD(Load)(IStream __RPC_FAR *pStm);
  469. STDMETHOD(Save)(IStream __RPC_FAR *pStm, BOOL fClearDirty);
  470. //
  471. // ISnapinHelp2 interface members
  472. //
  473. STDMETHOD(GetHelpTopic)(LPOLESTR* lpCompiledHelpFile);
  474. STDMETHOD(GetLinkedTopics)(LPOLESTR* lpCompiledHelpFile);
  475. //
  476. // IRequiredExtensions interface members
  477. //
  478. STDMETHOD(EnableAllExtensions)() { return S_OK;} // load all always
  479. STDMETHOD(GetFirstExtension)(LPCLSID) { return S_FALSE;} // should not be called
  480. STDMETHOD(GetNextExtension)(LPCLSID) { return S_FALSE;} // should not be called
  481. // virtual functions
  482. protected:
  483. virtual HRESULT OnSetImages(LPIMAGELIST lpScopeImage) = 0; // must override
  484. virtual HRESULT OnExtensionExpand(LPDATAOBJECT, LPARAM)
  485. { return E_FAIL;}
  486. virtual HRESULT OnRemoveChildren(LPDATAOBJECT lpDataObject, LPARAM arg);
  487. // Notify handler declarations
  488. private:
  489. HRESULT OnAdd(CTreeNode* cookie, LPARAM arg, LPARAM param);
  490. HRESULT OnRename(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  491. HRESULT OnExpand(CInternalFormatCracker& ifc,
  492. LPARAM arg,
  493. LPARAM param,
  494. BOOL bAsync = TRUE);
  495. HRESULT OnSelect(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  496. HRESULT OnContextMenu(CTreeNode* cookie, LPARAM arg, LPARAM param);
  497. HRESULT OnPropertyChange(LPARAM param, long fScopePane);
  498. // Scope item creation helpers
  499. private:
  500. void EnumerateScopePane(CTreeNode* cookie,
  501. HSCOPEITEM pParent,
  502. BOOL bAsync = TRUE);
  503. BOOL IsScopePaneNode(LPDATAOBJECT lpDataObject);
  504. // Helpers
  505. public:
  506. LPCONSOLE GetConsole() { return m_pConsole;}
  507. HRESULT OnDeleteVerbHandler(CInternalFormatCracker& ifc, CComponentObject* pComponentObject);
  508. HRESULT OnRefreshVerbHandler(CInternalFormatCracker& ifc);
  509. HRESULT OnHelpHandler(CInternalFormatCracker& ifc, CComponentObject* pComponentObject);
  510. HRESULT AddNode(CTreeNode* pNodeToAdd);
  511. HRESULT AddNodeSorted(CTreeNode* pNodeToAdd);
  512. HRESULT DeleteNode(CTreeNode* pNodeToDelete);
  513. HRESULT DeleteMultipleNodes(CNodeList* pNodeList);
  514. HRESULT ChangeNode(CTreeNode* pNodeToChange, long changeMask);
  515. HRESULT UpdateVerbState(CTreeNode* pNodeToChange);
  516. HRESULT RemoveAllChildren(CContainerNode* pNode);
  517. HRESULT RepaintSelectedFolderInResultPane();
  518. HRESULT RepaintResultPane(CContainerNode* pNode);
  519. HRESULT DeleteAllResultPaneItems(CContainerNode* pNode);
  520. HRESULT SortResultPane(CContainerNode* pContainerNode);
  521. HRESULT UpdateResultPaneView(CContainerNode* pContainerNode);
  522. CPropertyPageHolderTable* GetPropertyPageHolderTable() { return &m_PPHTable; }
  523. CRunningThreadTable* GetRunningThreadTable() { return &m_RTTable; }
  524. CNotificationSinkTable* GetNotificationSinkTable() { return &m_NSTable; }
  525. void WaitForThreadExitMessage(CMTContainerNode* pNode);
  526. CWatermarkInfo* SetWatermarkInfo(CWatermarkInfo* pWatermarkInfo);
  527. BOOL IsExtensionSnapin() { return m_bExtensionSnapin; }
  528. void SetLogFileName(PCWSTR pszLogName) { LOGFILE_NAME = pszLogName; }
  529. protected:
  530. void SetExtensionSnapin(BOOL bExtensionSnapin)
  531. { m_bExtensionSnapin = bExtensionSnapin;}
  532. private:
  533. HRESULT UpdateAllViewsHelper(LPARAM data, LONG_PTR hint);
  534. void HandleStandardVerbsHelper(CComponentObject* pComponentObj,
  535. LPCONSOLEVERB pConsoleVerb,
  536. BOOL bScope, BOOL bSelect,
  537. LPDATAOBJECT lpDataObject);
  538. protected:
  539. virtual HRESULT SnapinManagerCreatePropertyPages(LPPROPERTYSHEETCALLBACK,
  540. LONG_PTR) {return S_FALSE; }
  541. virtual BOOL HasPropertyPages(DATA_OBJECT_TYPES) {return FALSE; }
  542. virtual void OnInitialize();
  543. virtual void OnDestroy();
  544. // help handling
  545. virtual LPCWSTR GetHTMLHelpFileName() { return NULL; }
  546. BOOL WinHelp(LPCTSTR lpszHelpFileName, UINT uCommand, DWORD dwData);
  547. virtual void OnNodeContextHelp(CTreeNode*){}
  548. virtual void OnNodeContextHelp(CNodeList*) {}
  549. public:
  550. virtual void OnDialogContextHelp(UINT, HELPINFO*) {}
  551. virtual BOOL IsMultiSelect() { return FALSE; }
  552. // Scope pane helpers
  553. public:
  554. protected:
  555. HRESULT AddContainerNode(CContainerNode* pNodeToInsert, HSCOPEITEM pParentScopeItem);
  556. HRESULT AddContainerNodeSorted(CContainerNode* pNodeToInsert, HSCOPEITEM pParentScopeItem);
  557. private:
  558. HRESULT DeleteContainerNode(CContainerNode* pNodeToDelete);
  559. HRESULT ChangeContainerNode(CContainerNode* pNodeToChange, long changeMask);
  560. void InitializeScopeDataItem(LPSCOPEDATAITEM pScopeDataItem, HSCOPEITEM pParentScopeItem, LPARAM lParam,
  561. int nImage, int nOpenImage, BOOL bHasChildren);
  562. // Column Set helpers
  563. public:
  564. CColumnSetList* GetColumnSetList() { return &m_ColList; }
  565. private:
  566. CColumnSetList m_ColList;
  567. // Result pane helpers
  568. public:
  569. protected:
  570. private:
  571. HRESULT AddLeafNode(CLeafNode* pNodeToAdd);
  572. HRESULT DeleteLeafNode(CLeafNode* pNodeToDelete);
  573. HRESULT ChangeLeafNode(CLeafNode* pNodeToChange, long changeMask);
  574. // Attributes
  575. private:
  576. LPCONSOLE m_pConsole; // IConsole interface pointer
  577. LPCONSOLENAMESPACE2 m_pConsoleNameSpace; // IConsoleNameSpace interface pointer
  578. CPropertyPageHolderTable m_PPHTable; // property page holder table
  579. CRunningThreadTable m_RTTable; // table of running MT nodes
  580. CNotificationSinkTable m_NSTable; // notification sink table, for advise in events
  581. CWatermarkInfoState* m_pWatermarkInfoState; // internal watermark info for Wizards
  582. BOOL m_bExtensionSnapin; // is this an extension?
  583. // critical section (Serialization of calls to console)
  584. public:
  585. // REVIEWED-2002/03/08-JeffJon-There appears to be no danger
  586. // of getting stuck in the critical section
  587. void Lock() { ::EnterCriticalSection(&m_cs); }
  588. void Unlock() { ::LeaveCriticalSection(&m_cs); }
  589. private:
  590. CRITICAL_SECTION m_cs; // general purpose critical section
  591. // RootData
  592. protected:
  593. CRootData* m_pRootData; // root node for the cache
  594. virtual CRootData* OnCreateRootData() = 0; // must override
  595. public:
  596. CRootData* GetRootData() { ASSERT(m_pRootData != NULL); return m_pRootData;}
  597. // Hidden window
  598. private:
  599. CHiddenWnd m_hiddenWnd; // syncronization with background threads
  600. CTimerThread* m_pTimerThreadObj; // timer thread object
  601. HWND m_hWnd; // thread safe HWND (gotten from the MFC CWnd)
  602. public:
  603. BOOL PostExecMessage(CExecContext* pExec, LPARAM arg); // call from secondary thread
  604. BOOL PostForceEnumeration(CMTContainerNode* pContainerNode); // call from secondary thread
  605. HWND GetHiddenWindow() { ASSERT(m_hWnd != NULL); return m_hWnd;}
  606. BOOL OnCreateSheet(CPropertyPageHolderBase* pPPHolder, HWND hWnd);
  607. BOOL OnDeleteSheet(CPropertyPageHolderBase* pPPHolder, CTreeNode* pNode);
  608. HRESULT SetDescriptionBarText(CTreeNode* pTreeNode);
  609. // Timer and Background Thread
  610. public:
  611. BOOL StartTimerThread();
  612. void ShutDownTimerThread();
  613. BOOL PostMessageToTimerThread(UINT Msg, WPARAM wparam, LPARAM lParam);
  614. DWORD GetTimerInterval() { return m_dwTimerInterval;}
  615. protected:
  616. DWORD m_dwTimerTime; // sec
  617. // overrides that MUST be implemented
  618. virtual void OnTimer() { ASSERT(FALSE); }
  619. virtual void OnTimerThread(WPARAM, LPARAM) { ASSERT(FALSE); }
  620. virtual CTimerThread* OnCreateTimerThread() { return NULL; }
  621. private:
  622. BOOL SetTimer();
  623. void KillTimer();
  624. void WaitForTimerThreadStartAck();
  625. DWORD m_nTimerThreadID;
  626. BOOL m_bTimerThreadStarted;
  627. DWORD m_dwTimerInterval; // sec
  628. // friend class declarations
  629. friend class CDataObject; // for the GetRootData() member
  630. friend class CComponentObject; // for the FindObject() and OnPropertyChange() members
  631. friend class CHiddenWnd;
  632. };
  633. ///////////////////////////////////////////////////////////////////////////////
  634. // CComponentObject
  635. // * this class is the view on the data contained in the "document"
  636. // * base class, have to derive from it
  637. class CComponentObject :
  638. public IComponent,
  639. public IExtendPropertySheet2,
  640. public IExtendContextMenu,
  641. public IExtendControlbar,
  642. public IResultDataCompareEx,
  643. public CComObjectRoot
  644. {
  645. public:
  646. #ifdef _DEBUG_REFCOUNT
  647. static unsigned int m_nOustandingObjects; // # of objects created
  648. int dbg_cRef;
  649. ULONG InternalAddRef()
  650. {
  651. ++dbg_cRef;
  652. return CComObjectRoot::InternalAddRef();
  653. }
  654. ULONG InternalRelease()
  655. {
  656. --dbg_cRef;
  657. return CComObjectRoot::InternalRelease();
  658. }
  659. #endif // _DEBUG_REFCOUNT
  660. CComponentObject();
  661. virtual ~CComponentObject();
  662. BEGIN_COM_MAP(CComponentObject)
  663. COM_INTERFACE_ENTRY(IComponent)
  664. COM_INTERFACE_ENTRY(IExtendPropertySheet2)
  665. COM_INTERFACE_ENTRY(IExtendContextMenu)
  666. COM_INTERFACE_ENTRY(IExtendControlbar)
  667. COM_INTERFACE_ENTRY(IResultDataCompareEx)
  668. END_COM_MAP()
  669. public:
  670. //
  671. // IComponent interface members
  672. //
  673. STDMETHOD(Initialize)(LPCONSOLE lpConsole);
  674. STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param);
  675. STDMETHOD(Destroy)(MMC_COOKIE cookie);
  676. STDMETHOD(GetResultViewType)(MMC_COOKIE cookie, LPOLESTR* ppViewType, long* pViewOptions);
  677. STDMETHOD(QueryDataObject)(MMC_COOKIE cookie, DATA_OBJECT_TYPES type,
  678. LPDATAOBJECT* ppDataObject);
  679. STDMETHOD(GetDisplayInfo)(LPRESULTDATAITEM pResultDataItem);
  680. STDMETHOD(CompareObjects)( LPDATAOBJECT lpDataObjectA, LPDATAOBJECT lpDataObjectB);
  681. //
  682. // IExtendPropertySheet2 interface members
  683. //
  684. STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider,
  685. LONG_PTR handle,
  686. LPDATAOBJECT lpIDataObject);
  687. STDMETHOD(QueryPagesFor)(LPDATAOBJECT lpDataObject);
  688. STDMETHOD(GetWatermarks)(LPDATAOBJECT lpDataObject, HBITMAP* lphWatermark, HBITMAP* lphHeader,
  689. HPALETTE* lphPalette, BOOL* pbStretch);
  690. //
  691. // IExtendContextMenu interface members
  692. //
  693. STDMETHOD(AddMenuItems)(LPDATAOBJECT pDataObject,
  694. LPCONTEXTMENUCALLBACK pCallbackUnknown,
  695. long *pInsertionAllowed);
  696. STDMETHOD(Command)(long nCommandID, LPDATAOBJECT pDataObject);
  697. //
  698. // IExtendControlbar interface memebers
  699. //
  700. STDMETHOD(SetControlbar)(LPCONTROLBAR pControlbar);
  701. STDMETHOD(ControlbarNotify)(MMC_NOTIFY_TYPE type, LPARAM arg, LPARAM param);
  702. //
  703. // IResultDataCompare
  704. //
  705. STDMETHOD(Compare)(RDCOMPARE* prdc, int* pnResult);
  706. // Helpers for CComponentObject
  707. public:
  708. void SetIComponentData(CComponentDataObject* pData);
  709. void SetSelectedNode(CTreeNode* pSelectedNode, DATA_OBJECT_TYPES selectedType)
  710. { m_pSelectedNode = pSelectedNode; m_selectedType = selectedType; }
  711. // Notify event handlers
  712. protected:
  713. HRESULT OnFolder(CTreeNode* cookie, LPARAM arg, LPARAM param);
  714. HRESULT OnShow(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  715. HRESULT OnActivate(CTreeNode* cookie, LPARAM arg, LPARAM param);
  716. HRESULT OnResultItemClk(CInternalFormatCracker& ifc, BOOL fDblClick);
  717. HRESULT OnMinimize(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  718. HRESULT OnPropertyChange(LPARAM param, long fScopePane);
  719. HRESULT OnUpdateView(LPDATAOBJECT lpDataObject, LPARAM data, LONG_PTR hint);
  720. HRESULT OnAddImages(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  721. HRESULT SetDescriptionBarText(CTreeNode* pTreeNode);
  722. // Added by JEFFJON : response to MMCN_COLUMNS_CHANGED
  723. HRESULT OnColumnsChanged(CInternalFormatCracker& ifc, LPARAM arg, LPARAM param);
  724. HRESULT OnColumnSortChanged(LPARAM arg, LPARAM param);
  725. // Helper functions
  726. protected:
  727. BOOL IsEnumerating(LPDATAOBJECT lpDataObject);
  728. void Construct();
  729. void LoadResources();
  730. virtual HRESULT InitializeHeaders(CContainerNode* pContainerNode) = 0;
  731. virtual HRESULT InitializeToolbar(IToolbar*) { return E_NOTIMPL; }
  732. public:
  733. HRESULT ForceSort(UINT iCol, DWORD dwDirection);
  734. protected:
  735. void EnumerateResultPane(CContainerNode* pContainerNode);
  736. // Result pane helpers
  737. virtual HRESULT InitializeBitmaps(CTreeNode* cookie) = 0;
  738. void HandleStandardVerbs(BOOL bScope, BOOL bSelect, LPDATAOBJECT lpDataObject);
  739. HRESULT AddResultPaneItem(CLeafNode* pNodeToInsert);
  740. HRESULT DeleteResultPaneItem(CLeafNode* pNodeToDelete);
  741. HRESULT ChangeResultPaneItem(CLeafNode* pNodeToChange, LONG_PTR changeMask);
  742. HRESULT FindResultPaneItemID(CLeafNode* pNode, HRESULTITEM* pItemID);
  743. // Interface pointers
  744. protected:
  745. LPCONSOLE m_pConsole; // IConsole interface pointer
  746. LPHEADERCTRL m_pHeader; // Result pane's header control interface
  747. LPRESULTDATA m_pResult; // My interface pointer to the result pane
  748. LPIMAGELIST m_pImageResult; // My interface pointer to the result pane image list
  749. LPTOOLBAR m_pToolbar; // Toolbar for view
  750. LPCONTROLBAR m_pControlbar; // control bar to hold my tool bars
  751. LPCONSOLEVERB m_pConsoleVerb; // pointer the console verb
  752. LPCOMPONENTDATA m_pComponentData; // Pointer to the IComponentData this object belongs to
  753. // state variables for this window
  754. CContainerNode* m_pSelectedContainerNode; // scope item selection (MMCN_SHOW)
  755. CTreeNode* m_pSelectedNode; // item selection (MMC_SELECT)
  756. DATA_OBJECT_TYPES m_selectedType; // matching m_pSelectedNode
  757. };
  758. inline void CComponentObject::SetIComponentData(CComponentDataObject* pData)
  759. {
  760. TRACE(_T("CComponentObject::SetIComponentData()\n"));
  761. ASSERT(pData);
  762. ASSERT(m_pComponentData == NULL);
  763. LPUNKNOWN pUnk = pData->GetUnknown(); // does not addref
  764. HRESULT hr;
  765. hr = pUnk->QueryInterface(IID_IComponentData, reinterpret_cast<void**>(&m_pComponentData));
  766. ASSERT(hr == S_OK);
  767. }
  768. #define FREE_INTERNAL(pInternal) \
  769. ASSERT(pInternal != NULL); \
  770. do { if (pInternal != NULL) \
  771. GlobalFree(pInternal); } \
  772. while(0);
  773. // This wrapper function required to make prefast shut up when we are
  774. // initializing a critical section in a constructor.
  775. void ExceptionPropagatingInitializeCriticalSection(LPCRITICAL_SECTION critsec);
  776. #endif //_COMPBASE_H