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.

481 lines
11 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: //
  7. | //
  8. |Description: //
  9. | //
  10. |Created: Paul Skoglund 07-1998 //
  11. | //
  12. |Rev History: //
  13. | Based on code from ATL snapin wizard update for VC++ 6.0 - atlsnap.h
  14. | In this module class CSnapInPropertyPageImpl renamed to
  15. | CMySnapInPropertyPageImpl to avoid name clash
  16. | Modified to provide better support for Wizard style property pages...
  17. |
  18. | 1999 03 22 Paul Skoglund
  19. | Created CMySnapInPropertyWizardImpl template to use like CSnapInPropertyPageImpl
  20. | but specific for Wizard style pages. The template forces declaration of
  21. | Header Title resource ID and a SubHeader Title resource ID as used in the
  22. | PSH_WIZARD97 style.
  23. | Change to use Title as resource ID rather than string.
  24. |
  25. |=======================================================================================*/
  26. #ifndef __PPAGE_H__
  27. #define __PPAGE_H__
  28. #ifndef ATLASSERT
  29. #define ATLASSERT ASSERT
  30. #endif
  31. #include <mmc.h>
  32. #include <commctrl.h>
  33. #pragma comment(lib, "mmc.lib")
  34. #pragma comment(lib, "comctl32.lib")
  35. template <class T, bool bAutoDelete = true>
  36. class ATL_NO_VTABLE CMySnapInPropertyPageImpl : public CDialogImplBase
  37. {
  38. public:
  39. PROPSHEETPAGE m_psp;
  40. operator PROPSHEETPAGE*() { return &m_psp; }
  41. // Construction
  42. CMySnapInPropertyPageImpl(int nTitle)
  43. {
  44. // initialize PROPSHEETPAGE struct
  45. memset(&m_psp, 0, sizeof(PROPSHEETPAGE));
  46. m_psp.dwSize = sizeof(PROPSHEETPAGE);
  47. m_psp.dwFlags = PSP_USECALLBACK;
  48. m_psp.hInstance = _Module.GetResourceInstance();
  49. m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD);
  50. m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc;
  51. m_psp.pfnCallback = T::PropPageCallback;
  52. m_psp.lParam = (LPARAM)this;
  53. if(nTitle != NULL)
  54. {
  55. m_psp.pszTitle = MAKEINTRESOURCE(nTitle);
  56. m_psp.dwFlags |= PSP_USETITLE;
  57. }
  58. }
  59. static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  60. {
  61. ATLASSERT(hWnd == NULL);
  62. if(uMsg == PSPCB_CREATE)
  63. {
  64. CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam;
  65. _Module.AddCreateWndData(&pPage->m_thunk.cd, pPage);
  66. }
  67. if (bAutoDelete && uMsg == PSPCB_RELEASE)
  68. {
  69. T* pPage = (T*)ppsp->lParam;
  70. delete pPage;
  71. }
  72. return 1;
  73. }
  74. HPROPSHEETPAGE Create()
  75. {
  76. return ::CreatePropertySheetPage(&m_psp);
  77. }
  78. BOOL EndDialog(int)
  79. {
  80. // do nothing here, calling ::EndDialog will close the whole sheet
  81. ATLASSERT(FALSE);
  82. return FALSE;
  83. }
  84. // Operations
  85. void CancelToClose()
  86. {
  87. ATLASSERT(::IsWindow(m_hWnd));
  88. ATLASSERT(GetParent() != NULL);
  89. ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L);
  90. }
  91. void SetModified(BOOL bChanged = TRUE)
  92. {
  93. ATLASSERT(::IsWindow(m_hWnd));
  94. ATLASSERT(GetParent() != NULL);
  95. if(bChanged)
  96. ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L);
  97. else
  98. ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);
  99. }
  100. LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
  101. {
  102. ATLASSERT(::IsWindow(m_hWnd));
  103. ATLASSERT(GetParent() != NULL);
  104. return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam);
  105. }
  106. typedef CMySnapInPropertyPageImpl< T, bAutoDelete > thisClass;
  107. BEGIN_MSG_MAP(thisClass)
  108. MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
  109. END_MSG_MAP()
  110. // Message handler
  111. LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  112. {
  113. ATLASSERT(::IsWindow(m_hWnd));
  114. NMHDR* pNMHDR = (NMHDR*)lParam;
  115. // don't handle messages not from the page/sheet itself
  116. if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
  117. {
  118. bHandled = FALSE;
  119. return 1;
  120. }
  121. T* pT = (T*)this;
  122. LRESULT lResult = 0;
  123. // handle default
  124. switch(pNMHDR->code)
  125. {
  126. case PSN_SETACTIVE:
  127. lResult = pT->OnSetActive() ? 0 : -1;
  128. break;
  129. case PSN_KILLACTIVE:
  130. lResult = !pT->OnKillActive();
  131. break;
  132. case PSN_APPLY:
  133. lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
  134. break;
  135. case PSN_RESET:
  136. pT->OnReset();
  137. break;
  138. case PSN_QUERYCANCEL:
  139. lResult = !pT->OnQueryCancel();
  140. break;
  141. case PSN_WIZNEXT:
  142. lResult = !pT->OnWizardNext();
  143. break;
  144. case PSN_WIZBACK:
  145. lResult = !pT->OnWizardBack();
  146. break;
  147. case PSN_WIZFINISH:
  148. lResult = !pT->OnWizardFinish();
  149. break;
  150. case PSN_HELP:
  151. lResult = pT->OnHelp();
  152. break;
  153. default:
  154. bHandled = FALSE; // not handled
  155. }
  156. return lResult;
  157. }
  158. // Overridables
  159. BOOL OnSetActive()
  160. {
  161. return TRUE;
  162. }
  163. BOOL OnKillActive()
  164. {
  165. return TRUE;
  166. }
  167. BOOL OnApply()
  168. {
  169. return TRUE;
  170. }
  171. void OnReset()
  172. {
  173. }
  174. BOOL OnQueryCancel()
  175. {
  176. return TRUE; // ok to cancel
  177. }
  178. BOOL OnWizardBack()
  179. {
  180. return TRUE;
  181. }
  182. BOOL OnWizardNext()
  183. {
  184. return TRUE;
  185. }
  186. BOOL OnWizardFinish()
  187. {
  188. return TRUE;
  189. }
  190. BOOL OnHelp()
  191. {
  192. return TRUE;
  193. }
  194. void DisableControl(UINT id)
  195. {
  196. T* pT = dynamic_cast<T*>(this);
  197. if (!pT)
  198. return;
  199. HWND hWndCtl = pT->GetDlgItem(id);
  200. ASSERT(hWndCtl);
  201. if (hWndCtl)
  202. ::EnableWindow(hWndCtl, FALSE);
  203. }
  204. };
  205. //
  206. // For Wizard Pages...
  207. //
  208. template <class T, bool bAutoDelete = true>
  209. class ATL_NO_VTABLE CMySnapInPropertyWizardImpl : public CDialogImplBase
  210. {
  211. protected:
  212. BOOL OnBaseSetActive()
  213. {
  214. if (m_PagePosition != NOT_A_WIZARD)
  215. {
  216. DWORD dwFlags = 0;
  217. if ( m_PagePosition == FIRST_PAGE )
  218. dwFlags = PSWIZB_NEXT;
  219. else if ( m_PagePosition == MIDDLE_PAGE )
  220. dwFlags = PSWIZB_BACK | PSWIZB_NEXT;
  221. else if ( m_PagePosition == LAST_PAGE )
  222. dwFlags = PSWIZB_BACK | PSWIZB_FINISH;
  223. else if ( m_PagePosition == LASTANDONLY_PAGE )
  224. dwFlags = PSWIZB_FINISH;
  225. ::PostMessage(GetParent(), PSM_SETWIZBUTTONS, 0, (LPARAM) dwFlags);
  226. }
  227. T* pT = (T*)this;
  228. return pT->OnSetActive();
  229. }
  230. public:
  231. PROPSHEETPAGE m_psp;
  232. typedef enum _WIZ_POSITION
  233. {
  234. NOT_A_WIZARD,
  235. FIRST_PAGE,
  236. MIDDLE_PAGE,
  237. LAST_PAGE,
  238. LASTANDONLY_PAGE,
  239. } WIZ_POSITION;
  240. WIZ_POSITION m_PagePosition;
  241. operator PROPSHEETPAGE*() { return &m_psp; }
  242. // Construction
  243. CMySnapInPropertyWizardImpl(WIZ_POSITION pageposition, int nTitle)
  244. {
  245. //
  246. m_PagePosition = pageposition;
  247. // initialize PROPSHEETPAGE struct
  248. memset(&m_psp, 0, sizeof(PROPSHEETPAGE));
  249. m_psp.dwSize = sizeof(PROPSHEETPAGE);
  250. m_psp.dwFlags = PSP_USECALLBACK;
  251. m_psp.hInstance = _Module.GetResourceInstance();
  252. m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD);
  253. m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc;
  254. m_psp.pfnCallback = T::PropPageCallback;
  255. m_psp.lParam = (LPARAM)this;
  256. if(nTitle)
  257. {
  258. m_psp.pszTitle = MAKEINTRESOURCE(nTitle);
  259. m_psp.dwFlags |= PSP_USETITLE;
  260. }
  261. if (T::ID_HeaderTitle)
  262. {
  263. m_psp.dwFlags |= PSP_USEHEADERTITLE;
  264. m_psp.pszHeaderTitle = MAKEINTRESOURCE(T::ID_HeaderTitle);
  265. }
  266. if (T::ID_HeaderSubTitle)
  267. {
  268. m_psp.dwFlags |= PSP_USEHEADERSUBTITLE;
  269. m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(T::ID_HeaderSubTitle);
  270. }
  271. }
  272. static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
  273. {
  274. ATLASSERT(hWnd == NULL);
  275. if(uMsg == PSPCB_CREATE)
  276. {
  277. CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam;
  278. _Module.AddCreateWndData(&pPage->m_thunk.cd, pPage);
  279. }
  280. if (bAutoDelete && uMsg == PSPCB_RELEASE)
  281. {
  282. T* pPage = (T*)ppsp->lParam;
  283. delete pPage;
  284. }
  285. return 1;
  286. }
  287. HPROPSHEETPAGE Create()
  288. {
  289. return ::CreatePropertySheetPage(&m_psp);
  290. }
  291. BOOL EndDialog(int)
  292. {
  293. // do nothing here, calling ::EndDialog will close the whole sheet
  294. ATLASSERT(FALSE);
  295. return FALSE;
  296. }
  297. // Operations
  298. void CancelToClose()
  299. {
  300. ATLASSERT(::IsWindow(m_hWnd));
  301. ATLASSERT(GetParent() != NULL);
  302. ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L);
  303. }
  304. void SetModified(BOOL bChanged = TRUE)
  305. {
  306. ATLASSERT(::IsWindow(m_hWnd));
  307. ATLASSERT(GetParent() != NULL);
  308. if(bChanged)
  309. ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L);
  310. else
  311. ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);
  312. }
  313. LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
  314. {
  315. ATLASSERT(::IsWindow(m_hWnd));
  316. ATLASSERT(GetParent() != NULL);
  317. return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam);
  318. }
  319. typedef CMySnapInPropertyWizardImpl< T, bAutoDelete > thisClass;
  320. BEGIN_MSG_MAP(thisClass)
  321. MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
  322. END_MSG_MAP()
  323. // Message handler
  324. LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  325. {
  326. ATLASSERT(::IsWindow(m_hWnd));
  327. NMHDR* pNMHDR = (NMHDR*)lParam;
  328. // don't handle messages not from the page/sheet itself
  329. if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
  330. {
  331. bHandled = FALSE;
  332. return 1;
  333. }
  334. T* pT = (T*)this;
  335. LRESULT lResult = 0;
  336. // handle default
  337. switch(pNMHDR->code)
  338. {
  339. case PSN_SETACTIVE:
  340. lResult = pT->OnBaseSetActive() ? 0 : -1;
  341. break;
  342. case PSN_KILLACTIVE:
  343. lResult = !pT->OnKillActive();
  344. break;
  345. case PSN_APPLY:
  346. lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
  347. break;
  348. case PSN_RESET:
  349. pT->OnReset();
  350. break;
  351. case PSN_QUERYCANCEL:
  352. lResult = !pT->OnQueryCancel();
  353. break;
  354. case PSN_WIZNEXT:
  355. lResult = !pT->OnWizardNext();
  356. break;
  357. case PSN_WIZBACK:
  358. lResult = !pT->OnWizardBack();
  359. break;
  360. case PSN_WIZFINISH:
  361. lResult = !pT->OnWizardFinish();
  362. break;
  363. case PSN_HELP:
  364. lResult = pT->OnHelp();
  365. break;
  366. default:
  367. bHandled = FALSE; // not handled
  368. }
  369. return lResult;
  370. }
  371. // Overridables
  372. BOOL OnSetActive()
  373. {
  374. return TRUE;
  375. }
  376. BOOL OnKillActive()
  377. {
  378. return TRUE;
  379. }
  380. BOOL OnApply()
  381. {
  382. return TRUE;
  383. }
  384. void OnReset()
  385. {
  386. }
  387. BOOL OnQueryCancel()
  388. {
  389. return TRUE; // ok to cancel
  390. }
  391. BOOL OnWizardBack()
  392. {
  393. return TRUE;
  394. }
  395. BOOL OnWizardNext()
  396. {
  397. return TRUE;
  398. }
  399. BOOL OnWizardFinish()
  400. {
  401. if ( m_PagePosition == LAST_PAGE )
  402. {
  403. T* pT = (T*)this;
  404. if ( !pT->OnWizardNext() )
  405. return FALSE;
  406. }
  407. return TRUE;
  408. }
  409. BOOL OnHelp()
  410. {
  411. return TRUE;
  412. }
  413. void DisableControl(UINT id)
  414. {
  415. T* pT = dynamic_cast<T*>(this);
  416. if (!pT)
  417. return;
  418. HWND hWndCtl = pT->GetDlgItem(id);
  419. ASSERT(hWndCtl);
  420. if (hWndCtl)
  421. ::EnableWindow(hWndCtl, FALSE);
  422. }
  423. };
  424. #endif // __PPAGE_H__