source: trunk/src/comctl32/propsheet.c@ 180

Last change on this file since 180 was 180, checked in by cbratschi, 26 years ago

Several COMCTL32 changes

File size: 38.3 KB
Line 
1/* $Id: propsheet.c,v 1.4 1999-06-24 16:37:44 cbratschi Exp $ */
2/*
3 * Property Sheets
4 *
5 * Copyright 1998 Francis Beaudet
6 * Copyright 1999 Thuy Nguyen
7 * Copyright 1999 Achim Hasenmueller
8 * Copyright 1999 Christoph Bratschi
9 *
10 * TODO:
11 * - Modeless mode
12 * - Wizard mode
13 * - Unicode property sheets
14 */
15
16#include <string.h>
17#include "winbase.h"
18#include "commctrl.h"
19#include "prsht.h"
20#include "winnls.h"
21#include "comctl32.h"
22
23
24/******************************************************************************
25 * Data structures
26 */
27typedef struct
28{
29 WORD dlgVer;
30 WORD signature;
31 DWORD helpID;
32 DWORD exStyle;
33 DWORD style;
34} MyDLGTEMPLATEEX;
35
36typedef struct tagPropPageInfo
37{
38 int index; /* corresponds to the index in ppshheader->ppsp */
39 HPROPSHEETPAGE hpage; /* to keep track of pages not passed to PropertySheet */
40 HWND hwndPage;
41 BOOL isDirty;
42 LPCWSTR pszText;
43 BOOL hasHelp;
44 BOOL useCallback;
45} PropPageInfo;
46
47typedef struct tagPropSheetInfo
48{
49 LPSTR strPropertiesFor;
50 int nPages;
51 int active_page;
52 LPCPROPSHEETHEADERA ppshheader;
53 BOOL isModeless;
54 BOOL hasHelp;
55 BOOL hasApply;
56 BOOL useCallback;
57 BOOL restartWindows;
58 BOOL rebootSystem;
59 PropPageInfo* proppage;
60 int x;
61 int y;
62 int width;
63 int height;
64} PropSheetInfo;
65
66typedef struct
67{
68 int x;
69 int y;
70} PADDING_INFO;
71
72/******************************************************************************
73 * Defines and global variables
74 */
75
76const char * PropSheetInfoStr = "PropertySheetInfo";
77
78#define MAX_CAPTION_LENGTH 255
79#define MAX_TABTEXT_LENGTH 255
80
81
82/******************************************************************************
83 * Prototypes
84 */
85static BOOL PROPSHEET_CreateDialog(PropSheetInfo* psInfo);
86static BOOL PROPSHEET_IsTooSmall(HWND hwndDlg, PropSheetInfo* psInfo);
87static BOOL PROPSHEET_AdjustSize(HWND hwndDlg, PropSheetInfo* psInfo);
88static BOOL PROPSHEET_AdjustButtons(HWND hwndParent, PropSheetInfo* psInfo);
89static BOOL PROPSHEET_CollectSheetInfo(LPCPROPSHEETHEADERA lppsh,
90 PropSheetInfo * psInfo);
91static BOOL PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEA lppsp,
92 PropSheetInfo * psInfo,
93 int index);
94static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
95 PropSheetInfo * psInfo);
96static int PROPSHEET_CreatePage(HWND hwndParent, int index,
97 const PropSheetInfo * psInfo,
98 LPCPROPSHEETPAGEA ppshpage,
99 BOOL showPage);
100static BOOL PROPSHEET_ShowPage(HWND hwndDlg, int index, PropSheetInfo * psInfo);
101static PADDING_INFO PROPSHEET_GetPaddingInfo(HWND hwndDlg);
102static BOOL PROPSHEET_Apply(HWND hwndDlg);
103static void PROPSHEET_Cancel(HWND hwndDlg);
104static void PROPSHEET_Help(HWND hwndDlg);
105static void PROPSHEET_Changed(HWND hwndDlg, HWND hwndDirtyPage);
106static void PROPSHEET_UnChanged(HWND hwndDlg, HWND hwndCleanPage);
107static void PROPSHEET_PressButton(HWND hwndDlg, int buttonID);
108static void PROPSHEET_SetTitleA(HWND hwndDlg, DWORD dwStyle, LPCSTR lpszText);
109static BOOL PROPSHEET_SetCurSel(HWND hwndDlg,
110 int index,
111 HPROPSHEETPAGE hpage);
112static LRESULT PROPSHEET_QuerySiblings(HWND hwndDlg,
113 WPARAM wParam, LPARAM lParam);
114static LPCPROPSHEETPAGEA PROPSHEET_GetPSPPage(const PropSheetInfo * psInfo,
115 int index);
116static BOOL PROPSHEET_AddPage(HWND hwndDlg,
117 HPROPSHEETPAGE hpage);
118
119static BOOL PROPSHEET_RemovePage(HWND hwndDlg,
120 int index,
121 HPROPSHEETPAGE hpage);
122static void PROPSHEET_CleanUp();
123static int PROPSHEET_GetPageIndex(HPROPSHEETPAGE hpage, PropSheetInfo* psInfo);
124
125BOOL WINAPI
126PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
127
128
129/******************************************************************************
130 * PROPSHEET_CollectSheetInfo
131 *
132 * Collect relevant data.
133 */
134static BOOL PROPSHEET_CollectSheetInfo(LPCPROPSHEETHEADERA lppsh,
135 PropSheetInfo * psInfo)
136{
137 DWORD dwFlags = lppsh->dwFlags;
138
139 psInfo->hasHelp = dwFlags & PSH_HASHELP;
140 psInfo->hasApply = !(dwFlags & PSH_NOAPPLYNOW);
141 psInfo->useCallback = dwFlags & PSH_USECALLBACK;
142 psInfo->isModeless = dwFlags & PSH_MODELESS;
143 psInfo->ppshheader = lppsh;
144 psInfo->nPages = lppsh->nPages;
145
146 if (dwFlags & PSH_USEPSTARTPAGE)
147 {
148// TRACE(propsheet, "PSH_USEPSTARTPAGE is on");
149 psInfo->active_page = 0;
150 }
151 else
152 psInfo->active_page = lppsh->u2.nStartPage;
153
154 psInfo->restartWindows = FALSE;
155 psInfo->rebootSystem = FALSE;
156
157 return TRUE;
158}
159
160/******************************************************************************
161 * PROPSHEET_CollectPageInfo
162 *
163 * Collect property sheet data.
164 * With code taken from DIALOG_ParseTemplate32.
165 */
166BOOL PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEA lppsp,
167 PropSheetInfo * psInfo,
168 int index)
169{
170 DLGTEMPLATE* pTemplate;
171 const WORD* p;
172 DWORD dwFlags;
173 int width, height;
174
175 if (psInfo->ppshheader->dwFlags & PSH_PROPSHEETPAGE)
176 psInfo->proppage[index].hpage = 0;
177 psInfo->proppage[index].hwndPage = 0;
178 psInfo->proppage[index].isDirty = FALSE;
179
180 /*
181 * Process property page flags.
182 */
183 dwFlags = lppsp->dwFlags;
184 psInfo->proppage[index].useCallback = dwFlags & PSP_USECALLBACK;
185 psInfo->proppage[index].hasHelp = dwFlags & PSP_HASHELP;
186
187 /* as soon as we have a page with the help flag, set the sheet flag on */
188 if (psInfo->proppage[index].hasHelp)
189 psInfo->hasHelp = TRUE;
190
191 /*
192 * Process page template.
193 */
194 if (dwFlags & PSP_DLGINDIRECT)
195 pTemplate = (DLGTEMPLATE*)lppsp->u1.pResource;
196 else
197 {
198 HRSRC hResource = FindResourceA(lppsp->hInstance,
199 lppsp->u1.pszTemplate,
200 RT_DIALOGA);
201 HGLOBAL hTemplate = LoadResource(lppsp->hInstance,
202 hResource);
203 pTemplate = (LPDLGTEMPLATEA)LockResource(hTemplate);
204 }
205
206 /*
207 * Extract the size of the page and the caption.
208 */
209 p = (const WORD *)pTemplate;
210
211 if (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
212 {
213 /* DIALOGEX template */
214
215 p++; /* dlgVer */
216 p++; /* signature */
217 p += 2; /* help ID */
218 p += 2; /* ext style */
219 p += 2; /* style */
220 }
221 else
222 {
223 /* DIALOG template */
224
225 p += 2; /* style */
226 p += 2; /* ext style */
227 }
228
229 p++; /* nb items */
230 p++; /* x */
231 p++; /* y */
232 width = (WORD)*p; p++;
233 height = (WORD)*p; p++;
234
235 /* remember the largest width and height */
236 if (width > psInfo->width)
237 psInfo->width = width;
238
239 if (height > psInfo->height)
240 psInfo->height = height;
241
242 /* menu */
243 switch ((WORD)*p)
244 {
245 case 0x0000:
246 p++;
247 break;
248 case 0xffff:
249 p += 2;
250 break;
251 default:
252 p += lstrlenW( (LPCWSTR)p ) + 1;
253 break;
254 }
255
256 /* class */
257 switch ((WORD)*p)
258 {
259 case 0x0000:
260 p++;
261 break;
262 case 0xffff:
263 p += 2;
264 break;
265 default:
266 p += lstrlenW( (LPCWSTR)p ) + 1;
267 break;
268 }
269
270 /* Extract the caption */
271 psInfo->proppage[index].pszText = (LPCWSTR)p;
272// TRACE(propsheet, "Tab %d %s\n",index,debugstr_w((LPCWSTR)p));
273 p += lstrlenW((LPCWSTR)p) + 1;
274
275 return TRUE;
276}
277
278/******************************************************************************
279 * PROPSHEET_CreateDialog
280 *
281 * Creates the actual property sheet.
282 */
283BOOL PROPSHEET_CreateDialog(PropSheetInfo* psInfo)
284{
285 LRESULT ret;
286 LPCVOID template;
287 HRSRC hRes;
288
289 if (!(hRes = FindResourceA(COMCTL32_hModule,
290 MAKEINTRESOURCEA(IDD_PROPSHEET),
291 RT_DIALOGA)))
292 return FALSE;
293
294 if (!(template = (LPVOID)LoadResource(COMCTL32_hModule, hRes)))
295 return FALSE;
296
297 if (psInfo->useCallback)
298 (*(psInfo->ppshheader->pfnCallback))(0, PSCB_PRECREATE, (LPARAM)template);
299
300 if (psInfo->ppshheader->dwFlags & PSH_MODELESS)
301 ret = CreateDialogIndirectParamA(psInfo->ppshheader->hInstance,
302 (LPDLGTEMPLATEA) template,
303 psInfo->ppshheader->hwndParent,
304 (DLGPROC) PROPSHEET_DialogProc,
305 (LPARAM)psInfo);
306 else
307 ret = DialogBoxIndirectParamA(psInfo->ppshheader->hInstance,
308 (LPDLGTEMPLATEA) template,
309 psInfo->ppshheader->hwndParent,
310 (DLGPROC) PROPSHEET_DialogProc,
311 (LPARAM)psInfo);
312
313 return ret;
314}
315
316/******************************************************************************
317 * PROPSHEET_IsTooSmall
318 *
319 * Verify that the resource property sheet is big enough.
320 */
321static BOOL PROPSHEET_IsTooSmall(HWND hwndDlg, PropSheetInfo* psInfo)
322{
323 HWND hwndTabCtrl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
324 RECT rcOrigTab, rcPage;
325
326 /*
327 * Original tab size.
328 */
329 GetClientRect(hwndTabCtrl, &rcOrigTab);
330// TRACE(propsheet, "orig tab %d %d %d %d\n", rcOrigTab.left, rcOrigTab.top,
331// rcOrigTab.right, rcOrigTab.bottom);
332
333 /*
334 * Biggest page size.
335 */
336 rcPage.left = psInfo->x;
337 rcPage.top = psInfo->y;
338 rcPage.right = psInfo->width;
339 rcPage.bottom = psInfo->height;
340
341 MapDialogRect(hwndDlg, &rcPage);
342// TRACE(propsheet, "biggest page %d %d %d %d\n", rcPage.left, rcPage.top,
343// rcPage.right, rcPage.bottom);
344
345 if (rcPage.right > rcOrigTab.right)
346 return TRUE;
347
348 if (rcPage.bottom > rcOrigTab.bottom)
349 return TRUE;
350
351 return FALSE;
352}
353
354/******************************************************************************
355 * PROPSHEET_AdjustSize
356 *
357 * Resizes the property sheet and the tab control to fit the largest page.
358 */
359static BOOL PROPSHEET_AdjustSize(HWND hwndDlg, PropSheetInfo* psInfo)
360{
361 HWND hwndTabCtrl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
362 HWND hwndButton = GetDlgItem(hwndDlg, IDOK);
363 RECT rc;
364 int tabOffsetX, tabOffsetY, buttonHeight;
365 PADDING_INFO padding = PROPSHEET_GetPaddingInfo(hwndDlg);
366
367 /* Get the height of buttons */
368 GetClientRect(hwndButton, &rc);
369 buttonHeight = rc.bottom;
370
371 /*
372 * Biggest page size.
373 */
374 rc.left = psInfo->x;
375 rc.top = psInfo->y;
376 rc.right = psInfo->width;
377 rc.bottom = psInfo->height;
378
379 MapDialogRect(hwndDlg, &rc);
380
381 /*
382 * Resize the tab control.
383 */
384 SendMessageA(hwndTabCtrl, TCM_ADJUSTRECT, TRUE, (LPARAM)&rc);
385
386 tabOffsetX = -(rc.left);
387 tabOffsetY = -(rc.top);
388
389 rc.right -= rc.left;
390 rc.bottom -= rc.top;
391 SetWindowPos(hwndTabCtrl, 0, 0, 0, rc.right, rc.bottom,
392 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
393
394 GetClientRect(hwndTabCtrl, &rc);
395
396// TRACE(propsheet, "tab client rc %d %d %d %d\n",
397// rc.left, rc.top, rc.right, rc.bottom);
398
399 rc.right += ((padding.x * 2) + tabOffsetX);
400 rc.bottom += (buttonHeight + (3 * padding.y) + tabOffsetY);
401
402 /*
403 * Resize the property sheet.
404 */
405 SetWindowPos(hwndDlg, 0, 0, 0, rc.right, rc.bottom,
406 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
407
408 return TRUE;
409}
410
411/******************************************************************************
412 * PROPSHEET_AdjustButtons
413 *
414 * Adjusts the buttons' positions.
415 */
416static BOOL PROPSHEET_AdjustButtons(HWND hwndParent, PropSheetInfo* psInfo)
417{
418 HWND hwndButton = GetDlgItem(hwndParent, IDOK);
419 RECT rcSheet;
420 int x, y;
421 int num_buttons = 2;
422 int buttonWidth, buttonHeight;
423 PADDING_INFO padding = PROPSHEET_GetPaddingInfo(hwndParent);
424
425 if (psInfo->hasApply)
426 num_buttons++;
427
428 if (psInfo->hasHelp)
429 num_buttons++;
430
431 /*
432 * Obtain the size of the buttons.
433 */
434 GetClientRect(hwndButton, &rcSheet);
435 buttonWidth = rcSheet.right;
436 buttonHeight = rcSheet.bottom;
437
438 /*
439 * Get the size of the property sheet.
440 */
441 GetClientRect(hwndParent, &rcSheet);
442
443 /*
444 * All buttons will be at this y coordinate.
445 */
446 y = rcSheet.bottom - (padding.y + buttonHeight);
447
448 /*
449 * Position OK button.
450 */
451 hwndButton = GetDlgItem(hwndParent, IDOK);
452
453 x = rcSheet.right - ((padding.x + buttonWidth) * num_buttons);
454
455 SetWindowPos(hwndButton, 0, x, y, 0, 0,
456 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
457
458 /*
459 * Position Cancel button.
460 */
461 hwndButton = GetDlgItem(hwndParent, IDCANCEL);
462
463 x = rcSheet.right - ((padding.x + buttonWidth) * (num_buttons - 1));
464
465 SetWindowPos(hwndButton, 0, x, y, 0, 0,
466 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
467
468 /*
469 * Position Apply button.
470 */
471 hwndButton = GetDlgItem(hwndParent, IDC_APPLY_BUTTON);
472
473 if (psInfo->hasApply)
474 {
475 if (psInfo->hasHelp)
476 x = rcSheet.right - ((padding.x + buttonWidth) * 2);
477 else
478 x = rcSheet.right - (padding.x + buttonWidth);
479
480 SetWindowPos(hwndButton, 0, x, y, 0, 0,
481 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
482
483 EnableWindow(hwndButton, FALSE);
484 }
485 else
486 ShowWindow(hwndButton, SW_HIDE);
487
488 /*
489 * Position Help button.
490 */
491 hwndButton = GetDlgItem(hwndParent, IDHELP);
492
493 if (psInfo->hasHelp)
494 {
495 x = rcSheet.right - (padding.x + buttonWidth);
496
497 SetWindowPos(hwndButton, 0, x, y, 0, 0,
498 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
499 }
500 else
501 ShowWindow(hwndButton, SW_HIDE);
502
503 return TRUE;
504}
505
506/******************************************************************************
507 * PROPSHEET_GetPaddingInfo
508 *
509 * Returns the layout information.
510 */
511static PADDING_INFO PROPSHEET_GetPaddingInfo(HWND hwndDlg)
512{
513 HWND hwndTab = GetDlgItem(hwndDlg, IDC_TABCONTROL);
514 RECT rcTab;
515 POINT tl;
516 PADDING_INFO padding;
517
518 GetWindowRect(hwndTab, &rcTab);
519
520 tl.x = rcTab.left;
521 tl.y = rcTab.top;
522
523 ScreenToClient(hwndDlg, &tl);
524
525 padding.x = tl.x;
526 padding.y = tl.y;
527
528 return padding;
529}
530
531/******************************************************************************
532 * PROPSHEET_CreateTabControl
533 *
534 * Insert the tabs in the tab control.
535 */
536static BOOL PROPSHEET_CreateTabControl(HWND hwndParent,
537 PropSheetInfo * psInfo)
538{
539 HWND hwndTabCtrl = GetDlgItem(hwndParent, IDC_TABCONTROL);
540 TCITEMA item;
541 int i, nTabs;
542 char tabtext[MAX_TABTEXT_LENGTH] = "Tab text";
543
544 item.mask = TCIF_TEXT;
545 item.pszText = tabtext;
546 item.cchTextMax = MAX_TABTEXT_LENGTH;
547
548 nTabs = psInfo->ppshheader->nPages;
549
550 for (i = 0; i < nTabs; i++)
551 {
552 WideCharToMultiByte(CP_ACP, 0,
553 (LPCWSTR)psInfo->proppage[i].pszText,
554 -1, tabtext, MAX_TABTEXT_LENGTH, NULL, NULL);
555
556 SendMessageA(hwndTabCtrl, TCM_INSERTITEMA, (WPARAM)i, (LPARAM)&item);
557 }
558
559 return TRUE;
560}
561
562/******************************************************************************
563 * PROPSHEET_CreatePage
564 *
565 * Creates a page.
566 */
567static int PROPSHEET_CreatePage(HWND hwndParent,
568 int index,
569 const PropSheetInfo * psInfo,
570 LPCPROPSHEETPAGEA ppshpage,
571 BOOL showPage)
572{
573 DLGTEMPLATE* pTemplate;
574 HWND hwndPage;
575 RECT rc;
576 PropPageInfo* ppInfo = psInfo->proppage;
577 PADDING_INFO padding = PROPSHEET_GetPaddingInfo(hwndParent);
578 HWND hwndTabCtrl = GetDlgItem(hwndParent, IDC_TABCONTROL);
579
580// TRACE(propsheet, "index %d\n", index);
581
582 if (ppshpage->dwFlags & PSP_DLGINDIRECT)
583 pTemplate = (DLGTEMPLATE*)ppshpage->u1.pResource;
584 else
585 {
586 HRSRC hResource = FindResourceA(ppshpage->hInstance,
587 ppshpage->u1.pszTemplate,
588 RT_DIALOGA);
589 HGLOBAL hTemplate = LoadResource(ppshpage->hInstance, hResource);
590 pTemplate = (LPDLGTEMPLATEA)LockResource(hTemplate);
591 }
592
593 if (((MyDLGTEMPLATEEX*)pTemplate)->signature == 0xFFFF)
594 {
595 ((MyDLGTEMPLATEEX*)pTemplate)->style |= WS_CHILD;
596 ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~DS_MODALFRAME;
597 ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_CAPTION;
598 ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_SYSMENU;
599 ((MyDLGTEMPLATEEX*)pTemplate)->style &= ~WS_POPUP;
600 }
601 else
602 {
603 pTemplate->style |= WS_CHILD;
604 pTemplate->style &= ~DS_MODALFRAME;
605 pTemplate->style &= ~WS_CAPTION;
606 pTemplate->style &= ~WS_SYSMENU;
607 pTemplate->style &= ~WS_POPUP;
608 }
609
610 if (psInfo->proppage[index].useCallback)
611 (*(ppshpage->pfnCallback))(hwndParent,
612 PSPCB_CREATE,
613 (LPPROPSHEETPAGEA)ppshpage);
614
615 hwndPage = CreateDialogIndirectParamA(ppshpage->hInstance,
616 pTemplate,
617 hwndParent,
618 ppshpage->pfnDlgProc,
619 (LPARAM)ppshpage);
620
621 ppInfo[index].hwndPage = hwndPage;
622
623 rc.left = psInfo->x;
624 rc.top = psInfo->y;
625 rc.right = psInfo->width;
626 rc.bottom = psInfo->height;
627
628 MapDialogRect(hwndParent, &rc);
629
630 /*
631 * Ask the Tab control to fit this page in.
632 */
633 SendMessageA(hwndTabCtrl, TCM_ADJUSTRECT, FALSE, (LPARAM)&rc);
634
635 SetWindowPos(hwndPage, HWND_TOP,
636 rc.left + padding.x,
637 rc.top + padding.y,
638 0, 0, SWP_NOSIZE);
639
640 if (showPage)
641 ShowWindow(hwndPage, SW_SHOW);
642 else
643 ShowWindow(hwndPage, SW_HIDE);
644
645 return TRUE;
646}
647
648/******************************************************************************
649 * PROPSHEET_ShowPage
650 *
651 * Displays or creates the specified page.
652 */
653static BOOL PROPSHEET_ShowPage(HWND hwndDlg, int index, PropSheetInfo * psInfo)
654{
655 if (index == psInfo->active_page)
656 return TRUE;
657
658 ShowWindow(psInfo->proppage[psInfo->active_page].hwndPage, SW_HIDE);
659
660 if (psInfo->proppage[index].hwndPage != 0)
661 ShowWindow(psInfo->proppage[index].hwndPage, SW_SHOW);
662 else
663 {
664 LPCPROPSHEETPAGEA ppshpage = PROPSHEET_GetPSPPage(psInfo, index);
665 PROPSHEET_CreatePage(hwndDlg, index, psInfo, ppshpage, TRUE);
666 }
667
668 psInfo->active_page = index;
669
670 return TRUE;
671}
672
673/******************************************************************************
674 * PROPSHEET_Apply
675 */
676static BOOL PROPSHEET_Apply(HWND hwndDlg)
677{
678 int i;
679 NMHDR hdr;
680 HWND hwndPage;
681 LRESULT msgResult;
682 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
683 PropSheetInfoStr);
684
685 hdr.hwndFrom = hwndDlg;
686
687 /*
688 * Send PSN_KILLACTIVE to the current page.
689 */
690 hdr.code = PSN_KILLACTIVE;
691
692 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
693
694 if (SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr) != FALSE)
695 return FALSE;
696
697 /*
698 * Send PSN_APPLY to all pages.
699 */
700 hdr.code = PSN_APPLY;
701
702 for (i = 0; i < psInfo->nPages; i++)
703 {
704 hwndPage = psInfo->proppage[i].hwndPage;
705 msgResult = SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr);
706
707 if (msgResult == PSNRET_INVALID_NOCHANGEPAGE)
708 return FALSE;
709 }
710
711 return TRUE;
712}
713
714/******************************************************************************
715 * PROPSHEET_Cancel
716 */
717static void PROPSHEET_Cancel(HWND hwndDlg)
718{
719 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
720 PropSheetInfoStr);
721 HWND hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
722 NMHDR hdr;
723
724 hdr.hwndFrom = hwndDlg;
725 hdr.code = PSN_QUERYCANCEL;
726
727 if (SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr))
728 return;
729
730 hdr.code = PSN_RESET;
731
732 SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr);
733
734 if (psInfo->isModeless)
735 psInfo->active_page = -1; /* makes PSM_GETCURRENTPAGEHWND return NULL */
736 else
737 EndDialog(hwndDlg, FALSE);
738}
739
740/******************************************************************************
741 * PROPSHEET_Help
742 */
743static void PROPSHEET_Help(HWND hwndDlg)
744{
745 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
746 PropSheetInfoStr);
747 HWND hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
748 NMHDR hdr;
749
750 hdr.hwndFrom = hwndDlg;
751 hdr.code = PSN_HELP;
752
753 SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr);
754}
755
756/******************************************************************************
757 * PROPSHEET_Changed
758 */
759static void PROPSHEET_Changed(HWND hwndDlg, HWND hwndDirtyPage)
760{
761 int i;
762 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
763 PropSheetInfoStr);
764
765 /*
766 * Set the dirty flag of this page.
767 */
768 for (i = 0; i < psInfo->nPages; i++)
769 {
770 if (psInfo->proppage[i].hwndPage == hwndDirtyPage)
771 psInfo->proppage[i].isDirty = TRUE;
772 }
773
774 /*
775 * Enable the Apply button.
776 */
777 if (psInfo->hasApply)
778 {
779 HWND hwndApplyBtn = GetDlgItem(hwndDlg, IDC_APPLY_BUTTON);
780
781 EnableWindow(hwndApplyBtn, TRUE);
782 }
783}
784
785/******************************************************************************
786 * PROPSHEET_UnChanged
787 */
788static void PROPSHEET_UnChanged(HWND hwndDlg, HWND hwndCleanPage)
789{
790 int i;
791 BOOL noPageDirty = TRUE;
792 HWND hwndApplyBtn = GetDlgItem(hwndDlg, IDC_APPLY_BUTTON);
793 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
794 PropSheetInfoStr);
795
796 for (i = 0; i < psInfo->nPages; i++)
797 {
798 /* set the specified page as clean */
799 if (psInfo->proppage[i].hwndPage == hwndCleanPage)
800 psInfo->proppage[i].isDirty = FALSE;
801
802 /* look to see if there's any dirty pages */
803 if (psInfo->proppage[i].isDirty)
804 noPageDirty = FALSE;
805 }
806
807 /*
808 * Disable Apply button.
809 */
810 if (noPageDirty)
811 EnableWindow(hwndApplyBtn, FALSE);
812}
813
814/******************************************************************************
815 * PROPSHEET_PressButton
816 */
817static void PROPSHEET_PressButton(HWND hwndDlg, int buttonID)
818{
819 switch (buttonID)
820 {
821 case PSBTN_APPLYNOW:
822 SendMessageA(hwndDlg, WM_COMMAND, IDC_APPLY_BUTTON, 0);
823 break;
824 case PSBTN_BACK:
825// FIXME(propsheet, "Wizard mode not implemented.\n");
826 break;
827 case PSBTN_CANCEL:
828 SendMessageA(hwndDlg, WM_COMMAND, IDCANCEL, 0);
829 break;
830 case PSBTN_FINISH:
831// FIXME(propsheet, "Wizard mode not implemented.\n");
832 break;
833 case PSBTN_HELP:
834 SendMessageA(hwndDlg, WM_COMMAND, IDHELP, 0);
835 break;
836 case PSBTN_NEXT:
837// FIXME(propsheet, "Wizard mode not implemented.\n");
838 break;
839 case PSBTN_OK:
840 SendMessageA(hwndDlg, WM_COMMAND, IDOK, 0);
841 break;
842 default:
843// FIXME(propsheet, "Invalid button index %d\n", buttonID);
844 break;
845 }
846}
847
848/******************************************************************************
849 * PROPSHEET_SetCurSel
850 */
851static BOOL PROPSHEET_SetCurSel(HWND hwndDlg,
852 int index,
853 HPROPSHEETPAGE hpage)
854{
855 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
856 PropSheetInfoStr);
857 HWND hwndPage;
858 HWND hwndHelp = GetDlgItem(hwndDlg, IDHELP);
859 NMHDR hdr;
860
861 /*
862 * Notify the current page.
863 */
864 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
865
866 hdr.hwndFrom = hwndDlg;
867 hdr.code = PSN_KILLACTIVE;
868
869 if (SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr))
870 return FALSE;
871
872// if (hpage != NULL)
873// FIXME(propsheet, "Implement HPROPSHEETPAGE!\n");
874// else
875 hwndPage = psInfo->proppage[index].hwndPage;
876
877 /*
878 * Notify the new page.
879 */
880 hdr.code = PSN_SETACTIVE;
881
882 SendMessageA(hwndPage, WM_NOTIFY, 0, (LPARAM) &hdr);
883
884 /*
885 * Display the new page.
886 */
887 PROPSHEET_ShowPage(hwndDlg, index, psInfo);
888
889 if (psInfo->proppage[index].hasHelp)
890 EnableWindow(hwndHelp, TRUE);
891 else
892 EnableWindow(hwndHelp, FALSE);
893
894 return TRUE;
895}
896
897/******************************************************************************
898 * PROPSHEET_SetTitleA
899 */
900static void PROPSHEET_SetTitleA(HWND hwndDlg, DWORD dwStyle, LPCSTR lpszText)
901{
902 if (dwStyle & PSH_PROPTITLE)
903 {
904 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
905 PropSheetInfoStr);
906 char* dest;
907 int lentitle = strlen(lpszText);
908 int lenprop = strlen(psInfo->strPropertiesFor);
909
910 dest = COMCTL32_Alloc(lentitle + lenprop + 1);
911 strcpy(dest, psInfo->strPropertiesFor);
912 strcat(dest, lpszText);
913
914 SetWindowTextA(hwndDlg, dest);
915 COMCTL32_Free(dest);
916 }
917 else
918 SetWindowTextA(hwndDlg, lpszText);
919}
920
921/******************************************************************************
922 * PROPSHEET_QuerySiblings
923 */
924static LRESULT PROPSHEET_QuerySiblings(HWND hwndDlg,
925 WPARAM wParam, LPARAM lParam)
926{
927 int i = 0;
928 HWND hwndPage;
929 LRESULT msgResult = 0;
930 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
931 PropSheetInfoStr);
932
933 while ((i < psInfo->nPages) && (msgResult == 0))
934 {
935 hwndPage = psInfo->proppage[i].hwndPage;
936 msgResult = SendMessageA(hwndPage, PSM_QUERYSIBLINGS, wParam, lParam);
937 i++;
938 }
939
940 return msgResult;
941}
942
943/******************************************************************************
944 * PROPSHEET_GetPSPPage
945 */
946static LPCPROPSHEETPAGEA PROPSHEET_GetPSPPage(const PropSheetInfo * psInfo,
947 int index)
948{
949 BOOL usePSP = psInfo->ppshheader->dwFlags & PSH_PROPSHEETPAGE;
950 LPCPROPSHEETPAGEA lppsp;
951 int realIndex = psInfo->proppage[index].index;
952
953 if (usePSP)
954 {
955 BYTE* pByte;
956
957 lppsp = psInfo->ppshheader->u3.ppsp;
958
959 pByte = (BYTE*) lppsp;
960
961 pByte += (lppsp->dwSize * realIndex);
962 lppsp = (LPCPROPSHEETPAGEA)pByte;
963 }
964 else
965 lppsp = (LPCPROPSHEETPAGEA) psInfo->ppshheader->u3.phpage[realIndex];
966
967 return lppsp;
968}
969
970/******************************************************************************
971 * PROPSHEET_AddPage
972 */
973static BOOL PROPSHEET_AddPage(HWND hwndDlg,
974 HPROPSHEETPAGE hpage)
975{
976 PropSheetInfo * psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
977 PropSheetInfoStr);
978 HWND hwndTabControl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
979 TCITEMA item;
980 char tabtext[MAX_TABTEXT_LENGTH] = "Tab text";
981 LPCPROPSHEETPAGEA ppsp = (LPCPROPSHEETPAGEA)hpage;
982
983 /*
984 * Allocate and fill in a new PropPageInfo entry.
985 */
986 psInfo->proppage = (PropPageInfo*) COMCTL32_ReAlloc(psInfo->proppage,
987 sizeof(PropPageInfo) *
988 (psInfo->nPages + 1));
989
990 PROPSHEET_CollectPageInfo(ppsp, psInfo, psInfo->nPages);
991 psInfo->proppage[psInfo->nPages].index = -1;
992 psInfo->proppage[psInfo->nPages].hpage = hpage;
993
994 /*
995 * Create the page but don't show it.
996 */
997 PROPSHEET_CreatePage(hwndDlg, psInfo->nPages, psInfo, ppsp, FALSE);
998
999 /*
1000 * Add a new tab to the tab control.
1001 */
1002 item.mask = TCIF_TEXT;
1003 item.pszText = tabtext;
1004 item.cchTextMax = MAX_TABTEXT_LENGTH;
1005
1006 WideCharToMultiByte(CP_ACP, 0,
1007 (LPCWSTR)psInfo->proppage[psInfo->nPages].pszText,
1008 -1, tabtext, MAX_TABTEXT_LENGTH, NULL, NULL);
1009
1010 SendMessageA(hwndTabControl, TCM_INSERTITEMA, psInfo->nPages + 1,
1011 (LPARAM)&item);
1012
1013 psInfo->nPages++;
1014
1015 return FALSE;
1016}
1017
1018/******************************************************************************
1019 * PROPSHEET_RemovePage
1020 */
1021static BOOL PROPSHEET_RemovePage(HWND hwndDlg,
1022 int index,
1023 HPROPSHEETPAGE hpage)
1024{
1025 PropSheetInfo * psInfo = (PropSheetInfo*) GetPropA(hwndDlg,
1026 PropSheetInfoStr);
1027 HWND hwndTabControl = GetDlgItem(hwndDlg, IDC_TABCONTROL);
1028 PropPageInfo* oldPages = psInfo->proppage;
1029
1030 /*
1031 * hpage takes precedence over index.
1032 */
1033 if (hpage != 0)
1034 {
1035 index = PROPSHEET_GetPageIndex(hpage, psInfo);
1036
1037 if (index == -1)
1038 {
1039// TRACE(propsheet, "Could not find page to remove!\n");
1040 return FALSE;
1041 }
1042 }
1043
1044// TRACE(propsheet, "total pages %d removing page %d active page %d\n",
1045// psInfo->nPages, index, psInfo->active_page);
1046 /*
1047 * Check if we're removing the active page.
1048 */
1049 if (index == psInfo->active_page)
1050 {
1051 if (psInfo->nPages > 1)
1052 {
1053 if (index > 0)
1054 {
1055 /* activate previous page */
1056 PROPSHEET_ShowPage(hwndDlg, index - 1, psInfo);
1057 }
1058 else
1059 {
1060 /* activate the next page */
1061 PROPSHEET_ShowPage(hwndDlg, index + 1, psInfo);
1062 }
1063 }
1064 else
1065 {
1066// TRACE(propsheet, "Removing the only page, close the dialog!\n");
1067
1068 if (psInfo->isModeless)
1069 psInfo->active_page = -1;
1070 else
1071 EndDialog(hwndDlg, FALSE);
1072
1073 return TRUE;
1074 }
1075 }
1076
1077 if (index < psInfo->active_page)
1078 psInfo->active_page--;
1079
1080 /* Remove the tab */
1081 SendMessageA(hwndTabControl, TCM_DELETEITEM, index, 0);
1082
1083 psInfo->nPages--;
1084 psInfo->proppage = COMCTL32_Alloc(sizeof(PropPageInfo) * psInfo->nPages);
1085
1086 if (index > 0)
1087 memcpy(&psInfo->proppage[0], &oldPages[0], index * sizeof(PropPageInfo));
1088
1089 if (index < psInfo->nPages)
1090 memcpy(&psInfo->proppage[index], &oldPages[index + 1],
1091 (psInfo->nPages - index) * sizeof(PropPageInfo));
1092
1093 COMCTL32_Free(oldPages);
1094
1095 return FALSE;
1096}
1097
1098/******************************************************************************
1099 * PROPSHEET_GetPageIndex
1100 *
1101 * Given a HPROPSHEETPAGE, returns the index of the corresponding page from
1102 * the array of PropPageInfo.
1103 */
1104static int PROPSHEET_GetPageIndex(HPROPSHEETPAGE hpage, PropSheetInfo* psInfo)
1105{
1106 BOOL found = FALSE;
1107 int index = 0;
1108
1109 while ((index < psInfo->nPages) && (found == FALSE))
1110 {
1111 if (psInfo->proppage[index].hpage == hpage)
1112 found = TRUE;
1113 else
1114 index++;
1115 }
1116
1117 if (found == FALSE)
1118 index = -1;
1119
1120 return index;
1121}
1122
1123/******************************************************************************
1124 * PROPSHEET_CleanUp
1125 */
1126static void PROPSHEET_CleanUp(HWND hwndDlg)
1127{
1128 PropSheetInfo* psInfo = (PropSheetInfo*) RemovePropA(hwndDlg,
1129 PropSheetInfoStr);
1130 COMCTL32_Free(psInfo->proppage);
1131 COMCTL32_Free(psInfo->strPropertiesFor);
1132
1133 GlobalFree((HGLOBAL)psInfo);
1134}
1135
1136/******************************************************************************
1137 * PropertySheetA (COMCTL32.84)(COMCTL32.83)
1138 */
1139INT WINAPI PropertySheetA(LPCPROPSHEETHEADERA lppsh)
1140{
1141 int bRet = 0;
1142 PropSheetInfo* psInfo = (PropSheetInfo*) GlobalAlloc(GPTR,
1143 sizeof(PropSheetInfo));
1144 LPCPROPSHEETPAGEA lppsp;
1145 int i;
1146
1147 PROPSHEET_CollectSheetInfo(lppsh, psInfo);
1148
1149 psInfo->proppage = (PropPageInfo*) COMCTL32_Alloc(sizeof(PropPageInfo) *
1150 lppsh->nPages);
1151
1152 for (i = 0; i < lppsh->nPages; i++)
1153 {
1154 psInfo->proppage[i].index = i;
1155 if (!(lppsh->dwFlags & PSH_PROPSHEETPAGE))
1156 psInfo->proppage[i].hpage = psInfo->ppshheader->u3.phpage[i];
1157 lppsp = PROPSHEET_GetPSPPage(psInfo, i);
1158 PROPSHEET_CollectPageInfo(lppsp, psInfo, i);
1159 }
1160
1161 bRet = PROPSHEET_CreateDialog(psInfo);
1162
1163 return bRet;
1164}
1165
1166/******************************************************************************
1167 * PropertySheet32W (COMCTL32.85)
1168 */
1169INT WINAPI PropertySheetW(LPCPROPSHEETHEADERW propertySheetHeader)
1170{
1171// FIXME(propsheet, "(%p): stub\n", propertySheetHeader);
1172
1173 return -1;
1174}
1175
1176/******************************************************************************
1177 * CreatePropertySheetPageA (COMCTL32.19)(COMCTL32.18)
1178 */
1179HPROPSHEETPAGE WINAPI CreatePropertySheetPageA(
1180 LPCPROPSHEETPAGEA lpPropSheetPage)
1181{
1182 PROPSHEETPAGEA* ppsp = COMCTL32_Alloc(sizeof(PROPSHEETPAGEA));
1183
1184 *ppsp = *lpPropSheetPage;
1185
1186 return (HPROPSHEETPAGE)ppsp;
1187}
1188
1189/******************************************************************************
1190 * CreatePropertySheetPageW (COMCTL32.20)
1191 */
1192HPROPSHEETPAGE WINAPI CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage)
1193{
1194// FIXME(propsheet, "(%p): stub\n", lpPropSheetPage);
1195
1196 return 0;
1197}
1198
1199/******************************************************************************
1200 * DestroyPropertySheetPage (COMCTL32.24)
1201 */
1202BOOL WINAPI DestroyPropertySheetPage(HPROPSHEETPAGE hPropPage)
1203{
1204 COMCTL32_Free(hPropPage);
1205
1206 return TRUE;
1207}
1208
1209/******************************************************************************
1210 * PROPSHEET_DialogProc
1211 */
1212BOOL WINAPI
1213PROPSHEET_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
1214{
1215 switch (uMsg)
1216 {
1217 case WM_INITDIALOG:
1218 {
1219 PropSheetInfo* psInfo = (PropSheetInfo*) lParam;
1220 char* strCaption = (char*)COMCTL32_Alloc(MAX_CAPTION_LENGTH);
1221 HWND hwndTabCtrl = GetDlgItem(hwnd, IDC_TABCONTROL);
1222 LPCPROPSHEETPAGEA ppshpage;
1223
1224 psInfo->strPropertiesFor = strCaption;
1225
1226 GetWindowTextA(hwnd, psInfo->strPropertiesFor, MAX_CAPTION_LENGTH);
1227
1228 PROPSHEET_CreateTabControl(hwnd, psInfo);
1229
1230 if (PROPSHEET_IsTooSmall(hwnd, psInfo))
1231 {
1232 PROPSHEET_AdjustSize(hwnd, psInfo);
1233 PROPSHEET_AdjustButtons(hwnd, psInfo);
1234 }
1235
1236 ppshpage = PROPSHEET_GetPSPPage(psInfo, psInfo->active_page);
1237 PROPSHEET_CreatePage(hwnd, psInfo->active_page, psInfo, ppshpage, TRUE);
1238 SendMessageA(hwndTabCtrl, TCM_SETCURSEL, psInfo->active_page, 0);
1239
1240 SetPropA(hwnd, PropSheetInfoStr, (HANDLE)psInfo);
1241
1242 PROPSHEET_SetTitleA(hwnd,
1243 psInfo->ppshheader->dwFlags,
1244 psInfo->ppshheader->pszCaption);
1245
1246 return TRUE;
1247 }
1248
1249 case WM_DESTROY:
1250 PROPSHEET_CleanUp(hwnd);
1251 return TRUE;
1252
1253 case WM_CLOSE:
1254 PROPSHEET_Cancel(hwnd);
1255 return TRUE;
1256
1257 case WM_COMMAND:
1258 {
1259 WORD wID = LOWORD(wParam);
1260
1261 switch (wID)
1262 {
1263 case IDOK:
1264 case IDC_APPLY_BUTTON:
1265 {
1266 HWND hwndApplyBtn = GetDlgItem(hwnd, IDC_APPLY_BUTTON);
1267
1268 if (PROPSHEET_Apply(hwnd) == FALSE)
1269 break;
1270
1271 EnableWindow(hwndApplyBtn, FALSE);
1272
1273 if (wID == IDOK)
1274 {
1275 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwnd,
1276 PropSheetInfoStr);
1277 int result = TRUE;
1278
1279 if (psInfo->restartWindows)
1280 result = ID_PSRESTARTWINDOWS;
1281
1282 /* reboot system takes precedence over restart windows */
1283 if (psInfo->rebootSystem)
1284 result = ID_PSREBOOTSYSTEM;
1285
1286 if (psInfo->isModeless)
1287 psInfo->active_page = -1;
1288 else
1289 EndDialog(hwnd, result);
1290 }
1291
1292 break;
1293 }
1294
1295 case IDCANCEL:
1296 PROPSHEET_Cancel(hwnd);
1297 break;
1298
1299 case IDHELP:
1300 PROPSHEET_Help(hwnd);
1301 break;
1302 }
1303
1304 return TRUE;
1305 }
1306
1307 case WM_NOTIFY:
1308 {
1309 NMHDR* pnmh = (LPNMHDR) lParam;
1310
1311 if (pnmh->code == TCN_SELCHANGE)
1312 {
1313 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwnd,
1314 PropSheetInfoStr);
1315 int index = SendMessageA(pnmh->hwndFrom, TCM_GETCURSEL, 0, 0);
1316 HWND hwndHelp = GetDlgItem(hwnd, IDHELP);
1317
1318 PROPSHEET_ShowPage(hwnd, index, psInfo);
1319
1320 if (psInfo->proppage[index].hasHelp)
1321 EnableWindow(hwndHelp, TRUE);
1322 else
1323 EnableWindow(hwndHelp, FALSE);
1324 }
1325
1326 return 0;
1327 }
1328
1329 case PSM_GETCURRENTPAGEHWND:
1330 {
1331 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwnd,
1332 PropSheetInfoStr);
1333 HWND hwndPage = 0;
1334
1335 if (psInfo->active_page != -1)
1336 hwndPage = psInfo->proppage[psInfo->active_page].hwndPage;
1337
1338 SetWindowLongA(hwnd, DWL_MSGRESULT, hwndPage);
1339
1340 return TRUE;
1341 }
1342
1343 case PSM_CHANGED:
1344 PROPSHEET_Changed(hwnd, (HWND)wParam);
1345 return TRUE;
1346
1347 case PSM_UNCHANGED:
1348 PROPSHEET_UnChanged(hwnd, (HWND)wParam);
1349 return TRUE;
1350
1351 case PSM_GETTABCONTROL:
1352 {
1353 HWND hwndTabCtrl = GetDlgItem(hwnd, IDC_TABCONTROL);
1354
1355 SetWindowLongA(hwnd, DWL_MSGRESULT, hwndTabCtrl);
1356
1357 return TRUE;
1358 }
1359
1360 case PSM_SETCURSEL:
1361 {
1362 BOOL msgResult;
1363
1364 msgResult = PROPSHEET_SetCurSel(hwnd,
1365 (int)wParam,
1366 (HPROPSHEETPAGE)lParam);
1367
1368 SetWindowLongA(hwnd, DWL_MSGRESULT, msgResult);
1369
1370 return TRUE;
1371 }
1372
1373 case PSM_CANCELTOCLOSE:
1374 {
1375 HWND hwndOK = GetDlgItem(hwnd, IDOK);
1376 HWND hwndCancel = GetDlgItem(hwnd, IDCANCEL);
1377
1378 EnableWindow(hwndCancel, FALSE);
1379 SetWindowTextA(hwndOK, "Close"); /* FIXME: hardcoded string */
1380
1381 return TRUE;
1382 }
1383
1384 case PSM_RESTARTWINDOWS:
1385 {
1386 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwnd,
1387 PropSheetInfoStr);
1388
1389 psInfo->restartWindows = TRUE;
1390 return TRUE;
1391 }
1392
1393 case PSM_REBOOTSYSTEM:
1394 {
1395 PropSheetInfo* psInfo = (PropSheetInfo*) GetPropA(hwnd,
1396 PropSheetInfoStr);
1397
1398 psInfo->rebootSystem = TRUE;
1399 return TRUE;
1400 }
1401
1402 case PSM_SETTITLEA:
1403 PROPSHEET_SetTitleA(hwnd, (DWORD) wParam, (LPCSTR) lParam);
1404 return TRUE;
1405
1406 case PSM_APPLY:
1407 {
1408 BOOL msgResult = PROPSHEET_Apply(hwnd);
1409
1410 SetWindowLongA(hwnd, DWL_MSGRESULT, msgResult);
1411
1412 return TRUE;
1413 }
1414
1415 case PSM_QUERYSIBLINGS:
1416 {
1417 LRESULT msgResult = PROPSHEET_QuerySiblings(hwnd, wParam, lParam);
1418
1419 SetWindowLongA(hwnd, DWL_MSGRESULT, msgResult);
1420
1421 return TRUE;
1422 }
1423
1424 case PSM_ADDPAGE:
1425 PROPSHEET_AddPage(hwnd, (HPROPSHEETPAGE)lParam);
1426 return TRUE;
1427
1428 case PSM_REMOVEPAGE:
1429 PROPSHEET_RemovePage(hwnd, (int)wParam, (HPROPSHEETPAGE)lParam);
1430 return TRUE;
1431
1432 case PSM_ISDIALOGMESSAGE:
1433 {
1434// FIXME (propsheet, "Unimplemented msg PSM_ISDIALOGMESSAGE\n");
1435 return 0;
1436 }
1437
1438 case PSM_PRESSBUTTON:
1439 PROPSHEET_PressButton(hwnd, (int)wParam);
1440 return TRUE;
1441
1442 case PSM_SETTITLEW:
1443// FIXME (propsheet, "Unimplemented msg PSM_SETTITLE32W\n");
1444 return 0;
1445 case PSM_SETWIZBUTTONS:
1446// FIXME (propsheet, "Unimplemented msg PSM_SETWIZBUTTONS\n");
1447 return 0;
1448 case PSM_SETCURSELID:
1449// FIXME (propsheet, "Unimplemented msg PSM_SETCURSELID\n");
1450 return 0;
1451 case PSM_SETFINISHTEXTA:
1452// FIXME (propsheet, "Unimplemented msg PSM_SETFINISHTEXT32A\n");
1453 return 0;
1454 case PSM_SETFINISHTEXTW:
1455// FIXME (propsheet, "Unimplemented msg PSM_SETFINISHTEXT32W\n");
1456 return 0;
1457
1458 default:
1459 return FALSE;
1460 }
1461}
1462
Note: See TracBrowser for help on using the repository browser.