456 lines
11 KiB
C++
456 lines
11 KiB
C++
//----------------------------------------------------------------------------
|
||
//
|
||
// Microsoft Windows
|
||
// Copyright (C) Microsoft Corporation, 2001.
|
||
//
|
||
// File: Snppage.cpp
|
||
//
|
||
// Contents: WiF Policy Snapin
|
||
//
|
||
//
|
||
// History: TaroonM
|
||
// 10/30/01
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
#include "stdafx.h"
|
||
|
||
|
||
#ifdef _DEBUG
|
||
#define new DEBUG_NEW
|
||
#undef THIS_FILE
|
||
static char THIS_FILE[] = __FILE__;
|
||
#endif
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CSnapPage property page base class
|
||
|
||
IMPLEMENT_DYNCREATE(CSnapPage, CPropertyPage)
|
||
|
||
BEGIN_MESSAGE_MAP(CSnapPage, CPropertyPage)
|
||
//{{AFX_MSG_MAP(CSnapPage)
|
||
ON_WM_DESTROY()
|
||
//}}AFX_MSG_MAP
|
||
END_MESSAGE_MAP()
|
||
|
||
CSnapPage::CSnapPage (UINT nIDTemplate, BOOL bWiz97, UINT nNextIDD) : CPropertyPage(nIDTemplate)
|
||
{
|
||
m_pspiResultItem = NULL;
|
||
m_pDefaultCallback = NULL;
|
||
m_bDoRefresh = TRUE;
|
||
m_bModified = FALSE;
|
||
m_bInitializing = FALSE;
|
||
#ifdef _DEBUG
|
||
m_bDebugNewState = false;
|
||
#endif
|
||
|
||
// if they set this to begin with, but note that calling InitWiz97 turns this on anyway
|
||
m_bWiz97 = bWiz97;
|
||
|
||
m_nIDD = nIDTemplate;
|
||
m_nNextIDD = nNextIDD;
|
||
|
||
#ifdef WIZ97WIZARDS
|
||
// copy the base class m_psp to ours
|
||
m_psp.dwSize = sizeof (CPropertyPage::m_psp);
|
||
memcpy (&m_psp, &(CPropertyPage::m_psp), CPropertyPage::m_psp.dwSize);
|
||
m_psp.dwSize = sizeof (PROPSHEETPAGE);
|
||
|
||
m_pWiz97Sheet = NULL;
|
||
m_pHeaderTitle = NULL;
|
||
m_pHeaderSubTitle = NULL;
|
||
|
||
m_pstackWiz97Pages = NULL;
|
||
#endif
|
||
}
|
||
|
||
CSnapPage::~CSnapPage ()
|
||
{
|
||
// guess we are done with the m_pspiResultItem, decrement its reference count
|
||
if (m_pspiResultItem)
|
||
{
|
||
m_pspiResultItem->Release();
|
||
m_pspiResultItem = NULL;
|
||
}
|
||
|
||
// Page's parent or caller will delete these objs
|
||
m_pstackWiz97Pages = NULL;
|
||
|
||
#ifdef WIZ97WIZARDS
|
||
DELETE_OBJECT(m_pHeaderTitle);
|
||
DELETE_OBJECT(m_pHeaderSubTitle);
|
||
#endif
|
||
}
|
||
|
||
UINT CALLBACK CSnapPage::PropertyPageCallback (HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
|
||
{
|
||
// get our psuedo this pointer
|
||
CSnapPage* pThis = (CSnapPage*) ppsp->lParam;
|
||
// get the default callback pointer
|
||
UINT (CALLBACK* pDefaultCallback) (HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp) = pThis->m_pDefaultCallback;
|
||
|
||
switch (uMsg)
|
||
{
|
||
case PSPCB_RELEASE:
|
||
{
|
||
// Delete ourself
|
||
AFX_MANAGE_STATE(AfxGetStaticModuleState());
|
||
delete pThis;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// call the default cleanup function if there was one (because we are using
|
||
// mfc and it always puts in a callback for itself there should be one... or
|
||
// we block the page from coming up)
|
||
if (pDefaultCallback)
|
||
{
|
||
return pDefaultCallback (hwnd, uMsg, ppsp);
|
||
}
|
||
|
||
// There should be a default callback to handle creation, otherwise page will not
|
||
// be created because we return 0.
|
||
ASSERT( PSPCB_CREATE != uMsg );
|
||
|
||
// to create the page 1 allows it and 0 says 'no way'
|
||
return 0;
|
||
}
|
||
|
||
#ifdef WIZ97WIZARDS
|
||
BOOL CSnapPage::OnSetActive()
|
||
{
|
||
// NOTE: we only ever want to do this if it is a wizard, otherwise the
|
||
// cancel button gets the default focus!
|
||
if (m_bWiz97)
|
||
{
|
||
// now we can set our buttons correctly
|
||
GetParent()->SendMessage(PSM_SETWIZBUTTONS, 0, m_dwWizButtonFlags);
|
||
}
|
||
|
||
return CPropertyPage::OnSetActive();
|
||
}
|
||
|
||
LRESULT CSnapPage::OnWizardBack()
|
||
{
|
||
// use the snapitem to help us keep track of wizard state
|
||
if (m_pspiResultItem)
|
||
{
|
||
// pop to the last page
|
||
return m_pspiResultItem->PopWiz97Page ();
|
||
}
|
||
else if (NULL != m_pstackWiz97Pages)
|
||
{
|
||
// Or, use our own stack, if we have one
|
||
return PopWiz97Page();
|
||
}
|
||
|
||
return CPropertyPage::OnWizardBack();
|
||
}
|
||
|
||
LRESULT CSnapPage::OnWizardNext()
|
||
{
|
||
// use the snapitem to help us keep track of wizard state
|
||
if (m_pspiResultItem)
|
||
{
|
||
// push our id, in case they need to use the 'back' button
|
||
m_pspiResultItem->PushWiz97Page (m_nIDD);
|
||
}
|
||
else if (NULL != m_pstackWiz97Pages)
|
||
{
|
||
// Or, use our own stack, if we have one
|
||
PushWiz97Page( m_nIDD );
|
||
}
|
||
|
||
// If we have the ID of the next page, return it, otherwise return default
|
||
return ((m_nNextIDD != -1) ? m_nNextIDD : CPropertyPage::OnWizardNext());
|
||
}
|
||
|
||
int CSnapPage::PopWiz97Page ()
|
||
{
|
||
ASSERT( NULL != m_pstackWiz97Pages );
|
||
|
||
// There better be something on the stack if we're popping it
|
||
ASSERT( m_pstackWiz97Pages->size() );
|
||
|
||
int i;
|
||
i = m_pstackWiz97Pages->top();
|
||
m_pstackWiz97Pages->pop();
|
||
return i;
|
||
}
|
||
|
||
void CSnapPage::PushWiz97Page (int nIDD)
|
||
{
|
||
ASSERT( NULL != m_pstackWiz97Pages );
|
||
m_pstackWiz97Pages->push(nIDD);
|
||
}
|
||
|
||
BOOL CSnapPage::InitWiz97( CComObject<CSecPolItem> *pSecPolItem, DWORD dwFlags, DWORD dwWizButtonFlags, UINT nHeaderTitle, UINT nSubTitle )
|
||
{
|
||
CommonInitWiz97( pSecPolItem, dwFlags, dwWizButtonFlags, nHeaderTitle, nSubTitle );
|
||
// Use our own callback.
|
||
SetCallback( CSnapPage::PropertyPageCallback );
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
BOOL CSnapPage::InitWiz97( LPFNPSPCALLBACK pfnCallback, CComObject<CSecPolItem> *pSecPolItem, DWORD dwFlags, DWORD dwWizButtonFlags /*= 0*/, UINT nHeaderTitle /*= 0*/, UINT nSubTitle /*= 0*/, STACK_INT *pstackPages /*=NULL*/)
|
||
{
|
||
CommonInitWiz97( pSecPolItem, dwFlags, dwWizButtonFlags, nHeaderTitle, nSubTitle );
|
||
// Use the caller's callback which should call ours after it does whatever it does.
|
||
SetCallback( pfnCallback );
|
||
// Use the stack owned by our parent sheet
|
||
m_pstackWiz97Pages = pstackPages;
|
||
|
||
return S_OK;
|
||
}
|
||
|
||
void CSnapPage::CommonInitWiz97( CComObject<CSecPolItem> *pSecPolItem, DWORD dwFlags, DWORD dwWizButtonFlags, UINT nHeaderTitle, UINT nSubTitle )
|
||
{
|
||
m_psp.dwFlags |= dwFlags;
|
||
|
||
// they called us this way, so ... they must expect ...
|
||
m_bWiz97 = TRUE;
|
||
|
||
// get strings
|
||
CString str;
|
||
str.LoadString (nHeaderTitle);
|
||
m_pHeaderTitle = (TCHAR*) malloc ((str.GetLength()+1)*sizeof(TCHAR));
|
||
if (m_pHeaderTitle)
|
||
{
|
||
lstrcpy (m_pHeaderTitle, str.GetBuffer(20));
|
||
} else
|
||
{
|
||
m_pHeaderTitle = _T("\0");
|
||
}
|
||
str.ReleaseBuffer(-1);
|
||
|
||
str.LoadString (nSubTitle);
|
||
m_pHeaderSubTitle = (TCHAR*) malloc ((str.GetLength()+1)*sizeof(TCHAR));
|
||
if (m_pHeaderSubTitle)
|
||
{
|
||
lstrcpy (m_pHeaderSubTitle, str.GetBuffer(20));
|
||
} else
|
||
{
|
||
m_pHeaderSubTitle = _T("\0");
|
||
}
|
||
|
||
m_psp.pszHeaderTitle = m_pHeaderTitle;
|
||
m_psp.pszHeaderSubTitle = m_pHeaderSubTitle;
|
||
|
||
// save off the button flags
|
||
m_dwWizButtonFlags = dwWizButtonFlags;
|
||
|
||
// save the snapitem
|
||
SetResultObject(pSecPolItem);
|
||
}
|
||
|
||
void CSnapPage::SetCallback( LPFNPSPCALLBACK pfnCallback )
|
||
{
|
||
// attempt the wilder CSnapPage mmc stuff
|
||
|
||
// store the existing Callback information (if any)
|
||
if (m_psp.dwFlags |= PSP_USECALLBACK)
|
||
{
|
||
m_pDefaultCallback = m_psp.pfnCallback;
|
||
}
|
||
|
||
// hook up our callback function
|
||
m_psp.dwFlags |= PSP_USECALLBACK;
|
||
m_psp.lParam = reinterpret_cast<LONG_PTR>(this);
|
||
m_psp.pfnCallback = pfnCallback;
|
||
|
||
// IF WE SWITCH TO DLL VERSION OF MFC WE NEED THIS
|
||
// hook up mmc (this is an mmc hack to avoid an issue with AFX_MANAGE_STATE in MFC)
|
||
HRESULT hr = ::MMCPropPageCallback (&m_psp);
|
||
ASSERT (hr == S_OK);
|
||
}
|
||
|
||
#endif
|
||
|
||
void CSnapPage::SetPostRemoveFocus( int nListSel, UINT nAddId, UINT nRemoveId, CWnd *pwndPrevFocus )
|
||
{
|
||
ASSERT( 0 != nAddId );
|
||
ASSERT( 0 != nRemoveId );
|
||
|
||
// Fix up focus, if necessary
|
||
SET_POST_REMOVE_FOCUS<CDialog>( this, nListSel, nAddId, nRemoveId, pwndPrevFocus );
|
||
}
|
||
|
||
BOOL CSnapPage::OnWizardFinish()
|
||
{
|
||
return CPropertyPage::OnWizardFinish();
|
||
}
|
||
|
||
HRESULT CSnapPage::Initialize( CComObject<CSecPolItem> *pSecPolItem)
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
// turn on an hourglass
|
||
CWaitCursor waitCursor;
|
||
|
||
// store the snap object
|
||
ASSERT( NULL == m_pspiResultItem );
|
||
|
||
SetResultObject(pSecPolItem);
|
||
|
||
ASSERT( NULL != m_pspiResultItem );
|
||
|
||
// store the existing Callback information (if any)
|
||
if (m_psp.dwFlags |= PSP_USECALLBACK)
|
||
{
|
||
m_pDefaultCallback = m_psp.pfnCallback;
|
||
}
|
||
|
||
// hook up our callback function
|
||
m_psp.dwFlags |= PSP_USECALLBACK;
|
||
m_psp.lParam = reinterpret_cast<LONG_PTR>(this);
|
||
m_psp.pfnCallback = CSnapPage::PropertyPageCallback;
|
||
|
||
// IF WE SWITCH TO DLL VERSION OF MFC WE NEED THIS
|
||
// hook up mmc (this is an mmc hack to avoid an issue with AFX_MANAGE_STATE in MFC)
|
||
hr = ::MMCPropPageCallback (&m_psp);
|
||
ASSERT (hr == S_OK);
|
||
|
||
return hr;
|
||
};
|
||
|
||
void CSnapPage::SetModified( BOOL bChanged /*= TRUE*/ )
|
||
{
|
||
// Ignore modifications made during dialog initialization, its not
|
||
// the user doing anything.
|
||
if (!HandlingInitDialog())
|
||
{
|
||
m_bModified = bChanged;
|
||
|
||
if (bChanged && m_spManager.p)
|
||
m_spManager->SetModified(TRUE);
|
||
}
|
||
CPropertyPage::SetModified( bChanged );
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////
|
||
// CSnapPage message handlers
|
||
|
||
BOOL CSnapPage::OnInitDialog()
|
||
{
|
||
m_bInitializing = TRUE;
|
||
|
||
#ifdef _DEBUG
|
||
if (m_bDebugNewState)
|
||
{
|
||
// Page should be unmodified, unless its explicitly set new.
|
||
ASSERT( m_bModified );
|
||
}
|
||
else
|
||
{
|
||
ASSERT( !m_bModified );
|
||
}
|
||
#endif
|
||
|
||
// add context help to the style bits
|
||
if (GetParent())
|
||
{
|
||
//GetParent()->ModifyStyleEx (0, WS_EX_CONTEXTHELP, 0);
|
||
}
|
||
|
||
// call base class and dis-regard return value as per the docs
|
||
CPropertyPage::OnInitDialog();
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
BOOL CSnapPage::OnApply()
|
||
{
|
||
BOOL fRet = TRUE;
|
||
if (!m_bWiz97) //$review do we need this bool check here?
|
||
{
|
||
m_bModified = FALSE;
|
||
|
||
if (m_spManager.p && m_spManager->IsModified()) //to avoid call mutliple times
|
||
{
|
||
//the manager will force other pages in the sheet to apply
|
||
fRet = m_spManager->OnApply();
|
||
}
|
||
|
||
}
|
||
|
||
if (fRet)
|
||
{
|
||
return CPropertyPage::OnApply();
|
||
}
|
||
else
|
||
{
|
||
//Some page refuse to apply, we set this page back to dirty (will also
|
||
// in turn set the property sheet manager to dirty)
|
||
SetModified();
|
||
}
|
||
|
||
return fRet;
|
||
}
|
||
|
||
void CSnapPage::OnCancel()
|
||
{
|
||
|
||
if (m_spManager.p)
|
||
{
|
||
m_spManager->OnCancel();
|
||
}
|
||
|
||
// pass to base class
|
||
CPropertyPage::OnCancel();
|
||
}
|
||
|
||
void CSnapPage::OnDestroy()
|
||
{
|
||
CPropertyPage::OnDestroy();
|
||
}
|
||
|
||
|
||
BOOL CSnapPage::ActivateThisPage()
|
||
{
|
||
BOOL bRet = FALSE;
|
||
// Activate this page so it is visible. Return TRUE if successful.
|
||
// if the page is in a wizard, it wont have a property sheet manager
|
||
if (m_spManager.p)
|
||
{
|
||
CPropertySheet * pSheet = m_spManager->PropertySheet();
|
||
if (pSheet)
|
||
{
|
||
pSheet->SetActivePage(this);
|
||
bRet = TRUE;
|
||
}
|
||
}
|
||
|
||
return bRet;
|
||
}
|
||
|
||
BOOL CSnapPage::CancelApply()
|
||
{
|
||
// This function should be called from OnApply when changes made
|
||
// to the page are being rejected.
|
||
|
||
|
||
// Return FALSE to abort the OnApply
|
||
return FALSE;
|
||
}
|
||
|
||
|
||
IMPLEMENT_DYNCREATE(CSnapinPropPage, CSnapPage)
|
||
|
||
//Check whether the Cancel button of the property sheet is disabled by CancelToClose
|
||
BOOL CSnapPage::IsCancelEnabled()
|
||
{
|
||
BOOL fRet = TRUE;
|
||
|
||
CWnd * pWnd = GetParent()->GetDlgItem(IDCANCEL);
|
||
ASSERT(pWnd);
|
||
|
||
if (pWnd)
|
||
{
|
||
fRet = pWnd->IsWindowEnabled();
|
||
}
|
||
|
||
return fRet;
|
||
}
|
||
|