wizard.cc revision 706f2543
1/* 2 * Copyright (c) 2005 Alexander Gottwald 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 * DEALINGS IN THE SOFTWARE. 21 * 22 * Except as contained in this notice, the name(s) of the above copyright 23 * holders shall not be used in advertising or otherwise to promote the sale, 24 * use or other dealings in this Software without prior written authorization. 25 */ 26#include "wizard.h" 27#include "util.h" 28 29CWizard::CWizard() : pages() 30{ 31}; 32 33void CWizard::AddPage(const PROPSHEETPAGE &page) 34{ 35 pages.push_back(page); 36} 37 38void CWizard::AddPage(const char *page, HINSTANCE instance) 39{ 40 PROPSHEETPAGE psp; 41 if (instance == NULL) 42 instance = GetModuleHandle(NULL); 43 44 memset(&psp, 0, sizeof(psp)); 45 psp.dwSize = sizeof(PROPSHEETPAGE); 46 psp.dwFlags = PSP_DEFAULT; 47 psp.hInstance = instance; 48 psp.pszTemplate = page; 49 psp.pfnDlgProc = WizardDialogProc; 50 psp.lParam = (LPARAM)this; 51 52 AddPage(psp); 53} 54 55void CWizard::AddPage(DWORD id, DWORD title, DWORD subtitle, HINSTANCE instance) 56{ 57 PROPSHEETPAGE psp; 58 if (instance == NULL) 59 instance = GetModuleHandle(NULL); 60 61 memset(&psp, 0, sizeof(psp)); 62 psp.dwSize = sizeof(PROPSHEETPAGE); 63 psp.dwFlags = PSP_DEFAULT; 64#if _WIN32_IE >= 0x0500 65 if (title != 0) 66 { 67 psp.dwFlags |= PSP_USEHEADERTITLE; 68 psp.pszHeaderTitle = MAKEINTRESOURCE(title); 69 } 70 if (subtitle != 0) 71 { 72 psp.dwFlags |= PSP_USEHEADERSUBTITLE; 73 psp.pszHeaderSubTitle = MAKEINTRESOURCE(subtitle); 74 } 75#endif 76 77 psp.hInstance = instance; 78 psp.pszTemplate = MAKEINTRESOURCE(id); 79 psp.pfnDlgProc = WizardDialogProc; 80 psp.lParam = (LPARAM)this; 81 82 AddPage(psp); 83} 84 85HWND CWizard::CreateWindowHandle() 86{ 87 PROPSHEETHEADER psh; 88 HWND ret; 89 90 PrepareSheetHeader(psh, FALSE); 91 ret = (HWND)PropertySheet(&psh); 92 free(psh.phpage); 93 if (ret == NULL) 94 throw win32_error("PropertySheet failed"); 95 return ret; 96} 97 98int CWizard::ShowModal() 99{ 100 PROPSHEETHEADER psh; 101 int ret; 102 103 PrepareSheetHeader(psh, TRUE); 104 ret = PropertySheet(&psh); 105 free(psh.phpage); 106 return ret; 107} 108 109void CWizard::PrepareSheetHeader(PROPSHEETHEADER &psh, BOOL modal) 110{ 111 HPROPSHEETPAGE *phpage = (HPROPSHEETPAGE*)malloc(pages.size() * sizeof(HPROPSHEETPAGE)); 112 DWORD modeflag; 113 114 if (modal) 115 modeflag = 0; 116 else 117 modeflag = PSH_MODELESS; 118 119 for (unsigned i = 0; i < pages.size(); i++) 120 { 121 phpage[i] = CreatePropertySheetPage(&pages[i]); 122 if (phpage[i] == NULL) 123 { 124 DWORD err = GetLastError(); 125 free(phpage); 126 throw win32_error("CreatePropertySheetPage failed", err); 127 } 128 } 129 130 memset(&psh, 0, sizeof(psh)); 131 psh.dwSize = sizeof(PROPSHEETHEADER); 132#if _WIN32_IE >= 0x0500 133 psh.dwFlags = PSH_WIZARD97 | modeflag; 134#else 135 psh.dwFlags = PSH_WIZARD | modeflag; 136#endif 137 psh.hwndParent = NULL; 138 psh.hInstance = GetModuleHandle(NULL); 139 psh.pszIcon = NULL; 140 psh.pszCaption = (LPSTR) "Cell Properties"; 141 psh.nPages = pages.size(); 142 psh.nStartPage = 0; 143 psh.phpage = phpage; 144 psh.pfnCallback = NULL; 145} 146 147DWORD CWizard::PageID(unsigned index) 148{ 149 if (index < pages.size() && IS_INTRESOURCE(pages[index].pszTemplate)) 150 return (DWORD)pages[index].pszTemplate; 151 return (DWORD)-1; 152} 153 154unsigned CWizard::PageIndex(PROPSHEETPAGE *psp) 155{ 156 for (unsigned i = 0; i < pages.size(); i++) 157 { 158 if (IS_INTRESOURCE(psp->pszTemplate) || IS_INTRESOURCE(pages[i].pszTemplate )) 159 { 160 if (psp->pszTemplate == pages[i].pszTemplate) 161 return i; 162 } 163 else if (psp->pszTemplate && pages[i].pszTemplate) 164 { 165 if (strcmp(psp->pszTemplate, pages[i].pszTemplate) == 0) 166 return i; 167 } 168 } 169 return (unsigned)-1; 170} 171 172INT_PTR CWizard::DlgDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 173{ 174 return CBaseDialog::DlgDispatch(hwndDlg, uMsg, wParam, lParam); 175} 176 177INT_PTR CWizard::PageDispatch(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, PROPSHEETPAGE *psp) 178{ 179 LPNMHDR pnmh = (LPNMHDR)lParam; 180 DWORD flags; 181 unsigned pageindex; 182 switch (uMsg) 183 { 184 case WM_NOTIFY: 185 switch (pnmh->code) 186 { 187 case PSN_SETACTIVE: 188#ifdef _DEBUG 189 printf("PSN_SETACTIVE %d\n", PageIndex(psp)); 190#endif 191 pageindex = PageIndex(psp); 192 if (pageindex != (unsigned)-1) 193 { 194 flags = 0; 195 if (pageindex > 0) 196 flags |= PSWIZB_BACK; 197 if ((unsigned)pageindex + 1 == pages.size()) 198 flags |= PSWIZB_FINISH; 199 if ((unsigned)pageindex + 1 < pages.size()) 200 flags |= PSWIZB_NEXT; 201 PropSheet_SetWizButtons(GetParent(hwndDlg), flags); 202 } 203 WizardActivate(hwndDlg, pageindex); 204 break; 205 case PSN_WIZNEXT: 206 if (WizardNext(hwndDlg, PageIndex(psp))) 207 return TRUE; 208 break; 209 case PSN_WIZBACK: 210 if (WizardBack(hwndDlg, PageIndex(psp))) 211 return TRUE; 212 break; 213 case PSN_WIZFINISH: 214 if (WizardFinish(hwndDlg, PageIndex(psp))) 215 return TRUE; 216 DestroyWindow(GetParent(hwndDlg)); 217 case PSN_RESET: 218 if (WizardReset(hwndDlg, PageIndex(psp))) 219 return TRUE; 220 DestroyWindow(GetParent(hwndDlg)); 221 break; 222 } 223 } 224 return DlgDispatch(hwndDlg, uMsg, wParam, lParam); 225} 226 227 228INT_PTR CALLBACK CWizard::WizardDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 229{ 230 MessageDebug::debug(hwndDlg, uMsg, wParam, lParam, __FUNCTION__); 231 PROPSHEETPAGE *psp = (PROPSHEETPAGE*)lParam; 232 switch (uMsg) 233 { 234 case WM_INITDIALOG: 235 SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)psp); 236 break; 237 } 238 psp = (PROPSHEETPAGE*)GetWindowLongPtr(hwndDlg, GWLP_USERDATA); 239 CWizard* wizard = psp?(CWizard*)psp->lParam:NULL; 240 if (wizard != NULL) 241 return wizard->PageDispatch(hwndDlg, uMsg, wParam, lParam, psp); 242 return FALSE; 243} 244 245