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.

491 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation
  4. Module Name:
  5. PropertyPage.h
  6. This template class is currently implemented inline.
  7. There is node PropertyPage.cpp for implementation.
  8. Abstract:
  9. Header file for the CIASPropertyPage class.
  10. This is our virtual base class for an MMC property page.
  11. Author:
  12. Michael A. Maguire 11/24/97
  13. Revision History:
  14. mmaguire 11/24/97 - created
  15. --*/
  16. //////////////////////////////////////////////////////////////////////////////
  17. #if !defined(_PROPERTY_PAGE_H_)
  18. #define _PROPERTY_PAGE_H_
  19. //=============================================================================
  20. // Global Help Table for many Dialog IDs
  21. //
  22. #include "hlptable.h"
  23. //////////////////////////////////////////////////////////////////////////////
  24. // BEGIN INCLUDES
  25. //
  26. // where we can find what this class derives from:
  27. //
  28. // Moved to Precompiled.h: #include <atlsnap.h>
  29. //
  30. //
  31. // where we can find what this class has or uses:
  32. //
  33. //
  34. // END INCLUDES
  35. //////////////////////////////////////////////////////////////////////////////
  36. // This object is shared among all property pages
  37. // up for a given node and keeps a ref count
  38. // of how many pages have not yet made sure all their data is clean.
  39. // As long as this is non-zero, we don't commit our data.
  40. // Create it when you first make the property pages,
  41. // AddRef for each page you add it to, and delete
  42. // it when you check and find that the refcount is 0.
  43. class CSynchronizer
  44. {
  45. public:
  46. CSynchronizer::CSynchronizer()
  47. {
  48. m_lRefCount = 0;
  49. m_lCount = 0;
  50. m_lHighestCount = 0;
  51. }
  52. // Usual AddRef as for COM objects -- governs lifetime of this synchronizer object.
  53. LONG AddRef( void )
  54. {
  55. return m_lRefCount++;
  56. }
  57. // Usual Release as for COM objects -- governs lifetime of this synchronizer object.
  58. LONG Release( void )
  59. {
  60. LONG lRefCount = --m_lRefCount;
  61. if( 0 == m_lRefCount )
  62. {
  63. delete this;
  64. }
  65. return lRefCount;
  66. }
  67. // Raises count of interacting objects depending on this synchronizer.
  68. // Use this if an object has seen some data and will now need a
  69. // change to validate its data before allowing the data to be saved.
  70. LONG RaiseCount( void )
  71. {
  72. m_lCount++;
  73. if( m_lCount > m_lHighestCount )
  74. {
  75. m_lHighestCount = m_lCount;
  76. }
  77. return m_lCount;
  78. }
  79. // Lowers count of interacting objects depending on this synchronizer.
  80. // Use this if an object makes it through the validation of its data and is good to go.
  81. LONG LowerCount( void )
  82. {
  83. return --m_lCount;
  84. }
  85. // Resets count to highest it ever was during lifetime of this synchrnizer.
  86. // Use this if your objects all need to go through the data validation process again.
  87. LONG ResetCountToHighest( void )
  88. {
  89. return( m_lCount = m_lHighestCount );
  90. }
  91. protected:
  92. // This is just to govern the lifetime of this object.
  93. LONG m_lRefCount;
  94. // This is used to keep track of dependencies of several other objects.
  95. LONG m_lCount;
  96. // This is used to keep several other objects synchronized.
  97. LONG m_lHighestCount;
  98. };
  99. template <class T>
  100. class CIASPropertyPageNoHelp : public CSnapInPropertyPageImpl<T>
  101. {
  102. public :
  103. BEGIN_MSG_MAP(CIASPropertyPageNoHelp<T>)
  104. CHAIN_MSG_MAP(CSnapInPropertyPageImpl<T>)
  105. END_MSG_MAP()
  106. protected:
  107. /////////////////////////////////////////////////////////////////////////////
  108. /*++
  109. CIASPropertyPageNoHelp::CIASPropertyPageNoHelp
  110. Constructor
  111. We never want someone to instantiate an object of CIASPage -- it should
  112. be an abstract base class from which we derive.
  113. --*/
  114. //////////////////////////////////////////////////////////////////////////////
  115. CIASPropertyPageNoHelp(
  116. LONG_PTR hNotificationHandle,
  117. TCHAR* pTitle = NULL,
  118. BOOL bOwnsNotificationHandle = FALSE
  119. )
  120. : CSnapInPropertyPageImpl<T> (hNotificationHandle, pTitle, bOwnsNotificationHandle)
  121. {
  122. ATLTRACE(_T("# +++ CIASPropertyPageNoHelp::CIASPropertyPageNoHelp\n"));
  123. // Check for preconditions:
  124. // None.
  125. // Initialize the Synchronizer handle.
  126. m_pSynchronizer = NULL;
  127. }
  128. public:
  129. /////////////////////////////////////////////////////////////////////////////
  130. /*++
  131. CIASPropertyPageNoHelp::~CIASPropertyPageNoHelp
  132. Destructor
  133. This needs to be public as it has to be accessed from from a static callback
  134. function (PropPageCallback) which responds to the PSPCB_RELEASE notification
  135. by deleting the property page.
  136. --*/
  137. //////////////////////////////////////////////////////////////////////////////
  138. virtual ~CIASPropertyPageNoHelp()
  139. {
  140. ATLTRACE(_T("# --- CIASPropertyPageNoHelp::~CIASPropertyPageNoHelp\n"));
  141. // Check for preconditions:
  142. if( m_pSynchronizer != NULL )
  143. {
  144. m_pSynchronizer->Release();
  145. }
  146. }
  147. // This points to an object shared among all property pages
  148. // for a given node that keeps a ref count
  149. // of how many pages have not yet made sure all their data is clean.
  150. // As long as this is non-zero, we don't commit our data.
  151. CSynchronizer * m_pSynchronizer;
  152. };
  153. template <class T>
  154. class CIASPropertyPage : public CSnapInPropertyPageImpl<T>
  155. {
  156. protected:
  157. const DWORD *m_pHelpTable; // Help id pairs
  158. public :
  159. BEGIN_MSG_MAP(CIASPropertyPage<T>)
  160. MESSAGE_HANDLER(WM_CONTEXTMENU, OnContextHelp )
  161. MESSAGE_HANDLER(WM_HELP, OnF1Help )
  162. CHAIN_MSG_MAP(CSnapInPropertyPageImpl<T>)
  163. END_MSG_MAP()
  164. //////////////////////////////////////////////////////////////////////////////
  165. /*++
  166. CIASPropertyPage::OnF1Help
  167. You shouldn't need to override this method in your derived class.
  168. Just initialize your static m_dwHelpMap member variable appropriately.
  169. This is called in response to the WM_HELP Notify message.
  170. This message is sent when the user presses F1 or <Shift>-F1
  171. over an item or when the user clicks on the ? icon and then
  172. presses the mouse over an item.
  173. --*/
  174. //////////////////////////////////////////////////////////////////////////////
  175. LRESULT OnF1Help(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  176. {
  177. ATLTRACE(_T("# CIASPropertyPage::OnF1Help\n"));
  178. // Check for preconditions:
  179. // ISSUE: Should we make F1 bring up the same help as pressing the Help
  180. // button as I think the UI guidelines suggest? How do we do that?
  181. HELPINFO* helpinfo = (HELPINFO*) lParam;
  182. if (helpinfo->iContextType == HELPINFO_WINDOW)
  183. {
  184. ::WinHelp(
  185. (HWND) helpinfo->hItemHandle,
  186. HELPFILE_NAME,
  187. HELP_WM_HELP,
  188. (DWORD_PTR)(void*) m_pHelpTable );
  189. }
  190. return TRUE;
  191. }
  192. //////////////////////////////////////////////////////////////////////////////
  193. /*++
  194. CIASPropertyPage::OnContextHelp
  195. You shouldn't need to override this method in your derived class.
  196. Just initialize your static m_dwHelpMap member variable appropriately.
  197. This is called in response to the WM_CONTEXTMENU Notify message.
  198. This message is sent when the user right clicks over an item
  199. and then clicks "What's this?"
  200. --*/
  201. //////////////////////////////////////////////////////////////////////////////
  202. LRESULT OnContextHelp(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  203. {
  204. ATLTRACE(_T("# CIASPropertyPage::OnContextHelp\n"));
  205. // Check for preconditions:
  206. // None.
  207. //ISSUE: See sburns's code in localsec snapin on problem with Windows
  208. // algorithm for default context help for items with ID == -1.
  209. // It doesn't look like we will need to worry about this.
  210. WinHelp(
  211. HELPFILE_NAME
  212. , HELP_CONTEXTMENU
  213. , (DWORD_PTR)(void*) m_pHelpTable
  214. );
  215. return TRUE;
  216. }
  217. /////////////////////////////////////////////////////////////////////////////
  218. /*++
  219. CIASPropertyPage::OnHelp
  220. Remarks:
  221. Don't override this method in your derived class.
  222. Instead, override the GetHelpPath method.
  223. This implementation calls the HtmlHelp API call with the HH_DISPLAY_TOPIC
  224. parameter, supplying the correct path to the compressed HTML help
  225. file for our application. It calls our GetHelpPath
  226. method to get the string to pass in as the fourth parameter
  227. to the HtmlHelp call.
  228. This method is called when the user presses on the Help button of a
  229. property sheet.
  230. It is an override of atlsnap.h CSnapInPropertyPageImpl::OnHelp.
  231. --*/
  232. //////////////////////////////////////////////////////////////////////////////
  233. virtual BOOL OnHelp()
  234. {
  235. ATLTRACE(_T("# CIASPropertyPage::OnHelp -- Don't override\n"));
  236. // Check for preconditions:
  237. HRESULT hr;
  238. WCHAR szHelpFilePath[IAS_MAX_STRING*2];
  239. // Use system API to get windows directory.
  240. UINT uiResult = GetWindowsDirectory( szHelpFilePath, IAS_MAX_STRING );
  241. if( uiResult <=0 || uiResult > IAS_MAX_STRING )
  242. {
  243. return FALSE;
  244. }
  245. WCHAR *szTempAfterWindowsDirectory = szHelpFilePath + lstrlen(szHelpFilePath);
  246. // Load the help file name. Note: IDS_HTMLHELP_FILE = "iasmmc.chm"
  247. int nLoadStringResult = LoadString( _Module.GetResourceInstance(), IDS_HTMLHELP_PATH, szTempAfterWindowsDirectory, IAS_MAX_STRING );
  248. if( nLoadStringResult <= 0 )
  249. {
  250. return TRUE;
  251. }
  252. lstrcat( szTempAfterWindowsDirectory, L"::/" );
  253. WCHAR * szHelpFilePathAfterFileName = szHelpFilePath + lstrlen(szHelpFilePath);
  254. hr = GetHelpPath( szHelpFilePathAfterFileName );
  255. if( FAILED( hr ) )
  256. {
  257. return TRUE;
  258. }
  259. MMCPropertyHelp( szHelpFilePath );
  260. return TRUE;
  261. }
  262. /////////////////////////////////////////////////////////////////////////////
  263. /*++
  264. CIASPropertyPage::GetHelpPath
  265. Remarks:
  266. Override this method in your derived class.
  267. You should return the string with the relevant path within the
  268. compressed HTML file to get help for your property page.
  269. --*/
  270. //////////////////////////////////////////////////////////////////////////////
  271. virtual HRESULT GetHelpPath( LPTSTR szHelpPath )
  272. {
  273. ATLTRACE(_T("# CIASPropertyPage::GetHelpPath -- override in your derived class\n"));
  274. // Check for preconditions:
  275. #ifdef UNICODE_HHCTRL
  276. // ISSUE: We seemed to have a problem with passing WCHAR's to the hhctrl.ocx
  277. // installed on this machine -- it appears to be non-unicode.
  278. lstrcpy( szHelpPath, _T("") );
  279. #else
  280. strcpy( (CHAR *) szHelpPath, "" );
  281. #endif
  282. return S_OK;
  283. }
  284. protected:
  285. /////////////////////////////////////////////////////////////////////////////
  286. /*++
  287. CIASPropertyPage::CIASPropertyPage
  288. Constructor
  289. We never want someone to instantiate an object of CIASPage -- it should
  290. be an abstract base class from which we derive.
  291. --*/
  292. //////////////////////////////////////////////////////////////////////////////
  293. CIASPropertyPage( LONG_PTR hNotificationHandle, TCHAR* pTitle = NULL, BOOL bOwnsNotificationHandle = FALSE) : CSnapInPropertyPageImpl<T> (hNotificationHandle, pTitle, bOwnsNotificationHandle)
  294. {
  295. ATLTRACE(_T("# +++ CIASPropertyPage::CIASPropertyPage\n"));
  296. // Check for preconditions:
  297. // None.
  298. SET_HELP_TABLE(T::IDD);
  299. // Initialize the Synchronizer handle.
  300. m_pSynchronizer = NULL;
  301. }
  302. public:
  303. /////////////////////////////////////////////////////////////////////////////
  304. /*++
  305. CIASPropertyPage::~CIASPropertyPage
  306. Destructor
  307. This needs to be public as it has to be accessed from from a static callback
  308. function (PropPageCallback) which responds to the PSPCB_RELEASE notification
  309. by deleting the property page.
  310. --*/
  311. //////////////////////////////////////////////////////////////////////////////
  312. virtual ~CIASPropertyPage()
  313. {
  314. ATLTRACE(_T("# --- CIASPropertyPage::~CIASPropertyPage\n"));
  315. // Check for preconditions:
  316. if( m_pSynchronizer != NULL )
  317. {
  318. m_pSynchronizer->Release();
  319. }
  320. }
  321. public:
  322. // This points to an object shared among all property pages
  323. // for a given node that keeps a ref count
  324. // of how many pages have not yet made sure all their data is clean.
  325. // As long as this is non-zero, we don't commit our data.
  326. CSynchronizer * m_pSynchronizer;
  327. };
  328. template <class T, int titileId, int subtitleId>
  329. class CIASWizard97Page : public CIASPropertyPageNoHelp<T>
  330. {
  331. protected:
  332. ::CString m_strWizard97Title;
  333. ::CString m_strWizard97SubTitle;
  334. CIASWizard97Page( LONG_PTR hNotificationHandle, TCHAR* pTitle = NULL, BOOL bOwnsNotificationHandle = FALSE)
  335. : CIASPropertyPageNoHelp<T>( hNotificationHandle, pTitle, bOwnsNotificationHandle)
  336. {
  337. SetTitleIds(titileId, subtitleId);
  338. };
  339. public :
  340. void SetTitleIds(int titleId, int subtitleId)
  341. {
  342. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  343. // load titles, and set title with the property page
  344. if(titileId != 0 && subtitleId != 0)
  345. {
  346. m_strWizard97Title.LoadString(titileId);
  347. m_strWizard97SubTitle.LoadString(subtitleId);
  348. SetTitles((LPCTSTR)m_strWizard97Title, (LPCTSTR)m_strWizard97SubTitle);
  349. }
  350. else
  351. {
  352. m_psp.dwFlags |= PSP_HIDEHEADER;
  353. }
  354. };
  355. };
  356. #endif // _PROPERTY_PAGE_H_