4 * Copyright 1998 Francis Beaudet
5 * Copyright 1999 Thuy Nguyen
9 * - Unicode property sheets
20 #include "debugtools.h"
24 /******************************************************************************
36 typedef struct tagPropPageInfo
38 HPROPSHEETPAGE hpage
; /* to keep track of pages not passed to PropertySheet */
47 typedef struct tagPropSheetInfo
50 PROPSHEETHEADERA ppshheader
;
51 LPSTR strPropertiesFor
;
61 PropPageInfo
* proppage
;
66 HIMAGELIST hImageList
;
75 /******************************************************************************
76 * Defines and global variables
79 const char * PropSheetInfoStr
= "PropertySheetInfo";
81 #define MAX_CAPTION_LENGTH 255
82 #define MAX_TABTEXT_LENGTH 255
83 #define MAX_BUTTONTEXT_LENGTH 64
85 /******************************************************************************
88 static BOOL
PROPSHEET_CreateDialog(PropSheetInfo
* psInfo
);
89 static BOOL
PROPSHEET_SizeMismatch(HWND hwndDlg
, PropSheetInfo
* psInfo
);
90 static BOOL
PROPSHEET_AdjustSize(HWND hwndDlg
, PropSheetInfo
* psInfo
);
91 static BOOL
PROPSHEET_AdjustButtons(HWND hwndParent
, PropSheetInfo
* psInfo
);
92 static BOOL
PROPSHEET_CollectSheetInfo(LPCPROPSHEETHEADERA lppsh
,
93 PropSheetInfo
* psInfo
);
94 static BOOL
PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEA lppsp
,
95 PropSheetInfo
* psInfo
,
97 static BOOL
PROPSHEET_CreateTabControl(HWND hwndParent
,
98 PropSheetInfo
* psInfo
);
99 static int PROPSHEET_CreatePage(HWND hwndParent
, int index
,
100 const PropSheetInfo
* psInfo
,
101 LPCPROPSHEETPAGEA ppshpage
);
102 static BOOL
PROPSHEET_ShowPage(HWND hwndDlg
, int index
, PropSheetInfo
* psInfo
);
103 static PADDING_INFO
PROPSHEET_GetPaddingInfo(HWND hwndDlg
);
104 static BOOL
PROPSHEET_Back(HWND hwndDlg
);
105 static BOOL
PROPSHEET_Next(HWND hwndDlg
);
106 static BOOL
PROPSHEET_Finish(HWND hwndDlg
);
107 static BOOL
PROPSHEET_Apply(HWND hwndDlg
, LPARAM lParam
);
108 static void PROPSHEET_Cancel(HWND hwndDlg
, LPARAM lParam
);
109 static void PROPSHEET_Help(HWND hwndDlg
);
110 static void PROPSHEET_Changed(HWND hwndDlg
, HWND hwndDirtyPage
);
111 static void PROPSHEET_UnChanged(HWND hwndDlg
, HWND hwndCleanPage
);
112 static void PROPSHEET_PressButton(HWND hwndDlg
, int buttonID
);
113 static void PROPSHEET_SetFinishTextA(HWND hwndDlg
, LPCSTR lpszText
);
114 static void PROPSHEET_SetTitleA(HWND hwndDlg
, DWORD dwStyle
, LPCSTR lpszText
);
115 static BOOL
PROPSHEET_CanSetCurSel(HWND hwndDlg
);
116 static BOOL
PROPSHEET_SetCurSel(HWND hwndDlg
,
118 HPROPSHEETPAGE hpage
);
119 static LRESULT
PROPSHEET_QuerySiblings(HWND hwndDlg
,
120 WPARAM wParam
, LPARAM lParam
);
121 static BOOL
PROPSHEET_AddPage(HWND hwndDlg
,
122 HPROPSHEETPAGE hpage
);
124 static BOOL
PROPSHEET_RemovePage(HWND hwndDlg
,
126 HPROPSHEETPAGE hpage
);
127 static void PROPSHEET_CleanUp();
128 static int PROPSHEET_GetPageIndex(HPROPSHEETPAGE hpage
, PropSheetInfo
* psInfo
);
129 static void PROPSHEET_SetWizButtons(HWND hwndDlg
, DWORD dwFlags
);
130 static PADDING_INFO
PROPSHEET_GetPaddingInfoWizard(HWND hwndDlg
);
131 static BOOL
PROPSHEET_IsDialogMessage(HWND hwnd
, LPMSG lpMsg
);
132 static INT
PROPSHEET_DoDialogBox( HWND hwnd
, HWND owner
);
135 PROPSHEET_DialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
);
137 DEFAULT_DEBUG_CHANNEL(propsheet
)
139 /******************************************************************************
140 * PROPSHEET_CollectSheetInfo
142 * Collect relevant data.
144 static BOOL
PROPSHEET_CollectSheetInfo(LPCPROPSHEETHEADERA lppsh
,
145 PropSheetInfo
* psInfo
)
147 DWORD dwSize
= min(lppsh
->dwSize
,sizeof(PROPSHEETHEADERA
));
148 DWORD dwFlags
= lppsh
->dwFlags
;
150 psInfo
->hasHelp
= dwFlags
& PSH_HASHELP
;
151 psInfo
->hasApply
= !(dwFlags
& PSH_NOAPPLYNOW
);
152 psInfo
->useCallback
= dwFlags
& PSH_USECALLBACK
;
153 psInfo
->isModeless
= dwFlags
& PSH_MODELESS
;
155 memcpy(&psInfo
->ppshheader
,lppsh
,dwSize
);
157 if (HIWORD(lppsh
->pszCaption
))
158 psInfo
->ppshheader
.pszCaption
= HEAP_strdupA( GetProcessHeap(),
159 0, lppsh
->pszCaption
);
161 psInfo
->nPages
= lppsh
->nPages
;
163 if (dwFlags
& PSH_USEPSTARTPAGE
)
165 TRACE("PSH_USEPSTARTPAGE is on");
166 psInfo
->active_page
= 0;
169 psInfo
->active_page
= lppsh
->u2
.nStartPage
;
171 if (psInfo
->active_page
< 0 || psInfo
->active_page
>= psInfo
->nPages
)
172 psInfo
->active_page
= 0;
174 psInfo
->restartWindows
= FALSE
;
175 psInfo
->rebootSystem
= FALSE
;
176 psInfo
->hImageList
= 0;
177 psInfo
->activeValid
= FALSE
;
182 /******************************************************************************
183 * PROPSHEET_CollectPageInfo
185 * Collect property sheet data.
186 * With code taken from DIALOG_ParseTemplate32.
188 BOOL
PROPSHEET_CollectPageInfo(LPCPROPSHEETPAGEA lppsp
,
189 PropSheetInfo
* psInfo
,
192 DLGTEMPLATE
* pTemplate
;
197 psInfo
->proppage
[index
].hpage
= (HPROPSHEETPAGE
)lppsp
;
198 psInfo
->proppage
[index
].hwndPage
= 0;
199 psInfo
->proppage
[index
].isDirty
= FALSE
;
202 * Process property page flags.
204 dwFlags
= lppsp
->dwFlags
;
205 psInfo
->proppage
[index
].useCallback
= dwFlags
& PSP_USECALLBACK
;
206 psInfo
->proppage
[index
].hasHelp
= dwFlags
& PSP_HASHELP
;
207 psInfo
->proppage
[index
].hasIcon
= dwFlags
& (PSP_USEHICON
| PSP_USEICONID
);
209 /* as soon as we have a page with the help flag, set the sheet flag on */
210 if (psInfo
->proppage
[index
].hasHelp
)
211 psInfo
->hasHelp
= TRUE
;
214 * Process page template.
216 if (dwFlags
& PSP_DLGINDIRECT
)
217 pTemplate
= (DLGTEMPLATE
*)lppsp
->u1
.pResource
;
220 HRSRC hResource
= FindResourceA(lppsp
->hInstance
,
221 lppsp
->u1
.pszTemplate
,
223 HGLOBAL hTemplate
= LoadResource(lppsp
->hInstance
,
225 pTemplate
= (LPDLGTEMPLATEA
)LockResource(hTemplate
);
229 * Extract the size of the page and the caption.
234 p
= (const WORD
*)pTemplate
;
236 if (((MyDLGTEMPLATEEX
*)pTemplate
)->signature
== 0xFFFF)
238 /* DIALOGEX template */
242 p
+= 2; /* help ID */
243 p
+= 2; /* ext style */
248 /* DIALOG template */
251 p
+= 2; /* ext style */
257 width
= (WORD
)*p
; p
++;
258 height
= (WORD
)*p
; p
++;
260 /* remember the largest width and height */
261 if (width
> psInfo
->width
)
262 psInfo
->width
= width
;
264 if (height
> psInfo
->height
)
265 psInfo
->height
= height
;
277 p
+= lstrlenW( (LPCWSTR
)p
) + 1;
291 p
+= lstrlenW( (LPCWSTR
)p
) + 1;
295 /* Extract the caption */
296 psInfo
->proppage
[index
].pszText
= (LPCWSTR
)p
;
297 TRACE("Tab %d %s\n",index
,debugstr_w((LPCWSTR
)p
));
298 p
+= lstrlenW((LPCWSTR
)p
) + 1;
300 if (dwFlags
& PSP_USETITLE
)
302 if ( !HIWORD( lppsp
->pszTitle
) )
306 if ( !LoadStringA( lppsp
->hInstance
, (UINT
) lppsp
->pszTitle
, szTitle
, 256 ) )
309 psInfo
->proppage
[index
].pszText
= HEAP_strdupAtoW( GetProcessHeap(),
313 psInfo
->proppage
[index
].pszText
= HEAP_strdupAtoW(GetProcessHeap(),
319 * Build the image list for icons
321 if ((dwFlags
& PSP_USEHICON
) || (dwFlags
& PSP_USEICONID
))
324 int icon_cx
= GetSystemMetrics(SM_CXSMICON
);
325 int icon_cy
= GetSystemMetrics(SM_CYSMICON
);
327 if (dwFlags
& PSP_USEICONID
)
328 hIcon
= LoadImageA(lppsp
->hInstance
, lppsp
->u2
.pszIcon
, IMAGE_ICON
,
329 icon_cx
, icon_cy
, LR_DEFAULTCOLOR
);
331 hIcon
= lppsp
->u2
.hIcon
;
335 if (psInfo
->hImageList
== 0 )
336 psInfo
->hImageList
= ImageList_Create(icon_cx
, icon_cy
, ILC_COLOR
, 1, 1);
338 ImageList_AddIcon(psInfo
->hImageList
, hIcon
);
346 /******************************************************************************
347 * PROPSHEET_DoDialogBox
349 * Copied from windows/dialog.c:DIALOG_DoDialogBox
351 static INT
PROPSHEET_DoDialogBox( HWND hwnd
, HWND owner
)
354 DIALOGINFO
* dlgInfo
;
358 /* Owner must be a top-level window */
359 owner
= WIN_GetTopParent( owner
);
360 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return -1;
361 dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
363 if (!(dlgInfo
->flags
& DF_END
)) /* was EndDialog called in WM_INITDIALOG ? */
365 EnableWindow( owner
, FALSE
);
366 ShowWindow( hwnd
, SW_SHOW
);
367 while (GetMessageA(&msg
, 0, 0, 0))
369 if (!PROPSHEET_IsDialogMessage( hwnd
, &msg
))
371 TranslateMessage( &msg
);
372 DispatchMessageA( &msg
);
374 if (dlgInfo
->flags
& DF_END
) break;
376 EnableWindow( owner
, TRUE
);
378 retval
= dlgInfo
->idResult
;
379 WIN_ReleaseWndPtr(wndPtr
);
380 DestroyWindow( hwnd
);
385 /******************************************************************************
386 * PROPSHEET_CreateDialog
388 * Creates the actual property sheet.
390 BOOL
PROPSHEET_CreateDialog(PropSheetInfo
* psInfo
)
397 WORD resID
= IDD_PROPSHEET
;
399 if (psInfo
->ppshheader
.dwFlags
& PSH_WIZARD
)
402 if(!(hRes
= FindResourceA(COMCTL32_hModule
,
403 MAKEINTRESOURCEA(resID
),
407 if(!(template = (LPVOID
)LoadResource(COMCTL32_hModule
, hRes
)))
411 * Make a copy of the dialog template.
413 resSize
= SizeofResource(COMCTL32_hModule
, hRes
);
415 temp
= COMCTL32_Alloc(resSize
);
420 memcpy(temp
, template, resSize
);
422 if (psInfo
->useCallback
)
423 (*(psInfo
->ppshheader
.pfnCallback
))(0, PSCB_PRECREATE
, (LPARAM
)temp
);
425 ret
= CreateDialogIndirectParamA(psInfo
->ppshheader
.hInstance
,
426 (LPDLGTEMPLATEA
) temp
,
427 psInfo
->ppshheader
.hwndParent
,
428 (DLGPROC
) PROPSHEET_DialogProc
,
431 if (!(psInfo
->ppshheader
.dwFlags
& PSH_MODELESS
))
432 ret
= PROPSHEET_DoDialogBox((HWND
)ret
, psInfo
->ppshheader
.hwndParent
);
439 /******************************************************************************
440 * PROPSHEET_SizeMismatch
442 * Verify that the tab control and the "largest" property sheet page dlg. template
445 static BOOL
PROPSHEET_SizeMismatch(HWND hwndDlg
, PropSheetInfo
* psInfo
)
447 HWND hwndTabCtrl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
448 RECT rcOrigTab
, rcPage
;
453 GetClientRect(hwndTabCtrl
, &rcOrigTab
);
454 TRACE("orig tab %d %d %d %d\n", rcOrigTab
.left
, rcOrigTab
.top
,
455 rcOrigTab
.right
, rcOrigTab
.bottom
);
460 rcPage
.left
= psInfo
->x
;
461 rcPage
.top
= psInfo
->y
;
462 rcPage
.right
= psInfo
->width
;
463 rcPage
.bottom
= psInfo
->height
;
465 MapDialogRect(hwndDlg
, &rcPage
);
466 TRACE("biggest page %d %d %d %d\n", rcPage
.left
, rcPage
.top
,
467 rcPage
.right
, rcPage
.bottom
);
469 if ( (rcPage
.right
- rcPage
.left
) != (rcOrigTab
.right
- rcOrigTab
.left
) )
471 if ( (rcPage
.bottom
- rcPage
.top
) != (rcOrigTab
.bottom
- rcOrigTab
.top
) )
477 /******************************************************************************
478 * PROPSHEET_IsTooSmallWizard
480 * Verify that the default property sheet is big enough.
482 static BOOL
PROPSHEET_IsTooSmallWizard(HWND hwndDlg
, PropSheetInfo
* psInfo
)
484 RECT rcSheetRect
, rcPage
, rcLine
, rcSheetClient
;
485 HWND hwndLine
= GetDlgItem(hwndDlg
, IDC_SUNKEN_LINE
);
486 PADDING_INFO padding
= PROPSHEET_GetPaddingInfoWizard(hwndDlg
);
488 GetClientRect(hwndDlg
, &rcSheetClient
);
489 GetWindowRect(hwndDlg
, &rcSheetRect
);
490 GetWindowRect(hwndLine
, &rcLine
);
492 /* Remove the space below the sunken line */
493 rcSheetClient
.bottom
-= (rcSheetRect
.bottom
- rcLine
.top
);
495 /* Remove the buffer zone all around the edge */
496 rcSheetClient
.bottom
-= (padding
.y
* 2);
497 rcSheetClient
.right
-= (padding
.x
* 2);
502 rcPage
.left
= psInfo
->x
;
503 rcPage
.top
= psInfo
->y
;
504 rcPage
.right
= psInfo
->width
;
505 rcPage
.bottom
= psInfo
->height
;
507 MapDialogRect(hwndDlg
, &rcPage
);
508 TRACE("biggest page %d %d %d %d\n", rcPage
.left
, rcPage
.top
,
509 rcPage
.right
, rcPage
.bottom
);
511 if (rcPage
.right
> rcSheetClient
.right
)
514 if (rcPage
.bottom
> rcSheetClient
.bottom
)
520 /******************************************************************************
521 * PROPSHEET_AdjustSize
523 * Resizes the property sheet and the tab control to fit the largest page.
525 static BOOL
PROPSHEET_AdjustSize(HWND hwndDlg
, PropSheetInfo
* psInfo
)
527 HWND hwndTabCtrl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
528 HWND hwndButton
= GetDlgItem(hwndDlg
, IDOK
);
530 int tabOffsetX
, tabOffsetY
, buttonHeight
;
531 PADDING_INFO padding
= PROPSHEET_GetPaddingInfo(hwndDlg
);
532 WND
* wndPtr
= WIN_FindWndPtr( hwndDlg
);
533 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
535 /* Get the height of buttons */
536 GetClientRect(hwndButton
, &rc
);
537 buttonHeight
= rc
.bottom
;
544 rc
.right
= psInfo
->width
;
545 rc
.bottom
= psInfo
->height
;
547 MapDialogRect(hwndDlg
, &rc
);
550 * Resize the tab control.
552 GetClientRect(hwndTabCtrl
,&tabRect
);
554 SendMessageA(hwndTabCtrl
, TCM_ADJUSTRECT
, FALSE
, (LPARAM
)&tabRect
);
556 if ((rc
.bottom
- rc
.top
) < (tabRect
.bottom
- tabRect
.top
))
558 rc
.bottom
= rc
.top
+ tabRect
.bottom
- tabRect
.top
;
559 psInfo
->height
= MulDiv((rc
.bottom
- rc
.top
),8,dlgInfo
->yBaseUnit
);
562 if ((rc
.right
- rc
.left
) < (tabRect
.right
- tabRect
.left
))
564 rc
.right
= rc
.left
+ tabRect
.right
- tabRect
.left
;
565 psInfo
->width
= MulDiv((rc
.right
- rc
.left
),4,dlgInfo
->xBaseUnit
);
568 SendMessageA(hwndTabCtrl
, TCM_ADJUSTRECT
, TRUE
, (LPARAM
)&rc
);
570 tabOffsetX
= -(rc
.left
);
571 tabOffsetY
= -(rc
.top
);
575 SetWindowPos(hwndTabCtrl
, 0, 0, 0, rc
.right
, rc
.bottom
,
576 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
578 GetClientRect(hwndTabCtrl
, &rc
);
580 TRACE("tab client rc %d %d %d %d\n",
581 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
583 rc
.right
+= ((padding
.x
* 2) + tabOffsetX
);
584 rc
.bottom
+= (buttonHeight
+ (3 * padding
.y
) + tabOffsetY
);
587 * Resize the property sheet.
589 SetWindowPos(hwndDlg
, 0, 0, 0, rc
.right
, rc
.bottom
,
590 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
592 WIN_ReleaseWndPtr(wndPtr
);
596 /******************************************************************************
597 * PROPSHEET_AdjustSizeWizard
599 * Resizes the property sheet to fit the largest page.
601 static BOOL
PROPSHEET_AdjustSizeWizard(HWND hwndDlg
, PropSheetInfo
* psInfo
)
603 HWND hwndButton
= GetDlgItem(hwndDlg
, IDCANCEL
);
604 HWND hwndLine
= GetDlgItem(hwndDlg
, IDC_SUNKEN_LINE
);
605 HWND hwndTabCtrl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
607 int buttonHeight
, lineHeight
;
608 PADDING_INFO padding
= PROPSHEET_GetPaddingInfoWizard(hwndDlg
);
609 WND
* wndPtr
= WIN_FindWndPtr( hwndDlg
);
610 DIALOGINFO
* dlgInfo
= (DIALOGINFO
*)wndPtr
->wExtra
;
612 /* Get the height of buttons */
613 GetClientRect(hwndButton
, &rc
);
614 buttonHeight
= rc
.bottom
;
616 GetClientRect(hwndLine
, &rc
);
617 lineHeight
= rc
.bottom
;
624 rc
.right
= psInfo
->width
;
625 rc
.bottom
= psInfo
->height
;
627 MapDialogRect(hwndDlg
, &rc
);
629 GetClientRect(hwndTabCtrl
,&tabRect
);
631 if ((rc
.bottom
- rc
.top
) < (tabRect
.bottom
- tabRect
.top
))
633 rc
.bottom
= rc
.top
+ tabRect
.bottom
- tabRect
.top
;
634 psInfo
->height
= MulDiv((rc
.bottom
- rc
.top
), 8, dlgInfo
->yBaseUnit
);
637 if ((rc
.right
- rc
.left
) < (tabRect
.right
- tabRect
.left
))
639 rc
.right
= rc
.left
+ tabRect
.right
- tabRect
.left
;
640 psInfo
->width
= MulDiv((rc
.right
- rc
.left
), 4, dlgInfo
->xBaseUnit
);
643 TRACE("Biggest page %d %d %d %d\n", rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
646 rc
.right
+= (padding
.x
* 2);
647 rc
.bottom
+= (buttonHeight
+ (5 * padding
.y
) + lineHeight
);
650 * Resize the property sheet.
652 SetWindowPos(hwndDlg
, 0, 0, 0, rc
.right
, rc
.bottom
,
653 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
655 WIN_ReleaseWndPtr(wndPtr
);
659 /******************************************************************************
660 * PROPSHEET_AdjustButtons
662 * Adjusts the buttons' positions.
664 static BOOL
PROPSHEET_AdjustButtons(HWND hwndParent
, PropSheetInfo
* psInfo
)
666 HWND hwndButton
= GetDlgItem(hwndParent
, IDOK
);
670 int buttonWidth
, buttonHeight
;
671 PADDING_INFO padding
= PROPSHEET_GetPaddingInfo(hwndParent
);
673 if (psInfo
->hasApply
)
680 * Obtain the size of the buttons.
682 GetClientRect(hwndButton
, &rcSheet
);
683 buttonWidth
= rcSheet
.right
;
684 buttonHeight
= rcSheet
.bottom
;
687 * Get the size of the property sheet.
689 GetClientRect(hwndParent
, &rcSheet
);
692 * All buttons will be at this y coordinate.
694 y
= rcSheet
.bottom
- (padding
.y
+ buttonHeight
);
697 * Position OK button.
699 hwndButton
= GetDlgItem(hwndParent
, IDOK
);
701 x
= rcSheet
.right
- ((padding
.x
+ buttonWidth
) * num_buttons
);
703 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
704 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
707 * Position Cancel button.
709 hwndButton
= GetDlgItem(hwndParent
, IDCANCEL
);
711 x
= rcSheet
.right
- ((padding
.x
+ buttonWidth
) * (num_buttons
- 1));
713 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
714 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
717 * Position Apply button.
719 hwndButton
= GetDlgItem(hwndParent
, IDC_APPLY_BUTTON
);
721 if (psInfo
->hasApply
)
724 x
= rcSheet
.right
- ((padding
.x
+ buttonWidth
) * 2);
726 x
= rcSheet
.right
- (padding
.x
+ buttonWidth
);
728 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
729 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
731 EnableWindow(hwndButton
, FALSE
);
734 ShowWindow(hwndButton
, SW_HIDE
);
737 * Position Help button.
739 hwndButton
= GetDlgItem(hwndParent
, IDHELP
);
743 x
= rcSheet
.right
- (padding
.x
+ buttonWidth
);
745 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
746 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
749 ShowWindow(hwndButton
, SW_HIDE
);
754 /******************************************************************************
755 * PROPSHEET_AdjustButtonsWizard
757 * Adjusts the buttons' positions.
759 static BOOL
PROPSHEET_AdjustButtonsWizard(HWND hwndParent
,
760 PropSheetInfo
* psInfo
)
762 HWND hwndButton
= GetDlgItem(hwndParent
, IDCANCEL
);
763 HWND hwndLine
= GetDlgItem(hwndParent
, IDC_SUNKEN_LINE
);
767 int buttonWidth
, buttonHeight
, lineHeight
, lineWidth
;
768 PADDING_INFO padding
= PROPSHEET_GetPaddingInfoWizard(hwndParent
);
774 * Obtain the size of the buttons.
776 GetClientRect(hwndButton
, &rcSheet
);
777 buttonWidth
= rcSheet
.right
;
778 buttonHeight
= rcSheet
.bottom
;
780 GetClientRect(hwndLine
, &rcSheet
);
781 lineHeight
= rcSheet
.bottom
;
784 * Get the size of the property sheet.
786 GetClientRect(hwndParent
, &rcSheet
);
789 * All buttons will be at this y coordinate.
791 y
= rcSheet
.bottom
- (padding
.y
+ buttonHeight
);
794 * Position the Next and the Finish buttons.
796 hwndButton
= GetDlgItem(hwndParent
, IDC_NEXT_BUTTON
);
798 x
= rcSheet
.right
- ((padding
.x
+ buttonWidth
) * (num_buttons
- 1));
800 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
801 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
803 hwndButton
= GetDlgItem(hwndParent
, IDC_FINISH_BUTTON
);
805 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
806 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
808 ShowWindow(hwndButton
, SW_HIDE
);
811 * Position the Back button.
813 hwndButton
= GetDlgItem(hwndParent
, IDC_BACK_BUTTON
);
817 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
818 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
821 * Position the Cancel button.
823 hwndButton
= GetDlgItem(hwndParent
, IDCANCEL
);
825 x
= rcSheet
.right
- ((padding
.x
+ buttonWidth
) * (num_buttons
- 2));
827 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
828 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
831 * Position Help button.
833 hwndButton
= GetDlgItem(hwndParent
, IDHELP
);
837 x
= rcSheet
.right
- (padding
.x
+ buttonWidth
);
839 SetWindowPos(hwndButton
, 0, x
, y
, 0, 0,
840 SWP_NOSIZE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
843 ShowWindow(hwndButton
, SW_HIDE
);
846 * Position and resize the sunken line.
849 y
= rcSheet
.bottom
- ((padding
.y
* 2) + buttonHeight
+ lineHeight
);
851 GetClientRect(hwndParent
, &rcSheet
);
852 lineWidth
= rcSheet
.right
- (padding
.x
* 2);
854 SetWindowPos(hwndLine
, 0, x
, y
, lineWidth
, 2,
855 SWP_NOZORDER
| SWP_NOACTIVATE
);
860 /******************************************************************************
861 * PROPSHEET_GetPaddingInfo
863 * Returns the layout information.
865 static PADDING_INFO
PROPSHEET_GetPaddingInfo(HWND hwndDlg
)
867 HWND hwndTab
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
870 PADDING_INFO padding
;
872 GetWindowRect(hwndTab
, &rcTab
);
877 ScreenToClient(hwndDlg
, &tl
);
885 /******************************************************************************
886 * PROPSHEET_GetPaddingInfoWizard
888 * Returns the layout information.
889 * Horizontal spacing is the distance between the Cancel and Help buttons.
890 * Vertical spacing is the distance between the line and the buttons.
892 static PADDING_INFO
PROPSHEET_GetPaddingInfoWizard(HWND hwndDlg
)
894 PADDING_INFO padding
;
897 POINT ptHelp
, ptCancel
, ptLine
;
900 hwndControl
= GetDlgItem(hwndDlg
, IDHELP
);
901 GetWindowRect(hwndControl
, &rc
);
906 ScreenToClient(hwndDlg
, &ptHelp
);
909 hwndControl
= GetDlgItem(hwndDlg
, IDCANCEL
);
910 GetWindowRect(hwndControl
, &rc
);
912 ptCancel
.x
= rc
.right
;
915 ScreenToClient(hwndDlg
, &ptCancel
);
918 hwndControl
= GetDlgItem(hwndDlg
, IDC_SUNKEN_LINE
);
919 GetWindowRect(hwndControl
, &rc
);
922 ptLine
.y
= rc
.bottom
;
924 ScreenToClient(hwndDlg
, &ptLine
);
926 padding
.x
= ptHelp
.x
- ptCancel
.x
;
927 padding
.y
= ptHelp
.y
- ptLine
.y
;
932 /******************************************************************************
933 * PROPSHEET_CreateTabControl
935 * Insert the tabs in the tab control.
937 static BOOL
PROPSHEET_CreateTabControl(HWND hwndParent
,
938 PropSheetInfo
* psInfo
)
940 HWND hwndTabCtrl
= GetDlgItem(hwndParent
, IDC_TABCONTROL
);
944 char tabtext
[MAX_TABTEXT_LENGTH
] = "Tab text";
946 item
.mask
= TCIF_TEXT
;
947 item
.pszText
= tabtext
;
948 item
.cchTextMax
= MAX_TABTEXT_LENGTH
;
950 nTabs
= psInfo
->nPages
;
953 * Set the image list for icons.
955 if (psInfo
->hImageList
)
957 SendMessageA(hwndTabCtrl
, TCM_SETIMAGELIST
, 0, (LPARAM
)psInfo
->hImageList
);
960 for (i
= 0; i
< nTabs
; i
++)
962 if ( psInfo
->proppage
[i
].hasIcon
)
964 item
.mask
|= TCIF_IMAGE
;
965 item
.iImage
= iImage
++;
969 item
.mask
&= ~TCIF_IMAGE
;
972 WideCharToMultiByte(CP_ACP
, 0,
973 (LPCWSTR
)psInfo
->proppage
[i
].pszText
,
974 -1, tabtext
, MAX_TABTEXT_LENGTH
, NULL
, NULL
);
976 SendMessageA(hwndTabCtrl
, TCM_INSERTITEMA
, (WPARAM
)i
, (LPARAM
)&item
);
982 /******************************************************************************
983 * PROPSHEET_CreatePage
987 static int PROPSHEET_CreatePage(HWND hwndParent
,
989 const PropSheetInfo
* psInfo
,
990 LPCPROPSHEETPAGEA ppshpage
)
992 DLGTEMPLATE
* pTemplate
;
995 PropPageInfo
* ppInfo
= psInfo
->proppage
;
996 PADDING_INFO padding
;
997 UINT pageWidth
,pageHeight
;
999 TRACE("index %d\n", index
);
1001 if (ppshpage
->dwFlags
& PSP_DLGINDIRECT
)
1002 pTemplate
= (DLGTEMPLATE
*)ppshpage
->u1
.pResource
;
1005 HRSRC hResource
= FindResourceA(ppshpage
->hInstance
,
1006 ppshpage
->u1
.pszTemplate
,
1008 HGLOBAL hTemplate
= LoadResource(ppshpage
->hInstance
, hResource
);
1009 pTemplate
= (LPDLGTEMPLATEA
)LockResource(hTemplate
);
1012 if (((MyDLGTEMPLATEEX
*)pTemplate
)->signature
== 0xFFFF)
1014 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
|= WS_CHILD
| DS_CONTROL
;
1015 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~DS_MODALFRAME
;
1016 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~WS_CAPTION
;
1017 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~WS_SYSMENU
;
1018 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~WS_POPUP
;
1019 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~WS_DISABLED
;
1020 ((MyDLGTEMPLATEEX
*)pTemplate
)->style
&= ~WS_VISIBLE
;
1024 pTemplate
->style
|= WS_CHILD
| DS_CONTROL
;
1025 pTemplate
->style
&= ~DS_MODALFRAME
;
1026 pTemplate
->style
&= ~WS_CAPTION
;
1027 pTemplate
->style
&= ~WS_SYSMENU
;
1028 pTemplate
->style
&= ~WS_POPUP
;
1029 pTemplate
->style
&= ~WS_DISABLED
;
1030 pTemplate
->style
&= ~WS_VISIBLE
;
1033 if (psInfo
->proppage
[index
].useCallback
)
1034 (*(ppshpage
->pfnCallback
))(hwndParent
,
1036 (LPPROPSHEETPAGEA
)ppshpage
);
1038 hwndPage
= CreateDialogIndirectParamA(ppshpage
->hInstance
,
1041 ppshpage
->pfnDlgProc
,
1044 ppInfo
[index
].hwndPage
= hwndPage
;
1046 rc
.left
= psInfo
->x
;
1048 rc
.right
= psInfo
->width
;
1049 rc
.bottom
= psInfo
->height
;
1051 MapDialogRect(hwndParent
, &rc
);
1053 pageWidth
= rc
.right
- rc
.left
;
1054 pageHeight
= rc
.bottom
- rc
.top
;
1056 if (psInfo
->ppshheader
.dwFlags
& PSH_WIZARD
)
1057 padding
= PROPSHEET_GetPaddingInfoWizard(hwndParent
);
1061 * Ask the Tab control to fit this page in.
1064 HWND hwndTabCtrl
= GetDlgItem(hwndParent
, IDC_TABCONTROL
);
1065 SendMessageA(hwndTabCtrl
, TCM_ADJUSTRECT
, FALSE
, (LPARAM
)&rc
);
1066 padding
= PROPSHEET_GetPaddingInfo(hwndParent
);
1069 SetWindowPos(hwndPage
, HWND_TOP
,
1070 rc
.left
+ padding
.x
,
1072 pageWidth
, pageHeight
, 0);
1077 /******************************************************************************
1078 * PROPSHEET_ShowPage
1080 * Displays or creates the specified page.
1082 static BOOL
PROPSHEET_ShowPage(HWND hwndDlg
, int index
, PropSheetInfo
* psInfo
)
1084 if (index
== psInfo
->active_page
)
1086 if (GetTopWindow(hwndDlg
) != psInfo
->proppage
[index
].hwndPage
)
1087 SetWindowPos(psInfo
->proppage
[index
].hwndPage
, HWND_TOP
, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
);
1091 if (psInfo
->proppage
[index
].hwndPage
== 0)
1093 LPCPROPSHEETPAGEA ppshpage
;
1096 ppshpage
= (LPCPROPSHEETPAGEA
)psInfo
->proppage
[index
].hpage
;
1097 PROPSHEET_CreatePage(hwndDlg
, index
, psInfo
, ppshpage
);
1099 psn
.hdr
.hwndFrom
= hwndDlg
;
1100 psn
.hdr
.code
= PSN_SETACTIVE
;
1104 /* Send the notification before showing the page. */
1105 SendMessageA(psInfo
->proppage
[index
].hwndPage
,
1106 WM_NOTIFY
, 0, (LPARAM
) &psn
);
1109 * TODO: check return value.
1113 if (psInfo
->active_page
!= -1)
1114 ShowWindow(psInfo
->proppage
[psInfo
->active_page
].hwndPage
, SW_HIDE
);
1116 ShowWindow(psInfo
->proppage
[index
].hwndPage
, SW_SHOW
);
1118 if (!(psInfo
->ppshheader
.dwFlags
& PSH_WIZARD
))
1122 /* Synchronize current selection with tab control */
1123 hwndTabCtrl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
1124 SendMessageA(hwndTabCtrl
, TCM_SETCURSEL
, index
, 0);
1127 psInfo
->active_page
= index
;
1128 psInfo
->activeValid
= TRUE
;
1133 /******************************************************************************
1136 static BOOL
PROPSHEET_Back(HWND hwndDlg
)
1141 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1144 if (psInfo
->active_page
< 0)
1147 psn
.hdr
.code
= PSN_WIZBACK
;
1148 psn
.hdr
.hwndFrom
= hwndDlg
;
1152 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1154 if (SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
) == -1)
1157 if (psInfo
->active_page
> 0)
1159 res
= PROPSHEET_CanSetCurSel(hwndDlg
);
1162 res
= PROPSHEET_SetCurSel(hwndDlg
, psInfo
->active_page
- 1, 0);
1169 /******************************************************************************
1172 static BOOL
PROPSHEET_Next(HWND hwndDlg
)
1176 LRESULT msgResult
= 0;
1177 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1180 if (psInfo
->active_page
< 0)
1183 psn
.hdr
.code
= PSN_WIZNEXT
;
1184 psn
.hdr
.hwndFrom
= hwndDlg
;
1188 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1190 msgResult
= SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1192 TRACE("msg result %ld\n", msgResult
);
1194 if (msgResult
== -1)
1197 if(PROPSHEET_CanSetCurSel(hwndDlg
) != FALSE
)
1199 PROPSHEET_SetCurSel(hwndDlg
, psInfo
->active_page
+ 1, 0);
1205 /******************************************************************************
1208 static BOOL
PROPSHEET_Finish(HWND hwndDlg
)
1212 LRESULT msgResult
= 0;
1213 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1216 if (psInfo
->active_page
< 0)
1219 psn
.hdr
.code
= PSN_WIZFINISH
;
1220 psn
.hdr
.hwndFrom
= hwndDlg
;
1224 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1226 msgResult
= SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1228 TRACE("msg result %ld\n", msgResult
);
1233 if (psInfo
->isModeless
)
1234 psInfo
->activeValid
= FALSE
;
1236 EndDialog(hwndDlg
, TRUE
);
1241 /******************************************************************************
1244 static BOOL
PROPSHEET_Apply(HWND hwndDlg
, LPARAM lParam
)
1250 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1253 if (psInfo
->active_page
< 0)
1256 psn
.hdr
.hwndFrom
= hwndDlg
;
1262 * Send PSN_KILLACTIVE to the current page.
1264 psn
.hdr
.code
= PSN_KILLACTIVE
;
1266 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1268 if (SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
) != FALSE
)
1272 * Send PSN_APPLY to all pages.
1274 psn
.hdr
.code
= PSN_APPLY
;
1275 psn
.lParam
= lParam
;
1277 for (i
= 0; i
< psInfo
->nPages
; i
++)
1279 hwndPage
= psInfo
->proppage
[i
].hwndPage
;
1282 msgResult
= SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1283 if (msgResult
== PSNRET_INVALID_NOCHANGEPAGE
)
1290 psInfo
->activeValid
= FALSE
;
1292 else if(psInfo
->active_page
>= 0)
1294 psn
.hdr
.code
= PSN_SETACTIVE
;
1296 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1297 SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1303 /******************************************************************************
1306 static void PROPSHEET_Cancel(HWND hwndDlg
, LPARAM lParam
)
1308 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1314 if (psInfo
->active_page
< 0)
1317 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1318 psn
.hdr
.code
= PSN_QUERYCANCEL
;
1319 psn
.hdr
.hwndFrom
= hwndDlg
;
1323 if (SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
))
1326 psn
.hdr
.code
= PSN_RESET
;
1327 psn
.lParam
= lParam
;
1329 for (i
= 0; i
< psInfo
->nPages
; i
++)
1331 hwndPage
= psInfo
->proppage
[i
].hwndPage
;
1334 SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1337 if (psInfo
->isModeless
)
1339 /* makes PSM_GETCURRENTPAGEHWND return NULL */
1340 psInfo
->activeValid
= FALSE
;
1343 EndDialog(hwndDlg
, FALSE
);
1346 /******************************************************************************
1349 static void PROPSHEET_Help(HWND hwndDlg
)
1351 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1356 if (psInfo
->active_page
< 0)
1359 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1360 psn
.hdr
.code
= PSN_HELP
;
1361 psn
.hdr
.hwndFrom
= hwndDlg
;
1365 SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1368 /******************************************************************************
1371 static void PROPSHEET_Changed(HWND hwndDlg
, HWND hwndDirtyPage
)
1374 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1377 if (!psInfo
) return;
1379 * Set the dirty flag of this page.
1381 for (i
= 0; i
< psInfo
->nPages
; i
++)
1383 if (psInfo
->proppage
[i
].hwndPage
== hwndDirtyPage
)
1384 psInfo
->proppage
[i
].isDirty
= TRUE
;
1388 * Enable the Apply button.
1390 if (psInfo
->hasApply
)
1392 HWND hwndApplyBtn
= GetDlgItem(hwndDlg
, IDC_APPLY_BUTTON
);
1394 EnableWindow(hwndApplyBtn
, TRUE
);
1398 /******************************************************************************
1399 * PROPSHEET_UnChanged
1401 static void PROPSHEET_UnChanged(HWND hwndDlg
, HWND hwndCleanPage
)
1404 BOOL noPageDirty
= TRUE
;
1405 HWND hwndApplyBtn
= GetDlgItem(hwndDlg
, IDC_APPLY_BUTTON
);
1406 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1409 if ( !psInfo
) return;
1410 for (i
= 0; i
< psInfo
->nPages
; i
++)
1412 /* set the specified page as clean */
1413 if (psInfo
->proppage
[i
].hwndPage
== hwndCleanPage
)
1414 psInfo
->proppage
[i
].isDirty
= FALSE
;
1416 /* look to see if there's any dirty pages */
1417 if (psInfo
->proppage
[i
].isDirty
)
1418 noPageDirty
= FALSE
;
1422 * Disable Apply button.
1425 EnableWindow(hwndApplyBtn
, FALSE
);
1428 /******************************************************************************
1429 * PROPSHEET_PressButton
1431 static void PROPSHEET_PressButton(HWND hwndDlg
, int buttonID
)
1435 case PSBTN_APPLYNOW
:
1436 SendMessageA(hwndDlg
, WM_COMMAND
, IDC_APPLY_BUTTON
, 0);
1439 PROPSHEET_Back(hwndDlg
);
1442 SendMessageA(hwndDlg
, WM_COMMAND
, IDCANCEL
, 0);
1445 PROPSHEET_Finish(hwndDlg
);
1448 SendMessageA(hwndDlg
, WM_COMMAND
, IDHELP
, 0);
1451 PROPSHEET_Next(hwndDlg
);
1454 SendMessageA(hwndDlg
, WM_COMMAND
, IDOK
, 0);
1457 FIXME("Invalid button index %d\n", buttonID
);
1462 /*************************************************************************
1463 * BOOL PROPSHEET_CanSetCurSel [Internal]
1465 * Test weither the current page can be changed by sending a PSN_KILLACTIVE
1468 * hwndDlg [I] handle to a Dialog hWnd
1471 * TRUE if Current Selection can change
1475 static BOOL
PROPSHEET_CanSetCurSel(HWND hwndDlg
)
1477 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1485 if (psInfo
->active_page
< 0)
1489 * Notify the current page.
1491 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
1492 psn
.hdr
.code
= PSN_KILLACTIVE
;
1493 psn
.hdr
.hwndFrom
= hwndDlg
;
1497 return !SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1500 /******************************************************************************
1501 * PROPSHEET_SetCurSel
1503 static BOOL
PROPSHEET_SetCurSel(HWND hwndDlg
,
1505 HPROPSHEETPAGE hpage
)
1507 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1510 HWND hwndHelp
= GetDlgItem(hwndDlg
, IDHELP
);
1512 /* hpage takes precedence over index */
1514 index
= PROPSHEET_GetPageIndex(hpage
, psInfo
);
1516 if (index
< 0 || index
>= psInfo
->nPages
)
1518 TRACE("Could not find page to select!\n");
1522 hwndPage
= psInfo
->proppage
[index
].hwndPage
;
1525 * Notify the new page if it's already created.
1526 * If not it will get created and notified in PROPSHEET_ShowPage.
1533 psn
.hdr
.code
= PSN_SETACTIVE
;
1534 psn
.hdr
.hwndFrom
= hwndDlg
;
1538 result
= SendMessageA(hwndPage
, WM_NOTIFY
, 0, (LPARAM
) &psn
);
1541 * TODO: check return value.
1546 * Display the new page.
1548 PROPSHEET_ShowPage(hwndDlg
, index
, psInfo
);
1550 if (psInfo
->proppage
[index
].hasHelp
)
1551 EnableWindow(hwndHelp
, TRUE
);
1553 EnableWindow(hwndHelp
, FALSE
);
1558 /******************************************************************************
1559 * PROPSHEET_SetTitleA
1561 static void PROPSHEET_SetTitleA(HWND hwndDlg
, DWORD dwStyle
, LPCSTR lpszText
)
1563 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
, PropSheetInfoStr
);
1566 if (HIWORD(lpszText
) == 0) {
1567 if (!LoadStringA(psInfo
->ppshheader
.hInstance
,
1568 LOWORD(lpszText
), szTitle
, sizeof(szTitle
)-1))
1572 if (dwStyle
& PSH_PROPTITLE
)
1575 int lentitle
= strlen(lpszText
);
1576 int lenprop
= strlen(psInfo
->strPropertiesFor
);
1578 dest
= COMCTL32_Alloc(lentitle
+ lenprop
+ 1);
1579 strcpy(dest
, psInfo
->strPropertiesFor
);
1580 strcat(dest
, lpszText
);
1582 SetWindowTextA(hwndDlg
, dest
);
1583 COMCTL32_Free(dest
);
1586 SetWindowTextA(hwndDlg
, lpszText
);
1589 /******************************************************************************
1590 * PROPSHEET_SetFinishTextA
1592 static void PROPSHEET_SetFinishTextA(HWND hwndDlg
, LPCSTR lpszText
)
1594 HWND hwndButton
= GetDlgItem(hwndDlg
, IDC_FINISH_BUTTON
);
1596 /* Set text, show and enable the Finish button */
1597 SetWindowTextA(hwndButton
, lpszText
);
1598 ShowWindow(hwndButton
, SW_SHOW
);
1599 EnableWindow(hwndButton
, TRUE
);
1601 /* Make it default pushbutton */
1602 SendMessageA(hwndDlg
, DM_SETDEFID
, IDC_FINISH_BUTTON
, 0);
1604 /* Hide Back button */
1605 hwndButton
= GetDlgItem(hwndDlg
, IDC_BACK_BUTTON
);
1606 ShowWindow(hwndButton
, SW_HIDE
);
1608 /* Hide Next button */
1609 hwndButton
= GetDlgItem(hwndDlg
, IDC_NEXT_BUTTON
);
1610 ShowWindow(hwndButton
, SW_HIDE
);
1613 /******************************************************************************
1614 * PROPSHEET_QuerySiblings
1616 static LRESULT
PROPSHEET_QuerySiblings(HWND hwndDlg
,
1617 WPARAM wParam
, LPARAM lParam
)
1621 LRESULT msgResult
= 0;
1622 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1625 while ((i
< psInfo
->nPages
) && (msgResult
== 0))
1627 hwndPage
= psInfo
->proppage
[i
].hwndPage
;
1628 msgResult
= SendMessageA(hwndPage
, PSM_QUERYSIBLINGS
, wParam
, lParam
);
1636 /******************************************************************************
1639 static BOOL
PROPSHEET_AddPage(HWND hwndDlg
,
1640 HPROPSHEETPAGE hpage
)
1642 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1644 HWND hwndTabControl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
1646 char tabtext
[MAX_TABTEXT_LENGTH
] = "Tab text";
1647 LPCPROPSHEETPAGEA ppsp
= (LPCPROPSHEETPAGEA
)hpage
;
1650 * Allocate and fill in a new PropPageInfo entry.
1652 psInfo
->proppage
= (PropPageInfo
*) COMCTL32_ReAlloc(psInfo
->proppage
,
1653 sizeof(PropPageInfo
) *
1654 (psInfo
->nPages
+ 1));
1655 if (!PROPSHEET_CollectPageInfo(ppsp
, psInfo
, psInfo
->nPages
))
1658 psInfo
->proppage
[psInfo
->nPages
].hpage
= hpage
;
1660 if (ppsp
->dwFlags
& PSP_PREMATURE
)
1662 /* Create the page but don't show it */
1663 PROPSHEET_CreatePage(hwndDlg
, psInfo
->nPages
, psInfo
, ppsp
);
1667 * Add a new tab to the tab control.
1669 item
.mask
= TCIF_TEXT
;
1670 item
.pszText
= tabtext
;
1671 item
.cchTextMax
= MAX_TABTEXT_LENGTH
;
1673 WideCharToMultiByte(CP_ACP
, 0,
1674 (LPCWSTR
)psInfo
->proppage
[psInfo
->nPages
].pszText
,
1675 -1, tabtext
, MAX_TABTEXT_LENGTH
, NULL
, NULL
);
1677 SendMessageA(hwndTabControl
, TCM_INSERTITEMA
, psInfo
->nPages
+ 1,
1682 /* If it is the only page - show it */
1683 if(psInfo
->nPages
== 1)
1684 PROPSHEET_ShowPage(hwndDlg
, 0, psInfo
);
1689 /******************************************************************************
1690 * PROPSHEET_RemovePage
1692 static BOOL
PROPSHEET_RemovePage(HWND hwndDlg
,
1694 HPROPSHEETPAGE hpage
)
1696 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwndDlg
,
1698 HWND hwndTabControl
= GetDlgItem(hwndDlg
, IDC_TABCONTROL
);
1699 PropPageInfo
* oldPages
;
1704 oldPages
= psInfo
->proppage
;
1706 * hpage takes precedence over index.
1710 index
= PROPSHEET_GetPageIndex(hpage
, psInfo
);
1713 /* Make shure that index is within range */
1714 if (index
< 0 || index
>= psInfo
->nPages
)
1716 TRACE("Could not find page to remove!\n");
1720 TRACE("total pages %d removing page %d active page %d\n",
1721 psInfo
->nPages
, index
, psInfo
->active_page
);
1723 * Check if we're removing the active page.
1725 if (index
== psInfo
->active_page
)
1727 if (psInfo
->nPages
> 1)
1731 /* activate previous page */
1732 PROPSHEET_ShowPage(hwndDlg
, index
- 1, psInfo
);
1736 /* activate the next page */
1737 PROPSHEET_ShowPage(hwndDlg
, index
+ 1, psInfo
);
1738 psInfo
->active_page
= index
;
1743 psInfo
->active_page
= -1;
1744 if (!psInfo
->isModeless
)
1746 EndDialog(hwndDlg
, FALSE
);
1751 else if (index
< psInfo
->active_page
)
1752 psInfo
->active_page
--;
1754 /* Destroy page dialog window */
1755 DestroyWindow(psInfo
->proppage
[index
].hwndPage
);
1757 /* Free page resources */
1758 if(psInfo
->proppage
[index
].hpage
)
1760 PROPSHEETPAGEA
* psp
= (PROPSHEETPAGEA
*)psInfo
->proppage
[index
].hpage
;
1762 if ((psp
->dwFlags
& PSP_USETITLE
) && psInfo
->proppage
[index
].pszText
)
1763 HeapFree(GetProcessHeap(), 0, (LPVOID
)psInfo
->proppage
[index
].pszText
);
1765 DestroyPropertySheetPage(psInfo
->proppage
[index
].hpage
);
1768 /* Remove the tab */
1769 SendMessageA(hwndTabControl
, TCM_DELETEITEM
, index
, 0);
1772 psInfo
->proppage
= COMCTL32_Alloc(sizeof(PropPageInfo
) * psInfo
->nPages
);
1775 memcpy(&psInfo
->proppage
[0], &oldPages
[0], index
* sizeof(PropPageInfo
));
1777 if (index
< psInfo
->nPages
)
1778 memcpy(&psInfo
->proppage
[index
], &oldPages
[index
+ 1],
1779 (psInfo
->nPages
- index
) * sizeof(PropPageInfo
));
1781 COMCTL32_Free(oldPages
);
1786 /******************************************************************************
1787 * PROPSHEET_SetWizButtons
1789 * This code will work if (and assumes that) the Next button is on top of the
1790 * Finish button. ie. Finish comes after Next in the Z order.
1791 * This means make sure the dialog template reflects this.
1794 static void PROPSHEET_SetWizButtons(HWND hwndDlg
, DWORD dwFlags
)
1796 HWND hwndBack
= GetDlgItem(hwndDlg
, IDC_BACK_BUTTON
);
1797 HWND hwndNext
= GetDlgItem(hwndDlg
, IDC_NEXT_BUTTON
);
1798 HWND hwndFinish
= GetDlgItem(hwndDlg
, IDC_FINISH_BUTTON
);
1800 TRACE("%ld\n", dwFlags
);
1802 EnableWindow(hwndBack
, FALSE
);
1803 EnableWindow(hwndNext
, FALSE
);
1804 EnableWindow(hwndFinish
, FALSE
);
1806 if (dwFlags
& PSWIZB_BACK
)
1807 EnableWindow(hwndBack
, TRUE
);
1809 if (dwFlags
& PSWIZB_NEXT
)
1811 /* Hide the Finish button */
1812 ShowWindow(hwndFinish
, SW_HIDE
);
1814 /* Show and enable the Next button */
1815 ShowWindow(hwndNext
, SW_SHOW
);
1816 EnableWindow(hwndNext
, TRUE
);
1818 /* Set the Next button as the default pushbutton */
1819 SendMessageA(hwndDlg
, DM_SETDEFID
, IDC_NEXT_BUTTON
, 0);
1822 if ((dwFlags
& PSWIZB_FINISH
) || (dwFlags
& PSWIZB_DISABLEDFINISH
))
1824 /* Hide the Next button */
1825 ShowWindow(hwndNext
, SW_HIDE
);
1827 /* Show the Finish button */
1828 ShowWindow(hwndFinish
, SW_SHOW
);
1830 if (dwFlags
& PSWIZB_FINISH
)
1831 EnableWindow(hwndFinish
, TRUE
);
1833 /* Set the Finish button as the default pushbutton */
1834 SendMessageA(hwndDlg
, DM_SETDEFID
, IDC_FINISH_BUTTON
, 0);
1838 /******************************************************************************
1839 * PROPSHEET_GetPageIndex
1841 * Given a HPROPSHEETPAGE, returns the index of the corresponding page from
1842 * the array of PropPageInfo.
1844 static int PROPSHEET_GetPageIndex(HPROPSHEETPAGE hpage
, PropSheetInfo
* psInfo
)
1849 while ((index
< psInfo
->nPages
) && (found
== FALSE
))
1851 if (psInfo
->proppage
[index
].hpage
== hpage
)
1863 /******************************************************************************
1866 static void PROPSHEET_CleanUp(HWND hwndDlg
)
1869 PropSheetInfo
* psInfo
= (PropSheetInfo
*) RemovePropA(hwndDlg
,
1873 if (HIWORD(psInfo
->ppshheader
.pszCaption
))
1874 HeapFree(GetProcessHeap(), 0, (LPVOID
)psInfo
->ppshheader
.pszCaption
);
1876 for (i
= 0; i
< psInfo
->nPages
; i
++)
1878 PROPSHEETPAGEA
* psp
= (PROPSHEETPAGEA
*)psInfo
->proppage
[i
].hpage
;
1880 if(psInfo
->proppage
[i
].hwndPage
)
1881 DestroyWindow(psInfo
->proppage
[i
].hwndPage
);
1885 if ((psp
->dwFlags
& PSP_USETITLE
) && psInfo
->proppage
[i
].pszText
)
1886 HeapFree(GetProcessHeap(), 0, (LPVOID
)psInfo
->proppage
[i
].pszText
);
1888 DestroyPropertySheetPage(psInfo
->proppage
[i
].hpage
);
1892 COMCTL32_Free(psInfo
->proppage
);
1893 COMCTL32_Free(psInfo
->strPropertiesFor
);
1894 ImageList_Destroy(psInfo
->hImageList
);
1896 GlobalFree((HGLOBAL
)psInfo
);
1899 /******************************************************************************
1900 * PropertySheetA (COMCTL32.84)(COMCTL32.83)
1902 INT WINAPI
PropertySheetA(LPCPROPSHEETHEADERA lppsh
)
1905 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GlobalAlloc(GPTR
,
1906 sizeof(PropSheetInfo
));
1910 PROPSHEET_CollectSheetInfo(lppsh
, psInfo
);
1912 psInfo
->proppage
= (PropPageInfo
*) COMCTL32_Alloc(sizeof(PropPageInfo
) *
1914 pByte
= (BYTE
*) psInfo
->ppshheader
.u3
.ppsp
;
1916 for (n
= i
= 0; i
< lppsh
->nPages
; i
++, n
++)
1918 if (!(lppsh
->dwFlags
& PSH_PROPSHEETPAGE
))
1919 psInfo
->proppage
[n
].hpage
= psInfo
->ppshheader
.u3
.phpage
[i
];
1922 psInfo
->proppage
[n
].hpage
= CreatePropertySheetPageA((LPCPROPSHEETPAGEA
)pByte
);
1923 pByte
+= ((LPPROPSHEETPAGEA
)pByte
)->dwSize
;
1926 if (!PROPSHEET_CollectPageInfo((LPCPROPSHEETPAGEA
)psInfo
->proppage
[n
].hpage
,
1929 if (lppsh
->dwFlags
& PSH_PROPSHEETPAGE
)
1930 DestroyPropertySheetPage(psInfo
->proppage
[n
].hpage
);
1936 bRet
= PROPSHEET_CreateDialog(psInfo
);
1941 /******************************************************************************
1942 * PropertySheetW (COMCTL32.85)
1944 INT WINAPI
PropertySheetW(LPCPROPSHEETHEADERW propertySheetHeader
)
1946 FIXME("(%p): stub\n", propertySheetHeader
);
1951 /******************************************************************************
1952 * CreatePropertySheetPageA (COMCTL32.19)(COMCTL32.18)
1954 HPROPSHEETPAGE WINAPI
CreatePropertySheetPageA(
1955 LPCPROPSHEETPAGEA lpPropSheetPage
)
1957 PROPSHEETPAGEA
* ppsp
= COMCTL32_Alloc(sizeof(PROPSHEETPAGEA
));
1959 *ppsp
= *lpPropSheetPage
;
1961 if ( !(ppsp
->dwFlags
& PSP_DLGINDIRECT
) && HIWORD( ppsp
->u1
.pszTemplate
) )
1962 ppsp
->u1
.pszTemplate
= HEAP_strdupA( GetProcessHeap(), 0, lpPropSheetPage
->u1
.pszTemplate
);
1964 if ( (ppsp
->dwFlags
& PSP_USEICONID
) && HIWORD( ppsp
->u2
.pszIcon
) )
1965 ppsp
->u2
.pszIcon
= HEAP_strdupA( GetProcessHeap(), 0, lpPropSheetPage
->u2
.pszIcon
);
1968 if ((ppsp
->dwFlags
& PSP_USETITLE
) && HIWORD( ppsp
->pszTitle
))
1969 ppsp
->pszTitle
= HEAP_strdupA( GetProcessHeap(), 0, lpPropSheetPage
->pszTitle
);
1970 else if ( !(ppsp
->dwFlags
& PSP_USETITLE
) )
1971 ppsp
->pszTitle
= NULL
;
1973 return (HPROPSHEETPAGE
)ppsp
;
1976 /******************************************************************************
1977 * CreatePropertySheetPageW (COMCTL32.20)
1979 HPROPSHEETPAGE WINAPI
CreatePropertySheetPageW(LPCPROPSHEETPAGEW lpPropSheetPage
)
1981 FIXME("(%p): stub\n", lpPropSheetPage
);
1986 /******************************************************************************
1987 * DestroyPropertySheetPage (COMCTL32.24)
1989 BOOL WINAPI
DestroyPropertySheetPage(HPROPSHEETPAGE hPropPage
)
1991 PROPSHEETPAGEA
*psp
= (PROPSHEETPAGEA
*)hPropPage
;
1996 if ( !(psp
->dwFlags
& PSP_DLGINDIRECT
) && HIWORD( psp
->u1
.pszTemplate
) )
1997 HeapFree(GetProcessHeap(), 0, (LPVOID
)psp
->u1
.pszTemplate
);
1999 if ( (psp
->dwFlags
& PSP_USEICONID
) && HIWORD( psp
->u2
.pszIcon
) )
2000 HeapFree(GetProcessHeap(), 0, (LPVOID
)psp
->u2
.pszIcon
);
2002 if ((psp
->dwFlags
& PSP_USETITLE
) && HIWORD( psp
->pszTitle
))
2003 HeapFree(GetProcessHeap(), 0, (LPVOID
)psp
->pszTitle
);
2005 COMCTL32_Free(hPropPage
);
2010 /******************************************************************************
2011 * PROPSHEET_IsDialogMessage
2013 static BOOL
PROPSHEET_IsDialogMessage(HWND hwnd
, LPMSG lpMsg
)
2015 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwnd
, PropSheetInfoStr
);
2017 if (!psInfo
|| (hwnd
!= lpMsg
->hwnd
&& !IsChild(hwnd
, lpMsg
->hwnd
)))
2020 if (lpMsg
->message
== WM_KEYDOWN
&& (GetKeyState(VK_CONTROL
) & 0x8000))
2023 INT dlgCode
= SendMessageA(lpMsg
->hwnd
, WM_GETDLGCODE
, 0, (LPARAM
)lpMsg
);
2025 if (!(dlgCode
& DLGC_WANTMESSAGE
))
2027 switch (lpMsg
->wParam
)
2030 if (GetKeyState(VK_SHIFT
) & 0x8000)
2036 case VK_NEXT
: new_page
= 1; break;
2037 case VK_PRIOR
: new_page
= -1; break;
2043 if (PROPSHEET_CanSetCurSel(hwnd
) != FALSE
)
2045 new_page
+= psInfo
->active_page
;
2048 new_page
= psInfo
->nPages
- 1;
2049 else if (new_page
>= psInfo
->nPages
)
2052 PROPSHEET_SetCurSel(hwnd
, new_page
, 0);
2059 return IsDialogMessageA(hwnd
, lpMsg
);
2062 /******************************************************************************
2063 * PROPSHEET_DialogProc
2066 PROPSHEET_DialogProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2072 PropSheetInfo
* psInfo
= (PropSheetInfo
*) lParam
;
2073 char* strCaption
= (char*)COMCTL32_Alloc(MAX_CAPTION_LENGTH
);
2074 HWND hwndTabCtrl
= GetDlgItem(hwnd
, IDC_TABCONTROL
);
2075 LPCPROPSHEETPAGEA ppshpage
;
2078 SetPropA(hwnd
, PropSheetInfoStr
, (HANDLE
)psInfo
);
2081 * psInfo->hwnd is not being used by WINE code - it exists
2082 * for compatibility with "real" Windoze. The same about
2083 * SetWindowLong - WINE is only using the PropSheetInfoStr
2086 psInfo
->hwnd
= hwnd
;
2087 SetWindowLongA(hwnd
,DWL_USER
,(LONG
)psInfo
);
2090 * Small icon in the title bar.
2092 if ((psInfo
->ppshheader
.dwFlags
& PSH_USEICONID
) ||
2093 (psInfo
->ppshheader
.dwFlags
& PSH_USEHICON
))
2096 int icon_cx
= GetSystemMetrics(SM_CXSMICON
);
2097 int icon_cy
= GetSystemMetrics(SM_CYSMICON
);
2099 if (psInfo
->ppshheader
.dwFlags
& PSH_USEICONID
)
2100 hIcon
= LoadImageA(psInfo
->ppshheader
.hInstance
,
2101 psInfo
->ppshheader
.u1
.pszIcon
,
2106 hIcon
= psInfo
->ppshheader
.u1
.hIcon
;
2108 SendMessageA(hwnd
, WM_SETICON
, 0, hIcon
);
2111 if (psInfo
->ppshheader
.dwFlags
& PSH_USEHICON
)
2112 SendMessageA(hwnd
, WM_SETICON
, 0, psInfo
->ppshheader
.u1
.hIcon
);
2114 psInfo
->strPropertiesFor
= strCaption
;
2116 GetWindowTextA(hwnd
, psInfo
->strPropertiesFor
, MAX_CAPTION_LENGTH
);
2118 PROPSHEET_CreateTabControl(hwnd
, psInfo
);
2120 if (psInfo
->ppshheader
.dwFlags
& PSH_WIZARD
)
2122 if (PROPSHEET_IsTooSmallWizard(hwnd
, psInfo
))
2124 PROPSHEET_AdjustSizeWizard(hwnd
, psInfo
);
2125 PROPSHEET_AdjustButtonsWizard(hwnd
, psInfo
);
2130 if (PROPSHEET_SizeMismatch(hwnd
, psInfo
))
2132 PROPSHEET_AdjustSize(hwnd
, psInfo
);
2133 PROPSHEET_AdjustButtons(hwnd
, psInfo
);
2137 if (psInfo
->useCallback
)
2138 (*(psInfo
->ppshheader
.pfnCallback
))(hwnd
,
2139 PSCB_INITIALIZED
, (LPARAM
)0);
2141 idx
= psInfo
->active_page
;
2142 ppshpage
= (LPCPROPSHEETPAGEA
)psInfo
->proppage
[idx
].hpage
;
2143 psInfo
->active_page
= -1;
2145 PROPSHEET_SetCurSel(hwnd
, idx
, psInfo
->proppage
[idx
].hpage
);
2147 if (!(psInfo
->ppshheader
.dwFlags
& PSH_WIZARD
))
2148 SendMessageA(hwndTabCtrl
, TCM_SETCURSEL
, psInfo
->active_page
, 0);
2150 if (!HIWORD(psInfo
->ppshheader
.pszCaption
) &&
2151 psInfo
->ppshheader
.hInstance
)
2155 if (LoadStringA(psInfo
->ppshheader
.hInstance
,
2156 (UINT
)psInfo
->ppshheader
.pszCaption
, szText
, 255))
2157 PROPSHEET_SetTitleA(hwnd
, psInfo
->ppshheader
.dwFlags
, szText
);
2161 PROPSHEET_SetTitleA(hwnd
, psInfo
->ppshheader
.dwFlags
,
2162 psInfo
->ppshheader
.pszCaption
);
2169 PROPSHEET_CleanUp(hwnd
);
2173 PROPSHEET_Cancel(hwnd
, 1);
2178 WORD wID
= LOWORD(wParam
);
2183 case IDC_APPLY_BUTTON
:
2185 HWND hwndApplyBtn
= GetDlgItem(hwnd
, IDC_APPLY_BUTTON
);
2187 if (PROPSHEET_Apply(hwnd
, wID
== IDOK
? 1: 0) == FALSE
)
2192 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwnd
,
2196 if (psInfo
->restartWindows
)
2197 result
= ID_PSRESTARTWINDOWS
;
2199 /* reboot system takes precedence over restart windows */
2200 if (psInfo
->rebootSystem
)
2201 result
= ID_PSREBOOTSYSTEM
;
2203 if (psInfo
->isModeless
)
2204 psInfo
->activeValid
= FALSE
;
2206 EndDialog(hwnd
, result
);
2209 EnableWindow(hwndApplyBtn
, FALSE
);
2214 case IDC_BACK_BUTTON
:
2215 PROPSHEET_Back(hwnd
);
2218 case IDC_NEXT_BUTTON
:
2219 PROPSHEET_Next(hwnd
);
2222 case IDC_FINISH_BUTTON
:
2223 PROPSHEET_Finish(hwnd
);
2227 PROPSHEET_Cancel(hwnd
, 0);
2231 PROPSHEET_Help(hwnd
);
2240 NMHDR
* pnmh
= (LPNMHDR
) lParam
;
2242 if (pnmh
->code
== TCN_SELCHANGE
)
2244 int index
= SendMessageA(pnmh
->hwndFrom
, TCM_GETCURSEL
, 0, 0);
2245 PROPSHEET_SetCurSel(hwnd
, index
, 0);
2248 if(pnmh
->code
== TCN_SELCHANGING
)
2250 BOOL bRet
= PROPSHEET_CanSetCurSel(hwnd
);
2251 SetWindowLongA(hwnd
, DWL_MSGRESULT
, !bRet
);
2259 case PSM_GETCURRENTPAGEHWND
:
2261 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwnd
,
2265 if (psInfo
->activeValid
&& psInfo
->active_page
!= -1)
2266 hwndPage
= psInfo
->proppage
[psInfo
->active_page
].hwndPage
;
2268 SetWindowLongA(hwnd
, DWL_MSGRESULT
, hwndPage
);
2274 PROPSHEET_Changed(hwnd
, (HWND
)wParam
);
2278 PROPSHEET_UnChanged(hwnd
, (HWND
)wParam
);
2281 case PSM_GETTABCONTROL
:
2283 HWND hwndTabCtrl
= GetDlgItem(hwnd
, IDC_TABCONTROL
);
2285 SetWindowLongA(hwnd
, DWL_MSGRESULT
, hwndTabCtrl
);
2294 msgResult
= PROPSHEET_CanSetCurSel(hwnd
);
2295 if(msgResult
!= FALSE
)
2297 msgResult
= PROPSHEET_SetCurSel(hwnd
,
2299 (HPROPSHEETPAGE
)lParam
);
2302 SetWindowLongA(hwnd
, DWL_MSGRESULT
, msgResult
);
2307 case PSM_CANCELTOCLOSE
:
2309 char buf
[MAX_BUTTONTEXT_LENGTH
];
2310 HWND hwndOK
= GetDlgItem(hwnd
, IDOK
);
2311 HWND hwndCancel
= GetDlgItem(hwnd
, IDCANCEL
);
2313 EnableWindow(hwndCancel
, FALSE
);
2314 if (LoadStringA(COMCTL32_hModule
, IDS_CLOSE
, buf
, sizeof(buf
)))
2315 SetWindowTextA(hwndOK
, buf
);
2320 case PSM_RESTARTWINDOWS
:
2322 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwnd
,
2325 psInfo
->restartWindows
= TRUE
;
2329 case PSM_REBOOTSYSTEM
:
2331 PropSheetInfo
* psInfo
= (PropSheetInfo
*) GetPropA(hwnd
,
2334 psInfo
->rebootSystem
= TRUE
;
2339 PROPSHEET_SetTitleA(hwnd
, (DWORD
) wParam
, (LPCSTR
) lParam
);
2344 BOOL msgResult
= PROPSHEET_Apply(hwnd
, 0);
2346 SetWindowLongA(hwnd
, DWL_MSGRESULT
, msgResult
);
2351 case PSM_QUERYSIBLINGS
:
2353 LRESULT msgResult
= PROPSHEET_QuerySiblings(hwnd
, wParam
, lParam
);
2355 SetWindowLongA(hwnd
, DWL_MSGRESULT
, msgResult
);
2363 * Note: MSVC++ 6.0 documentation says that PSM_ADDPAGE does not have
2364 * a return value. This is not true. PSM_ADDPAGE returns TRUE
2365 * on success or FALSE otherwise, as specified on MSDN Online.
2366 * Also see the MFC code for
2367 * CPropertySheet::AddPage(CPropertyPage* pPage).
2370 BOOL msgResult
= PROPSHEET_AddPage(hwnd
, (HPROPSHEETPAGE
)lParam
);
2372 SetWindowLongA(hwnd
, DWL_MSGRESULT
, msgResult
);
2377 case PSM_REMOVEPAGE
:
2378 PROPSHEET_RemovePage(hwnd
, (int)wParam
, (HPROPSHEETPAGE
)lParam
);
2381 case PSM_ISDIALOGMESSAGE
:
2383 BOOL msgResult
= PROPSHEET_IsDialogMessage(hwnd
, (LPMSG
)lParam
);
2384 SetWindowLongA(hwnd
, DWL_MSGRESULT
, msgResult
);
2388 case PSM_PRESSBUTTON
:
2389 PROPSHEET_PressButton(hwnd
, (int)wParam
);
2392 case PSM_SETFINISHTEXTA
:
2393 PROPSHEET_SetFinishTextA(hwnd
, (LPCSTR
) lParam
);
2396 case PSM_SETWIZBUTTONS
:
2397 PROPSHEET_SetWizButtons(hwnd
, (DWORD
)lParam
);
2401 FIXME("Unimplemented msg PSM_SETTITLE32W\n");
2403 case PSM_SETCURSELID
:
2404 FIXME("Unimplemented msg PSM_SETCURSELID\n");
2406 case PSM_SETFINISHTEXTW
:
2407 FIXME("Unimplemented msg PSM_SETFINISHTEXT32W\n");