OWLNext    7.0
Borland's Object Windows Library for the modern age
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
propsht.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------
2// ObjectWindows
3// Copyright (c) 1993, 1996 by Borland International, All Rights Reserved
4//
5/// \file
6/// Implementation of TPropertyPage and TPropertySheet classes
7//----------------------------------------------------------------------------
8#include <owl/pch.h>
9
10#include <owl/commctrl.h>
11#include <owl/propsht.h>
12#include <owl/tabctrl.h>
13#include <owl/resource.h>
14#include <owl/propsht.rh>
15#include <owl/uimetric.h>
16
17#if !defined MAXPROPPAGES
18#define MAXPROPPAGES 100
19#endif
20
21namespace owl {
22
24
25
26//----------------------------------------------------------------------------
27// TPropertySheet
28//----------------------------------------------------------------------------
29
30const uint PropSheetTimerID = 0xBACB;
32
36
38{
39
40 //
41 // Initializes the structure representing the property sheet.
42 //
44 const TWindow& w,
46 bool isWizard,
47 uint32 flags)
48 {
50 h.dwFlags= flags | (isWizard ? PSH_WIZARD : 0);
51 h.hInstance = w.GetModule()->GetHandle();
52 h.pszCaption = w.GetCaption();
53 h.nStartPage = startPage;
54 return h;
55 }
56
57} // namespace
58
59//
60/// Constructs a PropertySheet object.
61//
63 TWindow* parent,
66 bool isWizard,
67 uint32 flags,
68 TModule* module)
69:
70 TWindow(parent, title, module),
71 SubClassSheet(false),
72 WantTimer(false),
73 TimerID(0),
74 HeaderInfo(InitHeaderInfo_(*this, startPage, isWizard, flags)),
75 IsWizard(isWizard)
76{}
77
78//
79/// String-aware overload
80//
82 TWindow* parent,
83 const tstring& title,
85 bool isWizard,
86 uint32 flags,
87 TModule* module)
88:
89 TWindow(parent, title, module),
90 SubClassSheet(false),
91 WantTimer(false),
92 TimerID(0),
93 HeaderInfo(InitHeaderInfo_(*this, startPage, isWizard, flags)),
94 IsWizard(isWizard)
95{}
96
97//
98// Clean up resources used by PropertySheet object
99//
103
104//
105//
106bool
108{
109 // Set flag and let 'SetupWindow' create timer
110 //
111 WantTimer = true;
112 if (!GetHandle())
113 return true;
114
115 // Set a timer if one's not enabled already
116 //
117 if(!TimerID)
119
120 return TimerID != 0;
121}
122
123//
124/// Computes the size of the sheet, activates the designated 'startPage'
125/// and sets focus to the tab control...
126//
127void
129{
131
132 // if 'WantTimer' is enabled, start a timer
133 //
134 if (WantTimer)
135 EnableTimer();
136}
137
138//
139//
140//
141void
143{
144 // Cleanup pending timer
145 //
146 if (TimerID && KillTimer(TimerID)) {
147 TimerID = 0;
148 }
149
150 // Chain to base class' version
151 //
153}
154
155//
156// Handler for the timer event.
157// Closes the window.
158//
159void
160TPropertySheet::EvTimer(uint timerId)
161{
162 if(timerId == TimerID)
163 IdleAction(0);
164}
165
166//
167/// Updates the caption of the property sheet.
168//
169void
171{
172 // Here we'll be a little flexible and allow a call to SetCaption
173 // even before the underlying window element has been created...
174 //
175 if (GetHandle())
176 SetTitle(title, 0);
177 else
178 {
179 // TWindow's implementation will cache a copy of the caption.
180 //
182 HeaderInfo.pszCaption = GetCaption() ? GetCaption() : _T("");
183 }
184}
185
186//
187/// Brings up the property sheet modally.
188/// Returns >= 1 if changes were saved by the user (possibly ID_PSREBOOTSYSTEM or
189/// ID_PSRESTARTWINDOWS), 0 if no changes were saved by the user, and -1 if an error occurred.
190/// To retrieve extended error information, call GetLastError.
191//
192int
194{
195 return static_cast<int>(Run(true));
196}
197
198//
199/// Brings up the property sheet modelessly.
200/// Returns `true` if successful, and `false` if an error occurred.
201/// To retrieve extended error information, call GetLastError.
202//
203bool
205{
206 return Run(false) != 0;
207}
208
209//
210// Internal routine use allow each page to register the classes
211// of it's children
212//
213void
214TPropertyPage::RegisterPageChildObjects(TPropertyPage* page, void*)
215{
216 CHECK(page);
217 page->RegisterChildObjects();
218}
219
220//
221/// Brings up the property sheet by calling the Windows API function PropertySheet.
222/// For more information about the return value, see the Windows API documentation.
223/// \sa http://msdn.microsoft.com/en-us/library/windows/desktop/bb760811.aspx
224//
227{
228 // At this point our C++ parent object has (should have!) a valid HWND -
229 // hence update our Header structure
230 //
232 HeaderInfo.hwndParent = GetParentO()->GetHandle();
233
235
236 // Have each page give us its handle
237 //
238 HeaderInfo.nPages = 0;
239 HeaderInfo.phpage = pHandle;
240 GetPageHandles();
241
242 // Have each page register the window classes of it's children
243 //
244 ForEachPage(TActionPageFunc(TPropertyPage::RegisterPageChildObjects), nullptr);
245
246 // Flag modal vs. modeless sheet
247 //
248 if (modal) {
249 HeaderInfo.dwFlags &= ~PSH_MODELESS;
250 }
251 else {
252 // Subclass the control so that this window will receive
253 // button click notifications
254 //
255 EnableSubclass(true);
256 HeaderInfo.dwFlags |= PSH_MODELESS;
257 }
258
259 // Display property sheet
260 //
261 const auto r = PropertySheet(&HeaderInfo);
262 if (modal)
264 return r;
265}
266
267//
268// Internal routine used to add the page handle of a 'TPropertyPage'
269// pointer to the array of page handles stored in a PROPSHEETHEADER
270// structure.
271//
272static void
274{
275 CHECK(page);
276 CHECK(pHeader);
277 CHECK(pHeader->phpage != 0);
278 pHeader->phpage[pHeader->nPages] = page->CreatePropertyPage();
279 pHeader->nPages++;
280}
281
282//
283// Have each page of dialog hand over the page handle.
284//
285bool
286TPropertySheet::GetPageHandles()
287{
288#if defined(__TRACE) || defined(__WARN)
289 // Retrieve number of pages in this sheet's child list
290 //
291 int pageCount = GetPageCount();
292
293 // A sheet must have a least one page
294 //
297#endif
298
299 // Have each page hand over it's handle
300 //
301 ForEachPage(TActionPageFunc(fillPageInfo), &HeaderInfo);
302
303#if defined(__TRACE) || defined(__WARN)
304 // Double check count
305 //
306 CHECK(pageCount == static_cast<int>(HeaderInfo.nPages));
307#endif
308 return true;
309}
310
311//
312/// Applies the specified 'action' function to each TPropertyPage child of the
313/// sheet.
314/// \note The logic here traverses the TPropertySheet's ChildList. Therefore
315/// we will miss any page that does not have an associated TPropertyPage
316/// inserted in the sheet's ChildList.
317void
333
334//
335/// Applies the specified 'test' function to each 'TPropertyPage' of the sheet and
336/// returns the first page which causes the 'test' function to return true. Returns
337/// '0' if no page meets the condition.
338//
341{
342 if (GetLastChild()) {
346 do {
348 nextChild = nextChild->Next();
350 if (curPage) {
351 if (test(curPage, paramList))
352 return curPage;
353 }
354 } while (curChild != GetLastChild() && GetLastChild() != nullptr);
355 }
356 return nullptr;
357}
358
359//
360// Internal callback used to count the number of pages within
361// a Property Sheet.
362//
363static void
364countPages(TPropertyPage* /*page*/, int* pCount)
365{
366 (*pCount)++;
367}
368
369//
370/// Retrieves the number of pages within a particular sheet.
371//
372int
374{
375 int pageCount = 0;
377 this)->ForEachPage(TActionPageFunc(countPages), &pageCount);
378 return pageCount;
379}
380
381//
382// Updates the 'HWINDOW' data member of the PropertySheet Object.
383// NOTE: This method is called from the InitHandle method of a
384// page of the sheet.
385//
386void
387TPropertySheet::InitHandle(THandle sheetHandle)
388{
392
393 // When using the system's underlying implementation of PropertySheet
394 // should we subclass the Sheet or should be it be treated as a black
395 // box? Ideally the Sheet is this abstract container and we're only
396 // concerned with our pages [dialogs]. However, there are scenarios where
397 // we might want to subclass it. For example, if the sheet is used as a
398 // client of a framewindow and 'ShrinkToClient' is enabled, we'll need to
399 // detect when the sheet is resized (i.e. receiving WM_SIZE messages) to
400 // allow the frame to adjust.
401 //
402 if (SubClassSheet) {
404 GetHWndState(true);
405 }
406
407 // Here we must explicitly set up the window - The typical OWL run-through
408 // (i.e. setup invoked off WM_CREATE) fails in this case since
409 // the sheet is created indirectly.
410 //
412}
413
414//
415/// Adds a new page to the end of the PropertySheet.
416/// \note The 'pg' must have been created via a call to
417/// 'TPropertyPage::CreatePropertyPage' before invoking the 'AddPage' method.
418/// \note The property sheet is not resized to fit the new page. The new page should
419/// be no larger than the largest page already in the property sheet.
420//
421void
423{
424 // Update pointer to parent object
425 //
426 if (pg.GetParentO() != this)
427 pg.SetParent(this);
428
429 // Have page create itself it necessary
430 //
431 pg.CreatePropertyPage();
433
434 // Inform sheet about new page
435 //
436 CHECK(HWND(*this));
438}
439
440
441//
442/// Simulates the choice of the Apply button, indicating that one or more pages have
443/// changed and the changes need to be validated or recorded. The property sheet
444/// sends the PSN_KILLACTIVE notification message to the current page. If the
445/// current page returns FALSE, the propertysheet sends the PSN_APPLY notification
446/// message to all pages. Returns true if all pages successfully applied the
447/// changes, or false otherwise.
448//
449bool
451{
452 CHECK(HWND(*this));
453 return SendMessage(PSM_APPLY) != 0;
454}
455
456//
457/// Disables the 'Cancel' button and changes the text of the 'OK' button to 'Close'.
458/// You must invoke this method after applying a change that cannot be canceled.
459//
460void
466
467//
468/// Informs the sheet that information in a sheet has changed. The sheet enables the
469/// 'Apply' button.
470//
471void
477
478//
479// Retrieves the handle to the window of the current page of the sheet.
480//
481HWND
487
488//
489/// Retrieves the handle to a tab control of a property sheet.
490//
491HWND
498
499//
500/// Passes a message to a property sheet dialog box and indicates whether the dialog
501/// processed the message. Returns true if the message was processed or false
502/// otherwise.
503//
504bool
510
511//
512/// Simulates the choice of a property sheet button. The button parameter can be one
513/// of the following:
514/// - \c \b PSBTN_APPLYNOW Apply Now button.
515/// - \c \b PSBTN_BACK Back button.
516/// - \c \b PSBTN_CANCEL Cancel button.
517/// - \c \b PSBTN_FINISH Finish button.
518/// - \c \b PSBTN_HELP Help button.
519/// - \c \b PSBTN_NEXT Next button.
520/// - \c \b PSBTN_OK OK button
521//
522void
528
529
530//
531/// Forwards the 'PSM_QUERYSIBLINGS' message to each page in the property sheet. If
532/// a page returns a nonzeroe value, the property sheet does not send the message to
533/// subsequent pages. Returns the nonzero value from a page in the property sheet,
534/// or zero if no page returns a nonzero value.
535//
536int
542
543//
544/// Indicates that the system needs to be restarted for the changes to take effect.
545/// You should invoke this method only in response to the PSN_APPLY or
546/// PSN_KILLACTIVE notifications.
547/// \note It's your responsibility to reboot the system (via ExitWindowEx, for
548/// example).
549/// \note Invoking this method causes the TPropertySheet::Execute method to return
550/// ID_PSREBOOTSYSTEM.
551//
552void
558
559//
560/// Removes the specified page from the property sheet
561//
562void
564{
566 CHECK(GetHandle());
568 //
569 // Should we actually invoke 'DestroyPropertySheetPage' for
570 // Pages which are added then removed from the PropertySheet??
571}
572
573//
574/// Removes the page at the specified index from the property sheet
575//
576void
578{
579 CHECK(GetHandle());
581 //
582 // Should we actually invoke 'DestroyPropertySheetPage' for
583 // Pages which are added then removed from the PropertySheet??
584}
585
586//
587/// Indicates that the system needs to be restarted for the changes to take effect.
588/// You should invoke this method only in response to the PSN_APPLY or
589/// PSN_KILLACTIVE notifications.
590/// \note It's your responsibility to reboot the system [via ExitWindowEx for
591/// example].
592/// \note Invoking this method causes the TPropertySheet::Execute method to return
593/// ID_PSRESTARTWINDOWS.
594//
595void
601
602//
603/// Activates the specified page in the property sheet. Returns true if successful
604/// or false otherwise.
605/// \note The page that's losing activation receives a PSN_KILLACTIVE notification
606/// while the window that's gaining activation receives a PSN_SETACTIVE
607/// notification.
608//
609bool
616
617//
618/// Activates the page at the specified index in the property sheet. Returns true if
619/// successful or false otherwise.
620/// \note The page that's losing activation receives a PSN_KILLACTIVE notification
621/// while the window that's gaining activation receives a PSN_SETACTIVE
622/// notification.
623//
624bool
630
631//
632/// Activates the page with the specified resource identifier. Returns true if
633/// successful or false otherwise.
634/// \note The page that's losing activation receives a PSN_KILLACTIVE notification
635/// while the window that's gaining activation receives a PSN_SETACTIVE
636/// notification.
637//
638bool
644
645//
646/// Sets the text for the 'Finish' button in a Wizard property sheet.
647/// \note The button is enabled while the 'Next' and 'Back' buttons are hidden.
648//
649void
655
656//
657/// Sets the title of a property sheet. If 'style' parameter is the PSH_PROPTITLE
658/// value, the prefix "Properties of" is included with the specified title ('txt')
659/// parameter.
660//
661void
667
668//
669// Enables the 'Back', 'Next' or 'Finish' button in a wizard
670// property sheet. The 'flags' parameter can be a combination of
671// the following values:
672//
673// PSWIZB_BACK Back button
674// PSWIZB_NEXT Next button
675// PSWIZB_FINISH Finish button
676//
677void
683
684//
685/// Informs the sheet that the information in the specified page has reverted to the
686/// previously saved state. The sheet disables the 'Apply' button if no other pages
687/// have registered changes with the property sheet.
688//
689void
696
697//
698//
699//
700bool
702
703 // If current page = 0, then it's time to close the property sheet.
704 //
706 if (!page) {
707 CloseWindow();
708 return false;
709 }
710 else {
712 }
713}
714
715
716// ---------------------------------------------------------------------------
717// TPropertyPage
718// ---------------------------------------------------------------------------
719
723 EV_PSN_KILLACTIVE(KillActive),
730 EV_PSN_QUERYCANCEL(QueryCancel),
732
733//
734/// Constructor for TPropertyPage
735//
736//
739 TModule* module)
740
741:
742 TDialog(parent, resId, module),
743 HPropPage(nullptr)
744{
745 // Initialize the PROPSHEETPAGE structure
746 // NOTE: We're storing the 'this' pointer in the application-defined
747 // section of the PROPSHEETPAGE structure...
748 //
749 memset(&PageInfo, 0, sizeof(PageInfo));
750 PageInfo.dwSize = sizeof(PROPSHEETPAGE);
751 PageInfo.dwFlags= PSP_DEFAULT;
752 PageInfo.pszTemplate = resId;
753 PageInfo.hInstance = *GetModule();
754
755 if (title)
757 if (iconRes)
759
760 PageInfo.dwFlags |= PSP_USECALLBACK;
761 PageInfo.pfnCallback = PropCallback;
762 PageInfo.pfnDlgProc = PropDlgProc;
763 PageInfo.lParam = LPARAM(this);
764}
765
766//
767/// String-aware overload
768//
769//
771 const tstring& title, TResId iconRes,
772 TModule* module)
773
774:
775 TDialog(parent, resId, module),
776 HPropPage(nullptr)
777{
778 // Initialize the PROPSHEETPAGE structure
779 // NOTE: We're storing the 'this' pointer in the application-defined
780 // section of the PROPSHEETPAGE structure...
781 //
782 memset(&PageInfo, 0, sizeof(PageInfo));
783 PageInfo.dwSize = sizeof(PROPSHEETPAGE);
784 PageInfo.dwFlags= PSP_DEFAULT;
785 PageInfo.pszTemplate = resId;
786 PageInfo.hInstance = *GetModule();
787
789 if (iconRes)
791
792 PageInfo.dwFlags |= PSP_USECALLBACK;
793 PageInfo.pfnCallback = PropCallback;
794 PageInfo.pfnDlgProc = PropDlgProc;
795 PageInfo.lParam = LPARAM(this);
796}
797
798//
799// !BB TDialog should probably support LPCDLGTEMPLATE in 32-bit to
800// allow proper support of the following constructor...
801//
802/// Constructor to create a property page object using the information stored in the
803/// "pgInfo" parameter.
804//
806 const PROPSHEETPAGE& pgInfo,
807 TModule* module)
808:
809 TDialog(parent, *pgInfo.pResource, NoAutoDelete, module),
810 HPropPage(nullptr)
811{
812
813 // Initialize the PROPSHEETPAGE structure
814 // NOTE: We're storing the 'this' pointer in the application-defined
815 // section of the PROPSHEETPAGE structure...
817 PageInfo.dwSize = sizeof(PROPSHEETPAGE);
818 PageInfo.hInstance = *GetModule();
819 PageInfo.dwFlags |= PSP_USECALLBACK;
820 PageInfo.pfnCallback = PropCallback;
821 PageInfo.pfnDlgProc = PropDlgProc;
822 PageInfo.lParam = LPARAM(this);
823}
824
825
826
827//
828/// Destructor of TPropertyPage. Cleans up allocated buffers used when ObjectWindows
829/// provides implementation of property pages.
830//
833
834//
835/// Specifies flags to be used in creating the property page. These
836/// are the flags that belong in PROPSHEETPAGE.dwFlags. If used, this
837/// method should be called immediately after the TPropertyPage is
838/// constructed.
839//
840void
842{
843 PageInfo.dwFlags = flags;
844}
845
846//
847/// Specifies the icon to be used for this page.
848/// \note This routine must be invoked before the page is created.
849//
850void
852{
853 PageInfo.hIcon = icon;
854 PageInfo.dwFlags &= ~PSH_USEICONID;
855 PageInfo.dwFlags |= PSH_USEHICON;
856}
857
858//
859/// Specifies the icon to be used for this page.
860/// \note This routine must be invoked before the page is created.
861//
862void
864{
865 PageInfo.pszIcon = iconResId;
866 PageInfo.dwFlags &= ~PSH_USEHICON;
867 PageInfo.dwFlags |= PSH_USEICONID;
868}
869
870//
871/// Sets the caption of this page.
872/// \note This routine must be invoked before the page is created.
873//
874void
876{
877 // Let TWindow make a copy of the title.
878 // Then point to the 'duped' copy...
879 //
881 PageInfo.pszTitle = GetCaption();
882 PageInfo.dwFlags |= PSP_USETITLE;
883}
884
885//
886/// Sets the caption of this page.
887/// \note This routine must be invoked before the page is created.
888//
889void
895
896//
897/// WM_NOTIFY handler: Scans for property sheet notifications to 'patch' the
898/// 'idFrom' member to the predefined 'PropPageID'.
899/// \note This is necessary because WM_NOTIFY subdispatching relies on the ID of
900/// the sender.
901//
904{
905 if (notifyInfo.code <= static_cast<uint>(PSN_FIRST) && notifyInfo.code >= static_cast<uint>(PSN_LAST)){
906 // Property sheet notifications require special handling since the
907 // concept of ctlId is non-existent. We patch it to the default
908 // PageID expected by the ObjectWindows Property Page dispatchers
909 //
910 notifyInfo.idFrom = PropPageID;
911 id = PropPageID;
912
913 // Also make sure we don't reflect the message back to what looks like
914 // the 'child' sender but is really the sheet. We achieve this by
915 // NULLing out the HWND of the sender.
916 //
917 notifyInfo.hwndFrom = nullptr;
918 }
919 return TDialog::EvNotify(id, notifyInfo);
920}
921
922//
923// Handle case of Escape from Edit control with ES_MULTILINE style
924//
926{
927 tchar szClass[10];
928 HWND hWnd = ::GetFocus();
930 ::GetClassName(hWnd, szClass, 10) && lstrcmpi(szClass, _T("EDIT")) == 0){
932 }
934}
935
936//
937/// This callback is the default 'Dialog box procedure' of each page of our
938/// property sheet....
939//
942{
943 switch(msg) {
944 case WM_INITDIALOG: {
945 // Attach C++ object with it's underlying handle if necessary
946 //
948 InitHandle(hDlg, pageInfo);
949 }
950 break;
951
952 case WM_NOTIFY: {
954 if (notifyInfo.code<=static_cast<uint>(PSN_FIRST) && notifyInfo.code>=static_cast<uint>(PSN_LAST)){
955 // Property sheet notifications require special handling
956 // since the concept of ctlId is non-existent. We patch it
957 // to the default PageID expected by the ObjectWindows
958 // Property Page dispatchers
959 //
960 notifyInfo.idFrom = PropPageID;
962 }
963 }
964 break;
965
966 default:
967 break;
968 }
970}
971
972//
973/// As with TDialog, most of the page's events are dispatched directly from the
974/// window procedure. Although the Sheet has each page's DialogProc, the notifications
975/// are not (or don't seem to be) funneled directly to the dialogProc.
976//
979{
980 switch(msg) {
981 case WM_NOTIFY: {
982 NMHDR& nmhdr = *(REINTERPRET_CAST(NMHDR *, p2));
983 if (nmhdr.code >= static_cast<uint>(PSN_LAST) && nmhdr.code <= static_cast<uint>(PSN_FIRST)) {
984 CHECK(p1 != 0);
985 CHECK(nmhdr.idFrom != 0);
986 }
987 }
988 break;
989
990 default:
991 break;
992 }
994}
995
996// 'CopyPageInfo' is called by the 'Sheet' object requesting
997// the page to fill out a 'PROPSHEETPAGE' structure which
998// describes the attribute of the page.
999//
1000void
1005
1006//
1007/// CreatePropertyPage is called by the Sheet object requesting the page to return a
1008/// handle used to represent this dialog when it's inserted into the Sheet.
1009//
1017
1018//
1019/// Destroys the page represented by this object.
1020//
1021bool
1023{
1026 HPropPage= nullptr;
1027 return true;
1028 }
1029 return false;
1030}
1031
1032//
1033/// Creates the page.
1034//
1035bool
1037{
1038 // When using the system's implementation if PropertyDialogs, the page
1039 // is actually created behind the scene when the PropertySheet is
1040 // created. The callbacks specified by ObjectWindows [PropDlgProc &
1041 // PropCallback] will update the TPropertyPage's HWindow data member.
1042 //
1043 // Therefore, our 'Create' method simply checks that the handle was
1044 // indeed initialized and happily returns true.
1045 //
1046 CHECK(GetHandle() != 0);
1047 return true;
1048}
1049
1050/// Method that ties the C++ object presenting the page with the underlying 'HWND'
1051//
1052/// The pages of a propertysheet are created internally by windows...
1053/// Consequently, we must attempt to grab and thunk the 'HWND' as
1054/// early as possible. There are two basic opportunities to do so:
1055///
1056/// (a) A Sheet can provide a callback which is called whenever a
1057/// page is created or released. Hence 'TPropertyPage::PropCallback'
1058/// invokes 'InitHandle'.
1059///
1060/// (b) Each page provides a dialog-procedure callback. Hence,
1061/// 'TPropertyPage::PropDlgProc' invokes 'InitHandle' upon receiving
1062/// a WM_INITDIALOG message.
1063//
1064void
1065TPropertyPage::InitHandle(THandle pageHandle, LPPROPSHEETPAGE ppsp)
1066{
1067 // First check that the lParam data member of the PROPSHEETPAGE
1068 // contains a 'this' pointer to an OWL TPropertyPage object
1069 // wrapping the dialog
1070 //
1072
1073 if (page && pageHandle) {
1074 // Only proceed if the C++ object is not fully initialized
1075 //
1076 if (page->GetHandle()) {
1077 CHECK(page->GetHandle() == pageHandle);
1078 return;
1079 }
1080
1081 // Proceed to initialize the handle of the page object.
1082 //
1083 page->SetHandle(pageHandle);
1084
1085 // We can now retrieve the pointer to the sheet object
1086 // and initialize the latter if necessary.
1087 //
1088 TPropertySheet* sheet = page->GetSheet();
1089 if (sheet) {
1090 if (!sheet->GetHandle()) {
1092 if (sheetHandle)
1093 sheet->InitHandle(sheetHandle);
1094 }
1095 }
1096
1097 // Allow OWL to thunk the page window.
1098 //
1099 page->SubclassWindowFunction();
1100
1101 // NOTE: Typically, we'd call 'GetHWndState', 'PerformDlgInit',
1102 // and 'PerformSetupAndTransfer' after
1103 // thunking a window. However, TDialog's 'EvInitDialog'
1104 // method [invoked via the PropDlgProc callback] will
1105 // handle that.
1106 }
1107}
1108
1109//
1110// Static callback invoked whenever a Property Page is created is
1111// destroyed.
1112//
1115{
1116 switch (uMsg) {
1117 case PSPCB_CREATE: {
1118
1119 // A Property Page was just created.. We'll attempt to thunk
1120 // the underlying 'HWND' if it was specified..
1121 //
1122 if (hwnd)
1123 InitHandle(hwnd, ppsp);
1124 }
1125 break;
1126
1127 case PSPCB_RELEASE: {
1128
1129 // A Property Page was just released... Currently, we
1130 // don't have any processing to do here....
1131 // Should we invoke a virtual method of TPropertyPage
1132 // from here - just in case a page needs to do something
1133 // when it's released or are the default ObjectWindows
1134 // mechanisms (CleanupWindow & Destructor) sufficient....
1135 //
1136 }
1137 break;
1138
1139 default:
1140 break;
1141 }
1142 // The return is ignored for PSPCB_RELEASE (according to the doc).
1143 // A non-zero value allows the page to be created...
1144 //
1145 return 1;
1146}
1147
1148
1149// Default implementation of PropertySheet notifications.. Derived classes
1150// will override - most likely.
1151//
1152
1153//
1154/// Virtual methods to handle the Sheet notifications: PSN_APPLY
1155//
1156int
1158{
1159 // Check if it's OK to close and attempt to retrieve data
1160 //
1161 try
1162 {
1163 if (CanClose())
1164 {
1166 return PSNRET_NOERROR;
1167 }
1168 }
1169 catch (TXOwl& x)
1170 {
1171 int MessageLoopResult = x.Unhandled(GetModule(), IDS_OKTORESUME);
1172 if (MessageLoopResult != 0)
1173 {
1174 ::PostQuitMessage(MessageLoopResult);
1175 }
1176
1177 return PSNRET_NOERROR;
1178 }
1179
1180 // It's not OK to proceed - return focus to this page
1181 //
1183}
1184
1185//
1186/// Virtual methods to handle the Sheet notifications: PSN_KILLACTIVE
1187//
1188bool
1190{
1191 return false;
1192}
1193
1194//
1195/// Virtual methods to handle the Sheet notifications: PSN_APPLY
1196//
1197void
1201
1202//
1203/// This virtual function is called when a user exits a property sheet by clicking
1204/// the Cancel button. By default, Reset() does nothing, but it can be overridden.
1205/// Virtual methods to handle the Sheet notifications: PSN_RESET
1206//
1207void
1211
1212//
1213/// Virtual methods to handle the Sheet notifications: PSN_SETACTIVE
1214//
1215int
1217{
1218 return 0;
1219}
1220
1221//
1222/// Virtual methods to handle the Sheet notifications: PSN_WIZBACK
1223//
1224int
1226{
1227 return 0;
1228}
1229
1230//
1231/// Virtual methods to handle the Sheet notifications: PSN_FINISH
1232//
1233bool
1235{
1236 return false;
1237}
1238
1239//
1240/// Virtual methods to handle the Sheet notifications: PSN_WIZNEXT
1241//
1242int
1244{
1245 return 0;
1246}
1247
1248//
1249/// Virtual methods to handle the Sheet notifications: PSN_QUERYCANCEL
1250//
1251bool
1253{
1254 return false;
1255}
1256
1257
1258} // OWL namespace
1259/* ========================================================================== */
1260
#define CHECK(condition)
Definition checks.h:239
#define PRECONDITION(condition)
Definition checks.h:227
void ResumeThrow()
Rethrows the suspended exception stored by a previous call to SuspendThrow.
Typically used to obtain information from a user, a dialog box is a window inside of which other cont...
Definition dialog.h:85
void EvClose()
Message response function for WM_CLOSE by unconditionally closing the window.
Definition dialog.cpp:933
virtual INT_PTR DialogFunction(TMsgId, TParam1, TParam2)
Override this to process messages within the dialog function.
Definition dialog.cpp:353
static INT_PTR CALLBACK StdDlgProc(HWND, UINT, WPARAM, LPARAM) noexcept
Callback procs for hooking TDialog to native window.
Definition dialog.cpp:440
TIcon, derived from TGdiObject, represents the GDI object icon class.
Definition gdiobjec.h:670
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Definition module.h:75
TNotify is a thin wrapper around the NMHDR structure.
Definition commctrl.h:91
The 'TPropertyPage' object represents a dialog box found within a property sheet.
Definition propsht.h:60
HPROPSHEETPAGE HPropPage
Handle of this property page.
Definition propsht.h:150
virtual void Reset(TPshNotify &)
PSN_RESET.
Definition propsht.cpp:1208
virtual int Apply(TPshNotify &)
PSN_APPLY.
Definition propsht.cpp:1157
virtual int WizNext(TPshNotify &)
PSN_WIZNEXT.
Definition propsht.cpp:1243
HPROPSHEETPAGE CreatePropertyPage()
CreatePropertyPage is called by the Sheet object requesting the page to return a handle used to repre...
Definition propsht.cpp:1011
virtual bool KillActive(TPshNotify &)
PSN_KILLACTIVE.
Definition propsht.cpp:1189
virtual bool WizFinish(TPshNotify &)
PSN_WIZFINISH.
Definition propsht.cpp:1234
friend class TPropertySheet
Definition propsht.h:206
virtual void Help(TPshNotify &)
PSN_HELP.
Definition propsht.cpp:1198
void SetIcon(const TIcon &)
Specifies the icon to be used for this page.
Definition propsht.cpp:851
bool DestroyPropertyPage()
Destroys the page represented by this object.
Definition propsht.cpp:1022
PROPSHEETPAGE PageInfo
Following structure holds information about this dialog when it is inserted into a PropertySheet.
Definition propsht.h:146
static INT_PTR CALLBACK PropDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
This callback is the default 'Dialog box procedure' of each page of our property sheet....
Definition propsht.cpp:941
auto DialogFunction(TMsgId, TParam1, TParam2) -> INT_PTR override
As with TDialog, most of the page's events are dispatched directly from the window procedure.
Definition propsht.cpp:978
void CopyPageInfo(PROPSHEETPAGE &pgInfo) const
Definition propsht.cpp:1001
void SetFlags(uint32 flags)
Specifies flags to be used in creating the property page.
Definition propsht.cpp:841
virtual int WizBack(TPshNotify &)
PSN_WIZBACK.
Definition propsht.cpp:1225
auto Create() -> bool override
Creates the page.
Definition propsht.cpp:1036
auto EvNotify(uint id, TNotify &) -> TResult override
WM_NOTIFY handler: Scans for property sheet notifications to 'patch' the 'idFrom' member to the prede...
Definition propsht.cpp:903
static UINT CALLBACK PropCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
Definition propsht.cpp:1114
void SetTitle(LPCTSTR)
Sets the caption of this page.
Definition propsht.cpp:875
virtual int SetActive(TPshNotify &)
PSN_SETACTIVE.
Definition propsht.cpp:1216
virtual bool QueryCancel(TPshNotify &)
PSN_QUERYCANCEL.
Definition propsht.cpp:1252
TPropertyPage(TPropertySheet *parent, TResId resId, LPCTSTR title=0, TResId iconRes=0, TModule *module=0)
Constructor for TPropertyPage.
Definition propsht.cpp:737
~TPropertyPage() override
Destructor of TPropertyPage.
Definition propsht.cpp:831
TPropertySheet encapsulates a window which contains one or more overlapping child windows knowns as p...
Definition propsht.h:218
bool SubClassSheet
Should we subclass the sheet (OS only)
Definition propsht.h:313
HWND GetTabControl() const
Retrieves the handle to a tab control of a property sheet.
Definition propsht.cpp:492
void PageUnchanged(TPropertyPage &)
Informs the sheet that the information in the specified page has reverted to the previously saved sta...
Definition propsht.cpp:690
INT_PTR Run(bool modal)
Brings up the property sheet by calling the Windows API function PropertySheet.
Definition propsht.cpp:226
void SetWizButtons(uint32 flags)
Definition propsht.cpp:678
bool WantTimer
Flags whether to start a timer.
Definition propsht.h:314
TPropertyPage * FirstPageThat(TCondPageFunc cond, void *paramList=0)
Applies the specified 'test' function to each 'TPropertyPage' of the sheet and returns the first page...
Definition propsht.cpp:340
void SetCaption(LPCTSTR title)
Updates the caption of the property sheet.
Definition propsht.cpp:170
auto Execute() -> int override
Brings up the property sheet modally.
Definition propsht.cpp:193
void CancelToClose()
Disables the 'Cancel' button and changes the text of the 'OK' button to 'Close'.
Definition propsht.cpp:461
UINT_PTR TimerID
Timer identifier.
Definition propsht.h:315
int QuerySiblings(TParam1, TParam2)
Forwards the 'PSM_QUERYSIBLINGS' message to each page in the property sheet.
Definition propsht.cpp:537
int GetPageCount() const
Retrieves the number of pages within a particular sheet.
Definition propsht.cpp:373
void EnableSubclass(bool subclass)
Definition propsht.h:478
bool Apply()
Simulates the choice of the Apply button, indicating that one or more pages have changed and the chan...
Definition propsht.cpp:450
void SetupWindow() override
Computes the size of the sheet, activates the designated 'startPage' and sets focus to the tab contro...
Definition propsht.cpp:128
auto Create() -> bool override
Brings up the property sheet modelessly.
Definition propsht.cpp:204
HWND GetCurrentPage() const
Definition propsht.cpp:482
void ForEachPage(TActionPageFunc action, void *paramList=0)
Applies the specified 'action' function to each TPropertyPage child of the sheet.
Definition propsht.cpp:318
bool SelectPage(TPropertyPage &)
Activates the specified page in the property sheet.
Definition propsht.cpp:610
void AddPage(TPropertyPage &)
Adds a new page to the end of the PropertySheet.
Definition propsht.cpp:422
TPropertySheet(TWindow *parent, LPCTSTR title, uint startPage=0, bool isWizard=false, uint32 flags=PSH_DEFAULT, TModule *module=0)
Constructs a PropertySheet object.
Definition propsht.cpp:62
void SetTitle(LPCTSTR text, uint32 style=PSH_PROPTITLE)
Sets the title of a property sheet.
Definition propsht.cpp:662
void CleanupWindow() override
Definition propsht.cpp:142
PROPSHEETHEADER HeaderInfo
Definition propsht.h:319
void RestartWindows()
Indicates that the system needs to be restarted for the changes to take effect.
Definition propsht.cpp:596
void PressButton(int button)
Simulates the choice of a property sheet button.
Definition propsht.cpp:523
auto PreProcessMsg(MSG &) -> bool override
Definition propsht.cpp:701
bool IsDialogMessage(MSG &msg)
Passes a message to a property sheet dialog box and indicates whether the dialog processed the messag...
Definition propsht.cpp:505
void SetFinishText(LPCTSTR text)
Sets the text for the 'Finish' button in a Wizard property sheet.
Definition propsht.cpp:650
void RebootSystem()
Indicates that the system needs to be restarted for the changes to take effect.
Definition propsht.cpp:553
void RemovePage(TPropertyPage &)
Removes the specified page from the property sheet.
Definition propsht.cpp:563
~TPropertySheet() override
Definition propsht.cpp:100
void PageChanged(const TPropertyPage &)
Informs the sheet that information in a sheet has changed.
Definition propsht.cpp:472
TWindow, derived from TEventHandler and TStreamableBase, provides window-specific behavior and encaps...
Definition window.h:414
bool KillTimer(UINT_PTR timerId)
Gets rid of the timer and removes any WM_TIMER messages from the message queue.
Definition window.h:3325
TApplication * GetApplication() const
Gets a pointer to the TApplication object associated with this.
Definition window.h:1855
TWindow * GetLastChild()
Returns a pointer to the last child window in the interface object's child list.
Definition window.h:1776
void GetHWndState(bool forceStyleSync=false)
Copies the style, coordinate, and the resource id (but not the title) from the existing HWnd into the...
Definition window.cpp:3463
virtual bool PreProcessMsg(MSG &msg)
Called from TApplication::ProcessAppMsg() to give the window an opportunity to perform preprocessing ...
Definition window.cpp:644
TWindow * GetParent() const
Retrieves the OWL object of the parent window. If none exists, returns 0.
Definition window.h:2013
void PerformSetupAndTransfer()
Ensures that the window is fully set up; then transfers data into the window.
Definition window.cpp:2528
void SetHandle(THandle)
Sets the window handle in a derived class.
Definition window.h:2034
long GetWindowLong(int index) const
Retrieves information about the window depending on the value stored in index.
Definition window.h:2388
TWindow * GetParentO() const
Return the OWL's parent for this window.
Definition window.h:2006
TModule * GetModule() const
Returns a pointer to the module object.
Definition window.h:1841
bool IsWindow() const
Returns true if an HWND is being used.
Definition window.h:2040
void SetCaption(LPCTSTR title)
Copies title to an allocated string pointed to by title.
Definition window.cpp:3410
bool IsChild(HWND hWnd) const
Returns true if the window is a child window or a descendant window of this window.
Definition window.h:3176
virtual void CleanupWindow()
Always called immediately before the HWindow becomes invalid, CleanupWindow gives derived classes an ...
Definition window.cpp:2640
virtual bool IdleAction(long idleCount)
Called when no messages are waiting to be processed, IdleAction performs idle processing as long as t...
Definition window.cpp:671
void SubclassWindowFunction()
Installs the instance thunk as the WindowProc and saves the old window function in DefaultProc.
Definition window.cpp:2720
LPCTSTR GetCaption() const
Returns the Title member of TWindow.
Definition window.h:1900
UINT_PTR SetTimer(UINT_PTR timerId, uint timeout, TIMERPROC proc=0)
Creates a timer object associated with this window.
Definition window.h:3339
virtual bool CanClose()
Use this function to determine if it is okay to close a window.
Definition window.cpp:2795
virtual void TransferData(TTransferDirection direction)
Transfers data between the TWindow's data buffer and the child windows in its ChildList (data is not ...
Definition window.cpp:2691
virtual TResult EvNotify(uint id, TNotify &notifyInfo)
Handles WM_NOTIFY and subdispatch messages from child controls.
Definition window.cpp:1075
bool PostMessage(TMsgId, TParam1=0, TParam2=0)
Posts a message (msg) to the window in the application's message queue.
Definition window.h:2103
TWindow * Next()
Returns a pointer to the next sibling window in the window's sibling list.
Definition window.h:1755
TResult SendMessage(TMsgId, TParam1=0, TParam2=0) const
Sends a message (msg) to a specified window or windows.
Definition window.cpp:3288
virtual void SetupWindow()
Performs setup following creation of an associated MS-Windows window.
Definition window.cpp:2575
static HWND GetFocus()
Gets a handle to the window that has the focus.
Definition window.h:2139
HWND GetHandle() const
Returns the handle of the window.
Definition window.h:2020
virtual void CloseWindow(int retVal=0)
Determines if it is okay to close a window before actually closing the window.
Definition window.cpp:2809
TXOwl is root class of the ObjectWindows exception hierarchy.
Definition except.h:38
Definition of classes for CommonControl encapsulation.
#define _T(x)
Definition cygwin.h:51
#define DEFINE_RESPONSE_TABLE1(cls, base)
Macro to define a response table for a class with one base.
Definition eventhan.h:492
@ NoAutoDelete
Definition gdibase.h:70
bool(* TCondPageFunc)(TPropertyPage *pPage, void *param)
Definition propsht.h:44
void(* TActionPageFunc)(TPropertyPage *pPage, void *param)
Definition propsht.h:43
virtual int Unhandled(TModule *appModule, uint promptResId)
Per-exception class unhandled-handler, will default to the per-module unhandled-handler.
Definition except.cpp:160
@ tdGetData
Get data from the window into the buffer.
Definition window.h:93
Object Windows Library (OWLNext Core)
Definition animctrl.h:22
const uint PropSheetTimerID
Definition propsht.cpp:30
UINT TMsgId
Message ID type.
Definition dispatch.h:53
unsigned long uint32
Definition number.h:34
const uint PropSheetTimeOut
Definition propsht.cpp:31
LPARAM TParam2
Second parameter type.
Definition dispatch.h:55
WPARAM TParam1
First parameter type.
Definition dispatch.h:54
const int PropPageID
Property sheets notify property pages of events via the standard WM_NOTIFY message.
Definition propsht.h:364
OWL_DIAGINFO
Definition animctrl.cpp:14
END_RESPONSE_TABLE
Definition button.cpp:26
LRESULT TResult
Result type.
Definition dispatch.h:52
std::string tstring
Definition defs.h:79
EV_WM_TIMER
Definition propsht.cpp:34
unsigned int uint
Definition number.h:25
action
Definition regexp.cpp:133
EV_WM_CLOSE
Definition commdial.cpp:23
#define CONST_CAST(targetType, object)
Definition defs.h:273
#define REINTERPRET_CAST(targetType, object)
Definition defs.h:275
#define TYPESAFE_DOWNCAST(object, toClass)
Definition defs.h:269
#define MAXPROPPAGES
Definition propsht.cpp:18
Definition of classes encapsulating PropertySheets and PropertyPages.
#define EV_PSN_SETACTIVE(method)
int method(TPshNotify&)
Definition propsht.h:399
#define EV_PSN_KILLACTIVE(method)
bool method(TPshNotify&)
Definition propsht.h:384
#define EV_PSN_QUERYCANCEL(method)
bool method(TPshNotify&)
Definition propsht.h:389
#define EV_PSN_APPLY(method)
void method(TPshNotify&)
Definition propsht.h:369
#define EV_PSN_HELP(method)
void method(TPshNotify&)
Definition propsht.h:379
#define EV_PSN_RESET(method)
void method(TPshNotify&)
Definition propsht.h:394
#define EV_PSN_WIZFINISH(method)
bool method(TPshNotify&)
Definition propsht.h:409
#define EV_PSN_WIZNEXT(method)
int method(TPshNotify&)
Definition propsht.h:414
#define EV_PSN_WIZBACK(method)
int method(TPshNotify&)
Definition propsht.h:404
Defines classes handling Windows resources.
Definition of class TTabItem and TTabControl.
Definition of TUIMetric, a UI metrics provider class.