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.

166 lines
5.1 KiB

  1. /******************************************************************************
  2. Source File: Property Page.CPP
  3. Implements the CPropertyPage class. See the associated header file for
  4. details.
  5. Copyright (c) 1996 by Microsoft Corporation
  6. A Pretty Penny Enterprises Production
  7. Change History:
  8. 11-01-96 a-robkj@microsoft.com- original version
  9. 12-04-96 a-robkj@microsoft.com retrieve handle to sheet, Create a derived
  10. class for shell extension pages
  11. ******************************************************************************/
  12. #include "ICMUI.H"
  13. // CPropertyPage member functions
  14. // Class constructor- basic initializations. Any remaining PROPSHEETPAGE
  15. // initializations are expected to be done by the derived class.
  16. CPropertyPage::CPropertyPage() {
  17. m_psp.dwSize = sizeof m_psp;
  18. m_psp.pfnDlgProc = DialogProc;
  19. m_psp.lParam = (LPARAM) this;
  20. m_psp.dwFlags = PSP_DEFAULT; // Can be overriden later
  21. m_hpsp = NULL;
  22. m_bChanged = FALSE;
  23. }
  24. // Handle retrieval- I'll admit an addiction to one-liners
  25. HPROPSHEETPAGE CPropertyPage::Handle() {
  26. return m_hpsp = (m_hpsp ? m_hpsp : CreatePropertySheetPage(&m_psp));
  27. }
  28. // Dialog Procedure
  29. INT_PTR CALLBACK CPropertyPage::DialogProc(HWND hwndPage, UINT uMsg, WPARAM wp,
  30. LPARAM lp) {
  31. CPropertyPage *pcppMe =
  32. (CPropertyPage *) GetWindowLongPtr(hwndPage, DWLP_USER);
  33. switch (uMsg) {
  34. case WM_INITDIALOG:
  35. // In this case, lp points to the PROPSHEETHEADER that created
  36. // us. We look into its lParam member for our this pointer,
  37. // and store this in the dialog's private data. This lets us
  38. // use the pointer to get at all of our overridable functions.
  39. pcppMe = (CPropertyPage *) ((LPPROPSHEETPAGE) lp) -> lParam;
  40. SetWindowLongPtr(hwndPage, DWLP_USER, (LONG_PTR) pcppMe);
  41. pcppMe -> m_hwnd = hwndPage;
  42. // Now, see if the derived class has any initialization needs
  43. return pcppMe -> OnInit();
  44. // Overridable processing for standard control notifications
  45. case WM_COMMAND:
  46. return pcppMe -> OnCommand(HIWORD(wp), LOWORD(wp), (HWND) lp);
  47. case WM_DESTROY:
  48. return pcppMe -> OnDestroy();
  49. case WM_HELP:
  50. return pcppMe -> OnHelp((LPHELPINFO) lp);
  51. case WM_CONTEXTMENU:
  52. return pcppMe -> OnContextMenu((HWND) wp);
  53. // Overridable processing for common control notifications
  54. case WM_NOTIFY: {
  55. // If the message is PSM_SETACTIVE, note the property sheet hwnd
  56. LPNMHDR pnmh = (LPNMHDR) lp;
  57. if (pnmh -> code == PSN_SETACTIVE)
  58. pcppMe -> m_hwndSheet = pnmh -> hwndFrom;
  59. return pcppMe -> OnNotify((int) wp, pnmh);
  60. }
  61. }
  62. return FALSE; // We didn't handle the message.
  63. }
  64. // CShellExtensionPage class member methods
  65. CShellExtensionPage *CShellExtensionPage::m_pcsepAnchor = NULL;
  66. // We enable reference counting, partially because on NT, the Window handle
  67. // sometimes appears invalid even while the dialog is up. However, we also
  68. // keep the chaining mechanism, as this is the only sane way we have of
  69. // freeing up the object instances we've created.
  70. CShellExtensionPage::CShellExtensionPage() {
  71. if (m_pcsepAnchor) {
  72. // If there is a cell other than anchor, update its list.
  73. if (m_pcsepAnchor -> m_pcsepNext)
  74. m_pcsepAnchor -> m_pcsepNext -> m_pcsepPrevious = this;
  75. // Insert this cell right after the anchor.
  76. m_pcsepPrevious = m_pcsepAnchor;
  77. m_pcsepNext = m_pcsepAnchor -> m_pcsepNext;
  78. m_pcsepAnchor -> m_pcsepNext = this;
  79. }
  80. else {
  81. m_pcsepAnchor = this;
  82. m_pcsepNext = m_pcsepPrevious = NULL;
  83. }
  84. m_psp.pcRefParent = (UINT *) &CGlobals::ReferenceCounter();
  85. m_psp.dwFlags |= PSP_USEREFPARENT;
  86. }
  87. CShellExtensionPage::~CShellExtensionPage() {
  88. if (this == m_pcsepAnchor) {
  89. m_pcsepAnchor = m_pcsepNext;
  90. if (m_pcsepAnchor) {
  91. // Anchor never has previous.
  92. m_pcsepAnchor -> m_pcsepPrevious = NULL;
  93. }
  94. }
  95. else {
  96. m_pcsepPrevious -> m_pcsepNext = m_pcsepNext;
  97. // If there is other cell following this, update it.
  98. if (m_pcsepNext)
  99. m_pcsepNext -> m_pcsepPrevious = m_pcsepPrevious;
  100. }
  101. }
  102. // This little ditty lets us decide when it's safe to unload the DLL- it also
  103. // guarantees all class destructors are called as sheets get closed by the
  104. // various potential callers.
  105. BOOL CShellExtensionPage::OKToClose() {
  106. while (m_pcsepAnchor) {
  107. if (IsWindow(m_pcsepAnchor -> m_hwnd))
  108. return FALSE; // This page is still alive!
  109. delete m_pcsepAnchor; // Page isn't alive, delete it...
  110. }
  111. return TRUE; // No more pages allocated
  112. }