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.
 
 
 
 
 
 

447 lines
12 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1998
//
// File: proppage.h
//
//--------------------------------------------------------------------------
#ifndef _PROPPAGE_H
#define _PROPPAGE_H
// proppage.h : header file
//
///////////////////////////////////////////////////////////////////////////////
// FORWARD DECLARATIONS
class CTreeNode;
class CContainerNode;
class CComponentDataObject;
class CPropertyPageHolderBase;
class CPropertyPageBase;
class CPropertyPageHolderTable;
class CWatermarkInfo;
typedef CList< CPropertyPageBase*, CPropertyPageBase* > CPropertyPageBaseList;
////////////////////////////////////////////////////////////////////
// CHiddenWndBase : Utility Hidden Window
class CHiddenWndBase : public CWindowImpl<CHiddenWndBase>
{
public:
DECLARE_WND_CLASS(L"DNSMgrHiddenWindow")
BOOL Create(HWND hWndParent = NULL);
BEGIN_MSG_MAP(CHiddenWndBase)
END_MSG_MAP()
};
/////////////////////////////////////////////////////////////////////////////
// CSheetWnd
class CSheetWnd : public CHiddenWndBase
{
public:
static const UINT s_SheetMessage;
static const UINT s_SelectPageMessage;
CSheetWnd(CPropertyPageHolderBase* pHolder) { m_pHolder = pHolder;}
BEGIN_MSG_MAP(CSheetWnd)
MESSAGE_HANDLER( WM_CLOSE, OnClose )
MESSAGE_HANDLER( CSheetWnd::s_SheetMessage, OnSheetMessage )
MESSAGE_HANDLER( CSheetWnd::s_SelectPageMessage, OnSelectPageMessage )
CHAIN_MSG_MAP(CHiddenWndBase)
END_MSG_MAP()
LRESULT OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSheetMessage(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSelectPageMessage(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
private:
CPropertyPageHolderBase* m_pHolder;
};
/////////////////////////////////////////////////////////////////////////////
// CCloseDialogInfo
class CCloseDialogInfo
{
public:
CCloseDialogInfo()
{ m_hWnd = NULL; m_dwFlags = 0x0; }
BOOL CloseDialog(BOOL bCheckForMsgBox);
static BOOL CCloseDialogInfo::CloseMessageBox(HWND hWndParent);
HWND m_hWnd;
DWORD m_dwFlags;
};
/////////////////////////////////////////////////////////////////////////////
// CCloseDialogInfoStack
template <UINT nSize> class CCloseDialogInfoStack
{
public:
CCloseDialogInfoStack()
{
m_nTop = 0; // first empty
m_bForcedClose = FALSE;
}
BOOL IsEmpty()
{
return m_nTop <= 0;
}
BOOL Push(HWND hWnd, DWORD dwFlags)
{
ASSERT(hWnd != NULL);
ASSERT(::IsWindow(hWnd));
if (m_nTop >= nSize)
return FALSE;
m_arr[m_nTop].m_hWnd = hWnd;
m_arr[m_nTop].m_dwFlags = dwFlags;
m_nTop++;
return TRUE;
}
BOOL Pop()
{
if (m_bForcedClose)
return TRUE; // going away
if (m_nTop <= 0)
return FALSE;
m_nTop--;
return TRUE;
}
void ForceClose(HWND hWndPage)
{
if (m_bForcedClose)
{
return; // avoid reentrancy
}
m_bForcedClose = TRUE;
if (m_nTop > 0)
{
// have a stack to unwind
BOOL bOutermost = TRUE;
while (m_nTop > 0)
{
VERIFY(m_arr[m_nTop-1].CloseDialog(bOutermost));
bOutermost = FALSE;
m_nTop--;
}
}
else
{
// empty stack, but might have a message box
HWND hWndSheet = ::GetParent(hWndPage);
ASSERT(hWndSheet != NULL);
if (CCloseDialogInfo::CloseMessageBox(hWndSheet))
VERIFY(::PostMessage(hWndSheet, WM_COMMAND, IDCANCEL, 0));
}
}
private:
UINT m_nTop;
CCloseDialogInfo m_arr[nSize];
BOOL m_bForcedClose;
};
/////////////////////////////////////////////////////////////////////////////
// CPropertyPageHolderBase
class CPropertyPageHolderBase
{
public:
// construction
CPropertyPageHolderBase(CContainerNode* pContNode, CTreeNode* pNode,
CComponentDataObject* pComponentData);
virtual ~CPropertyPageHolderBase();
// initialization
// common
void Attach(CPropertyPageHolderBase* pContHolder);
BOOL EnableSheetControl(UINT nCtrlID, BOOL bEnable);
// property sheet only
static HRESULT CreateModelessSheet(CTreeNode* pNode, CComponentDataObject* pComponentData);
HRESULT CreateModelessSheet(CTreeNode* pCookieNode);
HRESULT CreateModelessSheet(LPPROPERTYSHEETCALLBACK pSheetCallback, LONG_PTR hConsoleHandle);
void SetStartPageCode(int nStartPageCode)
{ m_nStartPageCode = nStartPageCode;}
// wizard only
HRESULT DoModalWizard();
INT_PTR DoModalDialog(LPCTSTR pszCaption);
// helpers
// common
void SetSheetWindow(HWND hSheetWindow);
void SetSheetTitle(LPCWSTR lpszSheetTitle);
void SetSheetTitle(UINT nStringFmtID, CTreeNode* pNode);
void AddRef();
void Release();
DWORD GetRefCount() { return m_nCreatedCount;}
CComponentDataObject* GetComponentData() { ASSERT(m_pComponentData != NULL); return m_pComponentData;}
HWND GetMainWindow() { return m_hMainWnd;}
// get/set for the node we are working on
CTreeNode* GetTreeNode() { return m_pNode;}
void SetTreeNode(CTreeNode* pNode) { m_pNode = pNode; }
// get/set for the container we refer to
CContainerNode* GetContainerNode()
{
return m_pContNode;
}
void SetContainerNode(CContainerNode* pContNode) { ASSERT(pContNode != NULL); m_pContNode = pContNode; }
BOOL IsWizardMode();
BOOL IsModalSheet();
void ForceDestroy(); // forcefull shut down running sheet
void AddPageToList(CPropertyPageBase* pPage);
BOOL RemovePageFromList(CPropertyPageBase* pPage, BOOL bDeleteObject);
// property sheet only
BOOL PushDialogHWnd(HWND hWndModalDlg);
BOOL PopDialogHWnd();
void CloseModalDialogs(HWND hWndPage);
DWORD NotifyConsole(CPropertyPageBase* pPage); // notify console of property changes
void AcknowledgeNotify(); // acknowledge from the console
virtual BOOL OnPropertyChange(BOOL bScopePane, long* pChangeMask); // execute from main thread
// wizard only
BOOL SetWizardButtons(DWORD dwFlags);
BOOL SetWizardButtonsFirst(BOOL bValid)
{
return SetWizardButtons(bValid ? PSWIZB_NEXT : 0);
}
BOOL SetWizardButtonsMiddle(BOOL bValid)
{
return SetWizardButtons(bValid ? (PSWIZB_BACK|PSWIZB_NEXT) : PSWIZB_BACK);
}
BOOL SetWizardButtonsLast(BOOL bValid)
{
return SetWizardButtons(bValid ? (PSWIZB_BACK|PSWIZB_FINISH) : (PSWIZB_BACK|PSWIZB_DISABLEDFINISH));
}
HRESULT AddPageToSheet(CPropertyPageBase* pPage);
HRESULT AddPageToSheetRaw(HPROPSHEETPAGE hPage);
HRESULT RemovePageFromSheet(CPropertyPageBase* pPage);
HRESULT AddAllPagesToSheet();
protected:
// common
virtual HRESULT OnAddPage(int, CPropertyPageBase*) { return S_OK; }
// property sheet only
virtual void OnSheetMessage(WPARAM, LPARAM) {}
virtual int OnSelectPageMessage(long) { return -1;}
// wizard only
void SetWatermarkInfo(CWatermarkInfo* pWatermarkInfo);
private:
void DeleteAllPages();
void FinalDestruct();
// attributes
private:
// common
CString m_szSheetTitle; // title for the sheet/wizard window
CPropertyPageBaseList m_pageList; // list of property page objects
CPropertyPageHolderBase* m_pContHolder; // prop page holder that migh contain this
CComponentDataObject* m_pComponentData; // cached pointer to CComponentDataImplementation
HWND m_hMainWnd; // cached MMC frame window, if present
protected:
BOOL m_bWizardMode; // Wizard Mode (i.e. not modeless property sheet)
BOOL m_bAutoDelete; // delete itself when refcount goes to zero
BOOL m_bAutoDeletePages; // explicitely delete the property page C++ objects
enum { useDefault, forceOn, forceOff } m_forceContextHelpButton; // setting for the [?] button
private:
DWORD m_nCreatedCount; // count of how many pages got actually created
CTreeNode* m_pNode; // node the pages (or the wizard) refer to
CContainerNode* m_pContNode; // container node the pages (or the wizard) refer to
HWND m_hSheetWindow; // window handle to the sheet (thread safe)
// property sheet only
LONG_PTR m_hConsoleHandle; // handle for notifications to console
HANDLE m_hEventHandle; // syncronization handle for property notifications
CSheetWnd* m_pSheetWnd; // hidden window CWnd object for messages
int m_nStartPageCode; // starting page code (not necessarily the page #)
CCloseDialogInfoStack<5> m_dlgInfoStack; // modal dialogs stack (to close them down)
// wizard only
IPropertySheetCallback* m_pSheetCallback; // cached pointer to add/remove pages
CPropertySheet* m_pDummySheet; // MFC surrogate property sheet for modal operations
CWatermarkInfo* m_pWatermarkInfo; // watermark info for Wiz 97 sheets
private:
// property sheet only
// variables to use across thread boundaries
DWORD m_dwLastErr; // generic error code
CPropertyPageBase* m_pPropChangePage; // page for which notification is valid
public:
void SetError(DWORD dwErr) { m_dwLastErr = dwErr;}
CPropertyPageBase* GetPropChangePage()
{ ASSERT(m_pPropChangePage != NULL); return m_pPropChangePage; }
friend class CSheetWnd;
};
/////////////////////////////////////////////////////////////////////////////
// CPropertyPageBase
class CPropertyPageBase : public CPropertyPage
{
// Construction
private:
CPropertyPageBase(){} // cannot use this constructor
public:
CPropertyPageBase(UINT nIDTemplate,
UINT nIDCaption = 0);
virtual ~CPropertyPageBase();
// Overrides
public:
virtual BOOL OnInitDialog()
{
CWinApp* pApp = AfxGetApp();
ASSERT(pApp);
return CPropertyPage::OnInitDialog();
}
virtual void OnCancel();
virtual BOOL OnApply();
protected:
// Generated message map functions
//{{AFX_MSG(CGeneralPage)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnDestroy();
//}}AFX_MSG
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnWhatsThis();
afx_msg BOOL OnHelp(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
// attributes
public:
// common
PROPSHEETPAGE m_psp97;
HPROPSHEETPAGE m_hPage;
void SetHolder(CPropertyPageHolderBase* pPageHolder)
{ ASSERT((pPageHolder != NULL) && (m_pPageHolder == NULL)); m_pPageHolder = pPageHolder;}
CPropertyPageHolderBase* GetHolder() { return m_pPageHolder;};
// property seet only
virtual BOOL OnPropertyChange(BOOL, long*) // execute from main thread
{ return FALSE; /* do not repaint UI */ }
// wizard only
UINT m_nPrevPageID; // to be used by OnWizardBack()
void InitWiz97(BOOL bHideHeader, UINT nIDHeaderTitle, UINT nIDHeaderSubTitle);
private:
CString m_szHeaderTitle;
CString m_szHeaderSubTitle;
protected:
virtual void SetUIData(){}
virtual void GetUIData(){}
virtual LONG GetUIDataEx() { return 0;}
virtual void SetDirty(BOOL bDirty);
BOOL IsDirty() { return m_bIsDirty; }
private:
CPropertyPageHolderBase* m_pPageHolder; // backpointer to holder
BOOL m_bIsDirty; // dirty flag
HWND m_hWndWhatsThis; // hwnd of right click "What's this" help
};
/////////////////////////////////////////////////////////////////////////////
// CPropertyPageHolderTable
class CPropertyPageHolderTable
{
public:
CPropertyPageHolderTable(CComponentDataObject* pComponentData);
~CPropertyPageHolderTable();
void Add(CPropertyPageHolderBase* pPPHolder);
void AddWindow(CPropertyPageHolderBase* pPPHolder, HWND hWnd);
void Remove(CPropertyPageHolderBase* pPPHolder);
void DeleteSheetsOfNode(CTreeNode* pNode);
void WaitForAllToShutDown();
// sheet notification mechanism
void BroadcastMessageToSheets(CTreeNode* pNode, WPARAM wParam, LPARAM lParam);
void BroadcastSelectPage(CTreeNode* pNode, long nPageCode);
int BroadcastCloseMessageToSheets(CTreeNode* pNode);
private:
CComponentDataObject* m_pComponentData; // back pointer
void WaitForSheetShutdown(int nCount, HWND* hWndArr = NULL);
struct PPAGE_HOLDER_TABLE_ENTRY
{
CPropertyPageHolderBase* pPPHolder;
CTreeNode* pNode;
HWND hWnd;
};
PPAGE_HOLDER_TABLE_ENTRY* m_pEntries;
int m_nSize;
};
////////////////////////////////////////////////////////////
// CHelpDialog
class CHelpDialog : public CDialog
{
// Construction
private:
CHelpDialog(){}
public:
CHelpDialog(UINT nIDTemplate, CComponentDataObject* pComponentData);
CHelpDialog(UINT nIDTemplate, CWnd* pParentWnd, CComponentDataObject* pComponentData);
virtual ~CHelpDialog() {};
virtual void OnOK() { CDialog::OnOK(); }
protected:
afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
afx_msg void OnWhatsThis();
afx_msg BOOL OnHelp(WPARAM wParam, LPARAM lParam);
DECLARE_MESSAGE_MAP()
private:
HWND m_hWndWhatsThis; // hwnd of right click "What's this" help
CComponentDataObject* m_pComponentData;
};
#endif // _PROPPAGE_H