/*======================================================================================// | Process Control // | // |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. // | // |File Name: // | // |Description: // | // |Created: Paul Skoglund 07-1998 // | // |Rev History: // | Based on code from ATL snapin wizard update for VC++ 6.0 - atlsnap.h | In this module class CSnapInPropertyPageImpl renamed to | CMySnapInPropertyPageImpl to avoid name clash | Modified to provide better support for Wizard style property pages... | | 1999 03 22 Paul Skoglund | Created CMySnapInPropertyWizardImpl template to use like CSnapInPropertyPageImpl | but specific for Wizard style pages. The template forces declaration of | Header Title resource ID and a SubHeader Title resource ID as used in the | PSH_WIZARD97 style. | Change to use Title as resource ID rather than string. | |=======================================================================================*/ #ifndef __PPAGE_H__ #define __PPAGE_H__ #ifndef ATLASSERT #define ATLASSERT ASSERT #endif #include #include #pragma comment(lib, "mmc.lib") #pragma comment(lib, "comctl32.lib") template class ATL_NO_VTABLE CMySnapInPropertyPageImpl : public CDialogImplBase { public: PROPSHEETPAGE m_psp; operator PROPSHEETPAGE*() { return &m_psp; } // Construction CMySnapInPropertyPageImpl(int nTitle) { // initialize PROPSHEETPAGE struct memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); m_psp.dwSize = sizeof(PROPSHEETPAGE); m_psp.dwFlags = PSP_USECALLBACK; m_psp.hInstance = _Module.GetResourceInstance(); m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD); m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; m_psp.pfnCallback = T::PropPageCallback; m_psp.lParam = (LPARAM)this; if(nTitle != NULL) { m_psp.pszTitle = MAKEINTRESOURCE(nTitle); m_psp.dwFlags |= PSP_USETITLE; } } static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { ATLASSERT(hWnd == NULL); if(uMsg == PSPCB_CREATE) { CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam; _Module.AddCreateWndData(&pPage->m_thunk.cd, pPage); } if (bAutoDelete && uMsg == PSPCB_RELEASE) { T* pPage = (T*)ppsp->lParam; delete pPage; } return 1; } HPROPSHEETPAGE Create() { return ::CreatePropertySheetPage(&m_psp); } BOOL EndDialog(int) { // do nothing here, calling ::EndDialog will close the whole sheet ATLASSERT(FALSE); return FALSE; } // Operations void CancelToClose() { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L); } void SetModified(BOOL bChanged = TRUE) { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); if(bChanged) ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L); else ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L); } LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam); } typedef CMySnapInPropertyPageImpl< T, bAutoDelete > thisClass; BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_NOTIFY, OnNotify) END_MSG_MAP() // Message handler LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ATLASSERT(::IsWindow(m_hWnd)); NMHDR* pNMHDR = (NMHDR*)lParam; // don't handle messages not from the page/sheet itself if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd)) { bHandled = FALSE; return 1; } T* pT = (T*)this; LRESULT lResult = 0; // handle default switch(pNMHDR->code) { case PSN_SETACTIVE: lResult = pT->OnSetActive() ? 0 : -1; break; case PSN_KILLACTIVE: lResult = !pT->OnKillActive(); break; case PSN_APPLY: lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; break; case PSN_RESET: pT->OnReset(); break; case PSN_QUERYCANCEL: lResult = !pT->OnQueryCancel(); break; case PSN_WIZNEXT: lResult = !pT->OnWizardNext(); break; case PSN_WIZBACK: lResult = !pT->OnWizardBack(); break; case PSN_WIZFINISH: lResult = !pT->OnWizardFinish(); break; case PSN_HELP: lResult = pT->OnHelp(); break; default: bHandled = FALSE; // not handled } return lResult; } // Overridables BOOL OnSetActive() { return TRUE; } BOOL OnKillActive() { return TRUE; } BOOL OnApply() { return TRUE; } void OnReset() { } BOOL OnQueryCancel() { return TRUE; // ok to cancel } BOOL OnWizardBack() { return TRUE; } BOOL OnWizardNext() { return TRUE; } BOOL OnWizardFinish() { return TRUE; } BOOL OnHelp() { return TRUE; } void DisableControl(UINT id) { T* pT = dynamic_cast(this); if (!pT) return; HWND hWndCtl = pT->GetDlgItem(id); ASSERT(hWndCtl); if (hWndCtl) ::EnableWindow(hWndCtl, FALSE); } }; // // For Wizard Pages... // template class ATL_NO_VTABLE CMySnapInPropertyWizardImpl : public CDialogImplBase { protected: BOOL OnBaseSetActive() { if (m_PagePosition != NOT_A_WIZARD) { DWORD dwFlags = 0; if ( m_PagePosition == FIRST_PAGE ) dwFlags = PSWIZB_NEXT; else if ( m_PagePosition == MIDDLE_PAGE ) dwFlags = PSWIZB_BACK | PSWIZB_NEXT; else if ( m_PagePosition == LAST_PAGE ) dwFlags = PSWIZB_BACK | PSWIZB_FINISH; else if ( m_PagePosition == LASTANDONLY_PAGE ) dwFlags = PSWIZB_FINISH; ::PostMessage(GetParent(), PSM_SETWIZBUTTONS, 0, (LPARAM) dwFlags); } T* pT = (T*)this; return pT->OnSetActive(); } public: PROPSHEETPAGE m_psp; typedef enum _WIZ_POSITION { NOT_A_WIZARD, FIRST_PAGE, MIDDLE_PAGE, LAST_PAGE, LASTANDONLY_PAGE, } WIZ_POSITION; WIZ_POSITION m_PagePosition; operator PROPSHEETPAGE*() { return &m_psp; } // Construction CMySnapInPropertyWizardImpl(WIZ_POSITION pageposition, int nTitle) { // m_PagePosition = pageposition; // initialize PROPSHEETPAGE struct memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); m_psp.dwSize = sizeof(PROPSHEETPAGE); m_psp.dwFlags = PSP_USECALLBACK; m_psp.hInstance = _Module.GetResourceInstance(); m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD); m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; m_psp.pfnCallback = T::PropPageCallback; m_psp.lParam = (LPARAM)this; if(nTitle) { m_psp.pszTitle = MAKEINTRESOURCE(nTitle); m_psp.dwFlags |= PSP_USETITLE; } if (T::ID_HeaderTitle) { m_psp.dwFlags |= PSP_USEHEADERTITLE; m_psp.pszHeaderTitle = MAKEINTRESOURCE(T::ID_HeaderTitle); } if (T::ID_HeaderSubTitle) { m_psp.dwFlags |= PSP_USEHEADERSUBTITLE; m_psp.pszHeaderSubTitle = MAKEINTRESOURCE(T::ID_HeaderSubTitle); } } static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp) { ATLASSERT(hWnd == NULL); if(uMsg == PSPCB_CREATE) { CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam; _Module.AddCreateWndData(&pPage->m_thunk.cd, pPage); } if (bAutoDelete && uMsg == PSPCB_RELEASE) { T* pPage = (T*)ppsp->lParam; delete pPage; } return 1; } HPROPSHEETPAGE Create() { return ::CreatePropertySheetPage(&m_psp); } BOOL EndDialog(int) { // do nothing here, calling ::EndDialog will close the whole sheet ATLASSERT(FALSE); return FALSE; } // Operations void CancelToClose() { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); ::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L); } void SetModified(BOOL bChanged = TRUE) { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); if(bChanged) ::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L); else ::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L); } LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) { ATLASSERT(::IsWindow(m_hWnd)); ATLASSERT(GetParent() != NULL); return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam); } typedef CMySnapInPropertyWizardImpl< T, bAutoDelete > thisClass; BEGIN_MSG_MAP(thisClass) MESSAGE_HANDLER(WM_NOTIFY, OnNotify) END_MSG_MAP() // Message handler LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { ATLASSERT(::IsWindow(m_hWnd)); NMHDR* pNMHDR = (NMHDR*)lParam; // don't handle messages not from the page/sheet itself if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd)) { bHandled = FALSE; return 1; } T* pT = (T*)this; LRESULT lResult = 0; // handle default switch(pNMHDR->code) { case PSN_SETACTIVE: lResult = pT->OnBaseSetActive() ? 0 : -1; break; case PSN_KILLACTIVE: lResult = !pT->OnKillActive(); break; case PSN_APPLY: lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; break; case PSN_RESET: pT->OnReset(); break; case PSN_QUERYCANCEL: lResult = !pT->OnQueryCancel(); break; case PSN_WIZNEXT: lResult = !pT->OnWizardNext(); break; case PSN_WIZBACK: lResult = !pT->OnWizardBack(); break; case PSN_WIZFINISH: lResult = !pT->OnWizardFinish(); break; case PSN_HELP: lResult = pT->OnHelp(); break; default: bHandled = FALSE; // not handled } return lResult; } // Overridables BOOL OnSetActive() { return TRUE; } BOOL OnKillActive() { return TRUE; } BOOL OnApply() { return TRUE; } void OnReset() { } BOOL OnQueryCancel() { return TRUE; // ok to cancel } BOOL OnWizardBack() { return TRUE; } BOOL OnWizardNext() { return TRUE; } BOOL OnWizardFinish() { if ( m_PagePosition == LAST_PAGE ) { T* pT = (T*)this; if ( !pT->OnWizardNext() ) return FALSE; } return TRUE; } BOOL OnHelp() { return TRUE; } void DisableControl(UINT id) { T* pT = dynamic_cast(this); if (!pT) return; HWND hWndCtl = pT->GetDlgItem(id); ASSERT(hWndCtl); if (hWndCtl) ::EnableWindow(hWndCtl, FALSE); } }; #endif // __PPAGE_H__