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

146 lines
4.8 KiB
C++

/******************************************************************************
Header File: Property Page.H
This defines the C++ class used to encapsulate property pages. This class
has a static method for the dialog procedure, which automatically caches the
"this" pointer for the class in the DWL_USER field of the windows internal
structure for the dialog used for the property page. This hand-off is
accomplished by setting the lParam field of the PROPSHEETPAGE structure to
the "this" pointer. It also saves the dialog handle in a protected member
for easy access from derived classes.
To create a C++ class for any specific property sheet, derive the class
from this class, providing the dialog ID and instance handle needed to get
the resource in the m_psp member.
The dialog procedure then provides virtual functions for Windows messages
of interest. I've added these as needed. If I were going to a truly
universal class of this sort, I'd just as well go to MFC, and save the
debugging time, so this approach seems reasonable to me.
Copyright (c) 1996 by Microsoft Corporation
A Pretty Penny Enterprises Production
Change History:
11-01-96 a-robkj@microsoft.com- original version
******************************************************************************/
#if !defined(PROPERTY_PAGE)
#define PROPERTY_PAGE
// CPropertyPage class- abstracts a property page for us
class CPropertyPage {
// Basic dialog procedure for all derived classes
static BOOL CALLBACK DialogProc(HWND hwndPage, UINT uMsg, WPARAM wp,
LPARAM lp);
// These elements should be protected (only available to derived classes)
protected:
PROPSHEETPAGE m_psp;
HWND m_hwnd, m_hwndSheet;
HPROPSHEETPAGE m_hpsp;
BOOL m_bChanged;
public:
CPropertyPage(); // Default Constructor
virtual ~CPropertyPage() {}
HPROPSHEETPAGE Handle(); // Calls CreatePropertySheetPage, if needed
VOID EnableApplyButton() {
SendMessage(m_hwndSheet, PSM_CHANGED, (WPARAM) m_hwnd, 0);
}
VOID DisableApplyButton() {
SendMessage(m_hwndSheet, PSM_UNCHANGED, (WPARAM) m_hwnd, 0);
}
BOOL SettingChanged() {
return m_bChanged;
}
VOID SettingChanged(BOOL b) {
m_bChanged = b;
}
// virtual functions- these get redefined on an as needed basis for
// any specialized handling desired by any derived classes.
// The default handling allows one to initially display the sheet with
// no coding beyond the constructor for the derived class
virtual BOOL OnCommand(WORD wNotifyCode, WORD wid, HWND hwndCtl) {
return FALSE;
}
virtual BOOL OnNotify(int idCtrl, LPNMHDR pnmh) {
return FALSE;
}
virtual BOOL OnInit() { return TRUE; }
virtual BOOL OnDestroy() { return FALSE; }
virtual BOOL OnHelp(LPHELPINFO pHelp) { return TRUE; }
virtual BOOL OnContextMenu(HWND hwnd) { return TRUE; }
};
/******************************************************************************
Shell Extension property page class
Noteworthy details:
These pages are displayed by the shell. The thread of execution is such that
we create the page, then return to the shell. The shell will then attempt to
unload the extension. It will query CanDllUnloadNow to do this. Since
freeing the library frees the page template and dialog procedure, we can't
allow this to happen while any instances of this class exist.
However, the shell doesn't know this is a class, so it won't destroy it.
What I've done is build a circular chain of all of the instances of this
class, anchored in a private static class member. A public static method
(OKToClose) then walks the chain. If an instance's window handle is no
longer valid, then the shell has finished with it, and we delete it. The
criterion for closing then becomes not finding a valid handle (so we don't
delay unloading by any lazy evaluation, such as requiring an empty chain
on entry).
All Property pages displayed by a property sheet extension should be derived
from this class.
While a mechanism is provided by property sheets for a reference count
maintenance mechanism, this mechanism will not call any class destructor-
this could lead to memory leaks, which is why I've chosen this method.
******************************************************************************/
class CShellExtensionPage: public CPropertyPage {
static CShellExtensionPage *m_pcsepAnchor; // Anchor the chain of these
CShellExtensionPage *m_pcsepPrevious, *m_pcsepNext;
public:
CShellExtensionPage();
~CShellExtensionPage();
static BOOL OKToClose();
};
#endif // Keep us from getting multiply defined