//Copyright (c) 1997-2000 Microsoft Corporation #include "pch.hxx" #pragma hdrstop #include "pgbase.h" #include "resource.h" #include "DlgFonts.h" /*************************************************************************** * Use the following define if for some reason we have to go back to using * a message loop to let shell have time to update the UI * #define NEED_MSG_PUMP **************************************************************************/ // Initialization of static members CWizardPageOrder WizardPage::sm_WizPageOrder; WizardPage::WizardPage( LPPROPSHEETPAGE ppsp, int nIdTitle, int nIdSubTitle ) : m_hwnd(NULL), m_dwPageId(0) { _ASSERTE(NULL != ppsp); // If we have a subtitle, we must have a title _ASSERTE(nIdSubTitle?nIdTitle:TRUE); // // Many of the members are 0 or NULL. // ZeroMemory(ppsp, sizeof(PROPSHEETPAGE)); ppsp->dwSize = sizeof(PROPSHEETPAGE); ppsp->dwFlags = PSP_DEFAULT; ppsp->hInstance = g_hInstDll; // If we are using a title/subtitle, include the flags // Otherwise, hide the header if(nIdTitle) { ppsp->dwFlags |= PSP_USEHEADERTITLE | (nIdSubTitle?PSP_USEHEADERSUBTITLE:0); ppsp->pszHeaderTitle = MAKEINTRESOURCE(nIdTitle); ppsp->pszHeaderSubTitle = MAKEINTRESOURCE(nIdSubTitle); // ppsp->pszbmHeader = MAKEINTRESOURCE(IDB_ACCMARK); } else ppsp->dwFlags |= PSP_HIDEHEADER; // // Callback is a base class function. The derived page // classes need to implement OnPropSheetPageCreate() and // OnPropSheetPageRelease() if they want to handle this callback. // By WizardPage::OnPropSheetPageCreate() returns 1. // ppsp->pfnCallback = WizardPage::PropSheetPageCallback; ppsp->dwFlags |= (PSP_USECALLBACK /*| PSP_USEREFPARENT*/); // JMC: TODO: Do we want PSP_USEREFPARENT // // Store "this" in the page struct so we can call member functions // from the page's message proc. // _ASSERTE(NULL != this); ppsp->lParam = (LPARAM)this; // // All dialog messages first go through the base class' message proc. // Virtual functions are called for some messages. If not processed // using a message-specific virtual function, the message is passed // to the derived class instance through the virtual funcion HandleMsg. // ppsp->pfnDlgProc = WizardPage::DlgProc; } WizardPage::~WizardPage( VOID ) { } UINT WizardPage::PropSheetPageCallback( HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp ) { UINT uResult = 0; WizardPage *pThis = (WizardPage *)ppsp->lParam; _ASSERTE(NULL != pThis); switch(uMsg) { case PSPCB_CREATE: uResult = pThis->OnPropSheetPageCreate(hwnd, ppsp); break; case PSPCB_RELEASE: uResult = pThis->OnPropSheetPageRelease(hwnd, ppsp); // // IMPORTANT: // This is where we delete each property sheet page. // HERE and ONLY HERE. // // delete pThis; // We won't do this since we'll keep our own list // The reason it won't work is because if you never get to a page, you // will never get this message break; } return uResult; } // // This is a static method. // INT_PTR WizardPage::DlgProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { INT_PTR bResult = FALSE; PROPSHEETPAGE *ppsp = NULL; if (WM_INITDIALOG == uMsg) ppsp = (PROPSHEETPAGE *)lParam; else ppsp = (PROPSHEETPAGE *)GetWindowLongPtr(hwnd, GWLP_USERDATA); if (NULL != ppsp) { WizardPage *pThis = (WizardPage *)ppsp->lParam; _ASSERTE(NULL != pThis); switch(uMsg) { case WM_INITDIALOG: { // The following will set fonts for 'known' controls, DialogFonts_InitWizardPage(hwnd); // // Store address of PROPSHEETPAGE struct for this page // in window's user data. // SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam); pThis->m_hwnd = hwnd; bResult = pThis->OnInitDialog(hwnd, wParam, lParam); } break; case WM_NOTIFY: bResult = pThis->OnNotify(hwnd, wParam, lParam); break; case PSM_QUERYSIBLINGS: bResult = pThis->OnPSM_QuerySiblings(hwnd, wParam, lParam); break; case WM_COMMAND: bResult = pThis->OnCommand(hwnd, wParam, lParam); break; case WM_TIMER: bResult = pThis->OnTimer(hwnd, wParam, lParam); break; case WM_DRAWITEM: bResult = pThis->OnDrawItem(hwnd, wParam, lParam); break; default: // // Let derived class instance handle any other messages // as needed. // bResult = pThis->HandleMsg(hwnd, uMsg, wParam, lParam); break; } } return bResult; } LRESULT WizardPage::OnNotify( HWND hwnd, WPARAM wParam, LPARAM lParam ) { INT idCtl = (INT)wParam; LPNMHDR pnmh = (LPNMHDR)lParam; LRESULT lResult = 0; switch(pnmh->code) { case PSN_APPLY: lResult = OnPSN_Apply(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_HELP: lResult = OnPSN_Help(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_KILLACTIVE: lResult = OnPSN_KillActive(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_QUERYCANCEL: lResult = OnPSN_QueryCancel(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_RESET: lResult = OnPSN_Reset(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_SETACTIVE: lResult = OnPSN_SetActive(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_WIZBACK: lResult = OnPSN_WizBack(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_WIZNEXT: lResult = OnPSN_WizNext(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case PSN_WIZFINISH: lResult = OnPSN_WizFinish(hwnd, idCtl, (LPPSHNOTIFY)pnmh); break; case NM_CLICK: case NM_RETURN: OnMsgNotify(hwnd, idCtl, (LPNMHDR) pnmh); break; default: break; } return lResult; } LRESULT WizardPage::OnPSN_SetActive( HWND hwnd, INT idCtl, LPPSHNOTIFY pnmh ) { // JMC: TODO: Maybe put this in the OnNotify Code so the overrided class does // not have to call this // // By default, each wizard page has a BACK and NEXT button. // DWORD dwFlags = 0; if(sm_WizPageOrder.GetPrevPage(m_dwPageId)) dwFlags |= PSWIZB_BACK; if(sm_WizPageOrder.GetNextPage(m_dwPageId)) dwFlags |= PSWIZB_NEXT; else dwFlags |= PSWIZB_FINISH; PropSheet_SetWizButtons(GetParent(hwnd), dwFlags); // Tell the wizard that it's ok to go to this page SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0); return TRUE; } LRESULT WizardPage::OnPSM_QuerySiblings( HWND hwnd, WPARAM wParam, LPARAM lParam ) { return 0; } LRESULT WizardPage::OnPSN_QueryCancel( HWND hwnd, INT idCtl, LPPSHNOTIFY pnmh ) { //If nothing has changed just exit... if ( memcmp( &g_Options.m_schemePreview, &g_Options.m_schemeOriginal, sizeof(WIZSCHEME)) == 0) { SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0); return TRUE; } // if ( switch(StringTableMessageBox(hwnd, IDS_WIZSAVECHANGESMESSAGETEXT, IDS_WIZSAVECHANGESMESSAGETITLE, MB_YESNO)) { case IDYES: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0); break; case IDNO: { // Restore all settings to the original settings g_Options.ApplyOriginal(); #if NEED_MSG_PUMP if (SetTimer(hwnd, 1, 4000, NULL)) { // Wait for messages to be processed BOOL fKeepChecking = TRUE; while (fKeepChecking) { MSG msg; while (PeekMessage(&msg, hwnd, WM_TIMER, WM_TIMER, PM_REMOVE)) { if (msg.message == WM_TIMER) { KillTimer(hwnd, 1); fKeepChecking = FALSE; break; } TranslateMessage(&msg); DispatchMessage(&msg); } } } #endif SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 0); } break; case IDCANCEL: SetWindowLongPtr(hwnd, DWLP_MSGRESULT, 1); break; } return TRUE; }