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

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

Unicode and other extensions

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