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.

273 lines
6.1 KiB

  1. /*++
  2. Copyright (C) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. proppage.cpp
  5. Abstract:
  6. This module implements CPropSheetPage class, the base class of
  7. CDeviceGeneralPage, CClassGeneralPage and CDeviceDriverPage.
  8. Author:
  9. William Hsieh (williamh) created
  10. Revision History:
  11. --*/
  12. #include "devmgr.h"
  13. #include "proppage.h"
  14. //
  15. // CPropSheetPage implementation
  16. //
  17. CPropSheetPage::CPropSheetPage(
  18. HINSTANCE hInst,
  19. UINT idTemplate
  20. )
  21. {
  22. memset(&m_psp, 0, sizeof(m_psp));
  23. m_psp.dwSize = sizeof(m_psp);
  24. m_psp.dwFlags = PSP_USECALLBACK;
  25. m_psp.pszTemplate = MAKEINTRESOURCE(idTemplate);
  26. m_psp.lParam = 0;
  27. m_psp.pfnCallback = CPropSheetPage::PageCallback;
  28. m_psp.pfnDlgProc = PageDlgProc;
  29. m_psp.hInstance = hInst;
  30. m_Active = FALSE;
  31. //
  32. // By default, we want every derived page to update its contents
  33. // on each PSN_SETACTIVE so that it has up-to-date information
  34. // presented since any page in the same property sheet may
  35. // change the target object and there are not reliable ways
  36. // to synchronize changes among pages.
  37. //
  38. m_AlwaysUpdateOnActive = TRUE;
  39. // Right after WM_INITDIALOG, we will receive a
  40. // PSN_SETACTIVE and by setting m_UpdateControlsPending
  41. // to TRUE, the PSN_SETACTIVE handler will call UpdateControls
  42. // to refresh the page.
  43. // derived classes can turn this off if they wish to
  44. // update the dialog box only once in OnInitDialog.
  45. // Also, since m_AlwaysUpdateOnActive is TRUE by-default,
  46. // m_UpdateControlPending is FALSE by-default.
  47. m_UpdateControlsPending = FALSE;
  48. m_IDCicon = 0;
  49. }
  50. INT_PTR
  51. CPropSheetPage::PageDlgProc(
  52. HWND hDlg,
  53. UINT uMsg,
  54. WPARAM wParam,
  55. LPARAM lParam
  56. )
  57. {
  58. CPropSheetPage* pThis = (CPropSheetPage *) GetWindowLongPtr(hDlg, DWLP_USER);
  59. LPNMHDR pnmhdr;
  60. BOOL Result;
  61. switch (uMsg) {
  62. case WM_INITDIALOG: {
  63. PROPSHEETPAGE* ppsp = (PROPSHEETPAGE *)lParam;
  64. pThis = (CPropSheetPage *) ppsp->lParam;
  65. ASSERT(pThis);
  66. SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pThis);
  67. pThis->m_hDlg = hDlg;
  68. Result = pThis->OnInitDialog(ppsp);
  69. break;
  70. }
  71. case WM_COMMAND:
  72. if (pThis)
  73. Result = pThis->OnCommand(wParam, lParam);
  74. else
  75. Result = FALSE;
  76. break;
  77. case WM_NOTIFY: {
  78. pnmhdr = (LPNMHDR)lParam;
  79. switch (pnmhdr->code) {
  80. case PSN_SETACTIVE:
  81. ASSERT(pThis);
  82. Result = pThis->OnSetActive();
  83. break;
  84. case PSN_KILLACTIVE:
  85. ASSERT(pThis);
  86. Result = pThis->OnKillActive();
  87. break;
  88. case PSN_APPLY:
  89. ASSERT(pThis);
  90. Result = pThis->OnApply();
  91. break;
  92. case PSN_LASTCHANCEAPPLY:
  93. ASSERT(pThis);
  94. Result = pThis->OnLastChanceApply();
  95. break;
  96. case PSN_RESET:
  97. ASSERT(pThis);
  98. Result = pThis->OnReset();
  99. break;
  100. case PSN_WIZFINISH:
  101. ASSERT(pThis);
  102. Result = pThis->OnWizFinish();
  103. break;
  104. case PSN_WIZNEXT:
  105. ASSERT(pThis);
  106. Result = pThis->OnWizNext();
  107. break;
  108. case PSN_WIZBACK:
  109. ASSERT(pThis);
  110. Result = pThis->OnWizBack();
  111. break;
  112. default:
  113. ASSERT(pThis);
  114. pThis->OnNotify(pnmhdr);
  115. Result = FALSE;
  116. break;
  117. }
  118. break;
  119. }
  120. case WM_DESTROY:
  121. if (pThis)
  122. Result = pThis->OnDestroy();
  123. else
  124. Result = FALSE;
  125. break;
  126. case PSM_QUERYSIBLINGS:
  127. ASSERT(pThis);
  128. Result = pThis->OnQuerySiblings(wParam, lParam);
  129. break;
  130. case WM_HELP:
  131. ASSERT(pThis);
  132. Result = pThis->OnHelp((LPHELPINFO)lParam);
  133. break;
  134. case WM_CONTEXTMENU:
  135. ASSERT(pThis);
  136. Result = pThis->OnContextMenu((HWND)wParam, LOWORD(lParam), HIWORD(lParam));
  137. break;
  138. default:
  139. Result = FALSE;
  140. break;
  141. }
  142. return Result;
  143. }
  144. UINT
  145. CPropSheetPage::DestroyCallback()
  146. {
  147. delete this;
  148. return TRUE;
  149. }
  150. //
  151. // This function is the property page create/desrtroy callback.
  152. // It monitors the PSPSCB_RELEASE to delete this object.
  153. // This is the most reliable way to free objects associated with
  154. // a property page. A property page which is never activated
  155. // will not receive a WM_DESTROY message because its window is not
  156. // created.
  157. //
  158. UINT
  159. CPropSheetPage::PageCallback(
  160. HWND hDlg,
  161. UINT uMsg,
  162. LPPROPSHEETPAGE ppsp
  163. )
  164. {
  165. ASSERT(ppsp);
  166. CPropSheetPage* pThis = (CPropSheetPage*)ppsp->lParam;
  167. if (PSPCB_CREATE == uMsg && pThis)
  168. {
  169. pThis->CreateCallback();
  170. }
  171. else if (PSPCB_RELEASE == uMsg && pThis)
  172. {
  173. return pThis->DestroyCallback();
  174. }
  175. return TRUE;
  176. }
  177. BOOL
  178. CPropSheetPage::OnQuerySiblings(
  179. WPARAM wParam,
  180. LPARAM lParam
  181. )
  182. {
  183. ASSERT(m_hDlg);
  184. DMQUERYSIBLINGCODE Code = (DMQUERYSIBLINGCODE)wParam;
  185. //
  186. // Properties of the device attached to this page have
  187. // changed. Try to update the controls if we are currently
  188. // active. If we are active at this time, signal a flag
  189. // so that on PSN_SETACTIVE will do the update.
  190. //
  191. switch (Code) {
  192. case QSC_PROPERTY_CHANGED:
  193. if (m_Active)
  194. {
  195. UpdateControls(lParam);
  196. m_UpdateControlsPending = FALSE;
  197. }
  198. else
  199. {
  200. // wait for SetActive to update the controls
  201. m_UpdateControlsPending = TRUE;
  202. }
  203. break;
  204. }
  205. SetWindowLongPtr(m_hDlg, DWLP_MSGRESULT, 0L);
  206. return FALSE;
  207. }
  208. BOOL
  209. CPropSheetPage::OnDestroy()
  210. {
  211. HICON hIcon;
  212. if (m_IDCicon)
  213. {
  214. if (hIcon = (HICON)SendDlgItemMessage(m_hDlg, m_IDCicon, STM_GETICON, 0, 0))
  215. {
  216. DestroyIcon(hIcon);
  217. }
  218. m_IDCicon = 0;
  219. }
  220. return FALSE;
  221. }