Windows2000/private/ntos/w32/ntgdi/icm/icmui/proppage.cpp
2020-09-30 17:12:32 +02:00

167 lines
4.8 KiB
C++

/***
Source File: Property Page.CPP
Implements the CPropertyPage class. See the associated header file for
details.
Copyright (c) 1996 by Microsoft Corporation
A Pretty Penny Enterprises Production
Change History:
11-01-96 a-robkj@microsoft.com- original version
12-04-96 a-robkj@microsoft.com retrieve handle to sheet, Create a derived
class for shell extension pages
***/
#include "ICMUI.H"
// CPropertyPage member functions
// Class constructor- basic initializations. Any remaining PROPSHEETPAGE
// initializations are expected to be done by the derived class.
CPropertyPage::CPropertyPage() {
m_psp.dwSize = sizeof m_psp;
m_psp.pfnDlgProc = (DLGPROC) DialogProc;
m_psp.lParam = (LPARAM) this;
m_psp.dwFlags = PSP_DEFAULT; // Can be overriden later
m_hpsp = NULL;
m_bChanged = FALSE;
}
// Handle retrieval- I'll admit an addiction to one-liners
HPROPSHEETPAGE CPropertyPage::Handle() {
return m_hpsp = (m_hpsp ? m_hpsp : CreatePropertySheetPage(&m_psp));
}
// Dialog Procedure
BOOL CALLBACK CPropertyPage::DialogProc(HWND hwndPage, UINT uMsg, WPARAM wp,
LPARAM lp) {
CPropertyPage *pcppMe =
(CPropertyPage *) GetWindowLongPtr(hwndPage, DWLP_USER);
switch (uMsg) {
case WM_INITDIALOG:
// In this case, lp points to the PROPSHEETHEADER that created
// us. We look into its lParam member for our this pointer,
// and store this in the dialog's private data. This lets us
// use the pointer to get at all of our overridable functions.
pcppMe = (CPropertyPage *) ((LPPROPSHEETPAGE) lp) -> lParam;
SetWindowLongPtr(hwndPage, DWLP_USER, (LONG_PTR) pcppMe);
pcppMe -> m_hwnd = hwndPage;
// Now, see if the derived class has any initialization needs
return pcppMe -> OnInit();
// Overridable processing for standard control notifications
case WM_COMMAND:
return pcppMe -> OnCommand(HIWORD(wp), LOWORD(wp), (HWND) lp);
case WM_DESTROY:
return pcppMe -> OnDestroy();
case WM_HELP:
return pcppMe -> OnHelp((LPHELPINFO) lp);
case WM_CONTEXTMENU:
return pcppMe -> OnContextMenu((HWND) wp);
// Overridable processing for common control notifications
case WM_NOTIFY: {
// If the message is PSM_SETACTIVE, note the property sheet hwnd
LPNMHDR pnmh = (LPNMHDR) lp;
if (pnmh -> code == PSN_SETACTIVE)
pcppMe -> m_hwndSheet = pnmh -> hwndFrom;
return pcppMe -> OnNotify((int) wp, pnmh);
}
}
return FALSE; // We didn't handle the message.
}
// CShellExtensionPage class member methods
CShellExtensionPage *CShellExtensionPage::m_pcsepAnchor = NULL;
// We enable reference counting, partially because on NT, the Window handle
// sometimes appears invalid even while the dialog is up. However, we also
// keep the chaining mechanism, as this is the only sane way we have of
// freeing up the object instances we've created.
CShellExtensionPage::CShellExtensionPage() {
if (m_pcsepAnchor) {
// If there is a cell other than anchor, update its list.
if (m_pcsepAnchor -> m_pcsepNext)
m_pcsepAnchor -> m_pcsepNext -> m_pcsepPrevious = this;
// Insert this cell right after the anchor.
m_pcsepPrevious = m_pcsepAnchor;
m_pcsepNext = m_pcsepAnchor -> m_pcsepNext;
m_pcsepAnchor -> m_pcsepNext = this;
}
else {
m_pcsepAnchor = this;
m_pcsepNext = m_pcsepPrevious = NULL;
}
m_psp.pcRefParent = (UINT *) &CGlobals::ReferenceCounter();
m_psp.dwFlags |= PSP_USEREFPARENT;
}
CShellExtensionPage::~CShellExtensionPage() {
if (this == m_pcsepAnchor) {
m_pcsepAnchor = m_pcsepNext;
if (m_pcsepAnchor) {
// Anchor never has previous.
m_pcsepAnchor -> m_pcsepPrevious = NULL;
}
}
else {
m_pcsepPrevious -> m_pcsepNext = m_pcsepNext;
// If there is other cell following this, update it.
if (m_pcsepNext)
m_pcsepNext -> m_pcsepPrevious = m_pcsepPrevious;
}
}
// This little ditty lets us decide when it's safe to unload the DLL- it also
// guarantees all class destructors are called as sheets get closed by the
// various potential callers.
BOOL CShellExtensionPage::OKToClose() {
while (m_pcsepAnchor) {
if (IsWindow(m_pcsepAnchor -> m_hwnd))
return FALSE; // This page is still alive!
delete m_pcsepAnchor; // Page isn't alive, delete it...
}
return TRUE; // No more pages allocated
}