Source code of Windows XP (NT5)
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.

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