598430f308088aafd978c1bf7b6820cf6d5cbaca
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / include / propertysheet.h
1 // Win32++   Version 7.3\r
2 // Released: 30th November 2011\r
3 //\r
4 //      David Nash\r
5 //      email: [email protected]\r
6 //      url: https://sourceforge.net/projects/win32-framework\r
7 //\r
8 //\r
9 // Copyright (c) 2005-2011  David Nash\r
10 //\r
11 // Permission is hereby granted, free of charge, to\r
12 // any person obtaining a copy of this software and\r
13 // associated documentation files (the "Software"),\r
14 // to deal in the Software without restriction, including\r
15 // without limitation the rights to use, copy, modify,\r
16 // merge, publish, distribute, sublicense, and/or sell\r
17 // copies of the Software, and to permit persons to whom\r
18 // the Software is furnished to do so, subject to the\r
19 // following conditions:\r
20 //\r
21 // The above copyright notice and this permission notice\r
22 // shall be included in all copies or substantial portions\r
23 // of the Software.\r
24 //\r
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF\r
26 // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED\r
27 // TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A\r
28 // PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\r
29 // SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
30 // ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
31 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
32 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE\r
33 // OR OTHER DEALINGS IN THE SOFTWARE.\r
34 //\r
35 ////////////////////////////////////////////////////////\r
36 \r
37 \r
38 ///////////////////////////////////////////////////////\r
39 // propertysheet.h\r
40 //  Declaration of the following classes:\r
41 //  CPropertyPage and CPropertySheet\r
42 \r
43 // These classes add support for property sheets to Win32++. A property sheet\r
44 // will have one or more property pages. These pages are much like dialogs\r
45 // which are presented within a tabbed dialog or within a wizard. The data\r
46 // on a property page can be validated before the next page is presented.\r
47 // Property sheets have three modes of use: Modal, Modeless, and Wizard.\r
48 //\r
49 // Refer to the PropertySheet demo program for an example of how propert sheets\r
50 // can be used.\r
51 \r
52 \r
53 #ifndef _WIN32XX_PROPERTYSHEET_H_\r
54 #define _WIN32XX_PROPERTYSHEET_H_\r
55 \r
56 #include "dialog.h"\r
57 \r
58 #define ID_APPLY_NOW   0x3021\r
59 #define ID_WIZBACK     0x3023\r
60 #define ID_WIZNEXT     0x3024\r
61 #define ID_WIZFINISH   0x3025\r
62 #define ID_HELP        0xE146\r
63 \r
64 #ifndef PROPSHEETHEADER_V1_SIZE\r
65  #define PROPSHEETHEADER_V1_SIZE 40\r
66 #endif\r
67 \r
68 namespace Win32xx\r
69 {\r
70     class CPropertyPage;\r
71         typedef Shared_Ptr<CPropertyPage> PropertyPagePtr;\r
72 \r
73         class CPropertyPage : public CWnd\r
74         {\r
75         public:\r
76                 CPropertyPage (UINT nIDTemplate, LPCTSTR szTitle = NULL);\r
77                 virtual ~CPropertyPage() {}\r
78 \r
79                 virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
80                 virtual INT_PTR DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
81                 virtual int  OnApply();\r
82                 virtual void OnCancel();\r
83                 virtual void OnHelp();\r
84                 virtual BOOL OnInitDialog();\r
85                 virtual BOOL OnKillActive();\r
86                 virtual LRESULT OnNotify(WPARAM wParam, LPARAM lParam);\r
87                 virtual int  OnOK();\r
88                 virtual BOOL OnQueryCancel();\r
89                 virtual BOOL OnQuerySiblings(WPARAM wParam, LPARAM lParam);\r
90                 virtual int  OnSetActive();\r
91                 virtual int  OnWizardBack();\r
92                 virtual INT_PTR OnWizardFinish();\r
93                 virtual int  OnWizardNext();\r
94                 virtual BOOL PreTranslateMessage(MSG* pMsg);\r
95 \r
96                 static UINT CALLBACK StaticPropSheetPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp);\r
97                 static INT_PTR CALLBACK StaticDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
98 \r
99                 void CancelToClose() const;\r
100                 PROPSHEETPAGE GetPSP() const {return m_PSP;}\r
101                 BOOL IsButtonEnabled(int iButton) const;\r
102                 LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) const;\r
103                 void SetModified(BOOL bChanged) const;\r
104                 void SetTitle(LPCTSTR szTitle);\r
105                 void SetWizardButtons(DWORD dwFlags) const;\r
106 \r
107         protected:\r
108                 PROPSHEETPAGE m_PSP;\r
109 \r
110         private:\r
111                 CPropertyPage(const CPropertyPage&);                            // Disable copy construction\r
112                 CPropertyPage& operator = (const CPropertyPage&);       // Disable assignment operator\r
113 \r
114                 CString m_Title;\r
115         };\r
116 \r
117         class CPropertySheet : public CWnd\r
118         {\r
119         public:\r
120                 CPropertySheet(UINT nIDCaption, CWnd* pParent = NULL);\r
121                 CPropertySheet(LPCTSTR pszCaption = NULL, CWnd* pParent = NULL);\r
122                 virtual ~CPropertySheet() {}\r
123 \r
124                 // Operations\r
125                 virtual CPropertyPage* AddPage(CPropertyPage* pPage);\r
126                 virtual HWND Create(CWnd* pParent = 0);\r
127                 virtual INT_PTR CreatePropertySheet(LPCPROPSHEETHEADER ppsph);\r
128                 virtual void DestroyButton(int iButton);\r
129                 virtual void Destroy();\r
130                 virtual int DoModal();\r
131                 virtual void RemovePage(CPropertyPage* pPage);\r
132 \r
133                 // State functions\r
134                 BOOL IsModeless() const;\r
135                 BOOL IsWizard() const;\r
136 \r
137                 //Attributes\r
138                 CPropertyPage* GetActivePage() const;\r
139                 int GetPageCount() const;\r
140                 int GetPageIndex(CPropertyPage* pPage) const;\r
141                 HWND GetTabControl() const;\r
142                 virtual BOOL SetActivePage(int nPage);\r
143                 virtual BOOL SetActivePage(CPropertyPage* pPage);\r
144                 virtual void SetIcon(UINT idIcon);\r
145                 virtual void SetTitle(LPCTSTR szTitle);\r
146                 virtual void SetWizardMode(BOOL bWizard);\r
147 \r
148         protected:\r
149                 virtual BOOL PreTranslateMessage(MSG* pMsg);\r
150                 virtual LRESULT WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
151 \r
152         private:\r
153                 CPropertySheet(const CPropertySheet&);                          // Disable copy construction\r
154                 CPropertySheet& operator = (const CPropertySheet&); // Disable assignment operator\r
155                 void BuildPageArray();\r
156                 static void CALLBACK Callback(HWND hwnd, UINT uMsg, LPARAM lParam);\r
157 \r
158                 CString m_Title;\r
159                 std::vector<PropertyPagePtr> m_vPages;  // vector of CPropertyPage\r
160                 std::vector<PROPSHEETPAGE> m_vPSP;              // vector of PROPSHEETPAGE\r
161                 BOOL m_bInitialUpdate;\r
162                 PROPSHEETHEADER m_PSH;\r
163         };\r
164 \r
165 }\r
166 \r
167 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//\r
168 \r
169 namespace Win32xx\r
170 {\r
171 \r
172         //////////////////////////////////////////\r
173         // Definitions for the CPropertyPage class\r
174         //\r
175         inline CPropertyPage::CPropertyPage(UINT nIDTemplate, LPCTSTR szTitle /* = NULL*/)\r
176         {\r
177                 ZeroMemory(&m_PSP, sizeof(PROPSHEETPAGE));\r
178                 SetTitle(szTitle);\r
179 \r
180                 m_PSP.dwSize        = sizeof(PROPSHEETPAGE);\r
181                 m_PSP.dwFlags       |= PSP_USECALLBACK;\r
182                 m_PSP.hInstance     = GetApp()->GetResourceHandle();\r
183                 m_PSP.pszTemplate   = MAKEINTRESOURCE(nIDTemplate);\r
184                 m_PSP.pszTitle      = m_Title;\r
185                 m_PSP.pfnDlgProc    = (DLGPROC)CPropertyPage::StaticDialogProc;\r
186                 m_PSP.lParam        = (LPARAM)this;\r
187                 m_PSP.pfnCallback   = CPropertyPage::StaticPropSheetPageProc;\r
188         }\r
189 \r
190         inline void CPropertyPage::CancelToClose() const\r
191         // Disables the Cancel button and changes the text of the OK button to "Close."\r
192         {\r
193                 assert(::IsWindow(m_hWnd));\r
194                 SendMessage(PSM_CANCELTOCLOSE, 0L, 0L);\r
195         }\r
196 \r
197 \r
198         inline INT_PTR CPropertyPage::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
199         {\r
200                 // Override this function in your class derrived from CPropertyPage if you wish to handle messages\r
201                 // A typical function might look like this:\r
202 \r
203                 //      switch (uMsg)\r
204                 //      {\r
205                 //      case MESSAGE1:          // Some Win32 API message\r
206                 //              OnMessage1();   // A user defined function\r
207                 //              break;                  // Also do default processing\r
208                 //      case MESSAGE2:\r
209                 //              OnMessage2();\r
210                 //              return x;               // Don't do default processing, but instead return\r
211                 //                                              //  a value recommended by the Win32 API documentation\r
212                 //      }\r
213 \r
214                 // Always pass unhandled messages on to DialogProcDefault\r
215                 return DialogProcDefault(uMsg, wParam, lParam);\r
216         }\r
217 \r
218         inline INT_PTR CPropertyPage::DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
219         // All DialogProc functions should pass unhandled messages to this function\r
220         {\r
221                 LRESULT lr = 0L;\r
222 \r
223                 switch (uMsg)\r
224             {\r
225                 case UWM_CLEANUPTEMPS:\r
226                         {\r
227                                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
228                                 pTLSData->vTmpWnds.clear();\r
229                         }\r
230                         break;\r
231 \r
232             case WM_INITDIALOG:\r
233                     return OnInitDialog();\r
234 \r
235                 case PSM_QUERYSIBLINGS:\r
236                         return (BOOL)OnQuerySiblings(wParam, lParam);\r
237 \r
238                 case WM_COMMAND:\r
239                         {\r
240                                 // Refelect this message if it's from a control\r
241                                 CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam);\r
242                                 if (pWnd != NULL)\r
243                                         lr = pWnd->OnCommand(wParam, lParam);\r
244 \r
245                                 // Handle user commands\r
246                                 if (!lr)\r
247                                         lr =  OnCommand(wParam, lParam);\r
248 \r
249                                 if (lr) return 0L;\r
250                         }\r
251                         break;\r
252 \r
253                 case WM_NOTIFY:\r
254                         {\r
255                                 // Do Notification reflection if it came from a CWnd object\r
256                                 HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom;\r
257                                 CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom);\r
258 \r
259                                 if (pWndFrom != NULL)\r
260                                         lr = pWndFrom->OnNotifyReflect(wParam, lParam);\r
261                                 else\r
262                                 {\r
263                                         // Some controls (eg ListView) have child windows.\r
264                                         // Reflect those notifications too.\r
265                                         CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom));\r
266                                         if (pWndFromParent != NULL)\r
267                                                 lr = pWndFromParent->OnNotifyReflect(wParam, lParam);\r
268                                 }\r
269 \r
270                                 // Handle user notifications\r
271                                 if (!lr) lr = OnNotify(wParam, lParam);\r
272 \r
273                                 // Set the return code for notifications\r
274                                 if (IsWindow())\r
275                                         SetWindowLongPtr(DWLP_MSGRESULT, (LONG_PTR)lr);\r
276 \r
277                                 return (BOOL)lr;\r
278                         }\r
279 \r
280                 case WM_PAINT:\r
281                         {\r
282                                 if (::GetUpdateRect(m_hWnd, NULL, FALSE))\r
283                                 {\r
284                                         CPaintDC dc(this);\r
285                                         OnDraw(&dc);\r
286                                 }\r
287                                 else\r
288                                 // RedrawWindow can require repainting without an update rect\r
289                                 {\r
290                                         CClientDC dc(this);\r
291                                         OnDraw(&dc);\r
292                                 }\r
293 \r
294                                 break;\r
295                         }\r
296                         \r
297                 case WM_ERASEBKGND:\r
298                         {\r
299                                 CDC dc((HDC)wParam);\r
300                                 BOOL bResult = OnEraseBkgnd(&dc);\r
301                                 dc.Detach();\r
302                                 if (bResult) return TRUE;\r
303                         }\r
304                         break;\r
305 \r
306                 // A set of messages to be reflected back to the control that generated them\r
307                 case WM_CTLCOLORBTN:\r
308                 case WM_CTLCOLOREDIT:\r
309                 case WM_CTLCOLORDLG:\r
310                 case WM_CTLCOLORLISTBOX:\r
311                 case WM_CTLCOLORSCROLLBAR:\r
312                 case WM_CTLCOLORSTATIC:\r
313                 case WM_DRAWITEM:\r
314                 case WM_MEASUREITEM:\r
315                 case WM_DELETEITEM:\r
316                 case WM_COMPAREITEM:\r
317                 case WM_CHARTOITEM:\r
318                 case WM_VKEYTOITEM:\r
319                 case WM_HSCROLL:\r
320                 case WM_VSCROLL:\r
321                 case WM_PARENTNOTIFY:\r
322                         return MessageReflect(m_hWnd, uMsg, wParam, lParam);\r
323 \r
324             } // switch(uMsg)\r
325             return FALSE;\r
326 \r
327         } // INT_PTR CALLBACK CPropertyPage::DialogProc(...)\r
328 \r
329         inline BOOL CPropertyPage::IsButtonEnabled(int iButton) const\r
330         {\r
331                 assert(::IsWindow(m_hWnd));\r
332                 return GetParent()->GetDlgItem(iButton)->IsWindowEnabled();\r
333         }\r
334 \r
335         inline int CPropertyPage::OnApply()\r
336         {\r
337                 // This function is called for each page when the Apply button is pressed\r
338                 // Override this function in your derived class if required.\r
339 \r
340                 // The possible return values are:\r
341                 // PSNRET_NOERROR. The changes made to this page are valid and have been applied\r
342                 // PSNRET_INVALID. The property sheet will not be destroyed, and focus will be returned to this page.\r
343                 // PSNRET_INVALID_NOCHANGEPAGE. The property sheet will not be destroyed, and focus will be returned;\r
344 \r
345                 return PSNRET_NOERROR;\r
346         }\r
347 \r
348         inline void CPropertyPage::OnCancel()\r
349         {\r
350                 // This function is called for each page when the Cancel button is pressed\r
351                 // Override this function in your derived class if required.\r
352         }\r
353 \r
354         inline void CPropertyPage::OnHelp()\r
355         {\r
356                 // This function is called in response to the PSN_HELP notification.\r
357                 SendMessage(m_hWnd, WM_COMMAND, ID_HELP, 0L);\r
358         }\r
359 \r
360         inline BOOL CPropertyPage::OnQueryCancel()\r
361         {\r
362                 // Called when the cancel button is pressed, and before the cancel has taken place\r
363                 // Returns TRUE to prevent the cancel operation, or FALSE to allow it.\r
364 \r
365                 return FALSE;    // Allow cancel to proceed\r
366         }\r
367 \r
368         inline BOOL CPropertyPage::OnQuerySiblings(WPARAM wParam, LPARAM lParam)\r
369         {\r
370                 UNREFERENCED_PARAMETER(wParam);\r
371                 UNREFERENCED_PARAMETER(lParam);\r
372 \r
373                 // Responds to a query request from the Property Sheet.\r
374                 // The values for wParam and lParam are the ones set by\r
375                 // the CPropertySheet::QuerySiblings call\r
376 \r
377                 // return FALSE to allow other siblings to be queried, or\r
378                 // return TRUE to stop query at this page.\r
379 \r
380                 return FALSE;\r
381         }\r
382 \r
383         inline BOOL CPropertyPage::OnInitDialog()\r
384         {\r
385                 // Called when the property page is created\r
386                 // Override this function in your derived class if required.\r
387 \r
388                 return TRUE; // Pass Keyboard control to handle in WPARAM\r
389         }\r
390 \r
391         inline BOOL CPropertyPage::OnKillActive()\r
392         {\r
393                 // This is called in response to a PSN_KILLACTIVE notification, which\r
394                 // is sent whenever the OK or Apply button is pressed.\r
395                 // It provides an opportunity to validate the page contents before it's closed.\r
396                 // Return TRUE to prevent the page from losing the activation, or FALSE to allow it.\r
397 \r
398                 return FALSE;\r
399         }\r
400 \r
401         inline int CPropertyPage::OnOK()\r
402         {\r
403                 // Called for each page when the OK button is pressed\r
404                 // Override this function in your derived class if required.\r
405 \r
406                 // The possible return values are:\r
407                 // PSNRET_NOERROR. The changes made to this page are valid and have been applied\r
408                 // PSNRET_INVALID. The property sheet will not be destroyed, and focus will be returned to this page.\r
409                 // PSNRET_INVALID_NOCHANGEPAGE. The property sheet will not be destroyed, and focus will be returned;\r
410 \r
411                 return PSNRET_NOERROR;\r
412         }\r
413 \r
414         inline LRESULT CPropertyPage::OnNotify(WPARAM wParam, LPARAM lParam)\r
415         {\r
416                 UNREFERENCED_PARAMETER(wParam);\r
417 \r
418                 LPPSHNOTIFY pNotify = (LPPSHNOTIFY)lParam;\r
419                 switch(pNotify->hdr.code)\r
420                 {\r
421                 case PSN_SETACTIVE:\r
422                         return OnSetActive();\r
423                 case PSN_KILLACTIVE:\r
424                         return OnKillActive();\r
425                 case PSN_APPLY:\r
426                         if (pNotify->lParam)\r
427                                 return OnOK();\r
428                         else\r
429                                 return OnApply();\r
430                 case PSN_RESET:\r
431                         OnCancel();\r
432                         return FALSE;\r
433                 case PSN_QUERYCANCEL:\r
434                         return OnQueryCancel();\r
435                 case PSN_WIZNEXT:\r
436                         return OnWizardNext();\r
437                 case PSN_WIZBACK:\r
438                         return OnWizardBack();\r
439                 case PSN_WIZFINISH:\r
440                         return OnWizardFinish();\r
441                 case PSN_HELP:\r
442                         OnHelp();\r
443                         return TRUE;\r
444                 }\r
445                 return FALSE;\r
446         }\r
447 \r
448         inline int CPropertyPage::OnSetActive()\r
449         {\r
450                 // Called when a page becomes active\r
451                 // Override this function in your derived class if required.\r
452 \r
453                 // Returns zero to accept the activation, or -1 to activate the next or the previous page (depending\r
454                 // on whether the user clicked the Next or Back button). To set the activation to a particular page,\r
455                 // return the resource identifier of the page.\r
456 \r
457                 return 0;\r
458         }\r
459 \r
460         inline int CPropertyPage::OnWizardBack()\r
461         {\r
462                 // This function is called when the Back button is pressed on a wizard page\r
463                 // Override this function in your derived class if required.\r
464 \r
465                 // Returns 0 to allow the wizard to go to the previous page. Returns -1 to prevent the wizard\r
466                 // from changing pages. To display a particular page, return its dialog resource identifier.\r
467 \r
468                 return 0;\r
469         }\r
470 \r
471         inline INT_PTR CPropertyPage::OnWizardFinish()\r
472         {\r
473                 // This function is called when the Finish button is pressed on a wizard page\r
474                 // Override this function in your derived class if required.\r
475 \r
476                 // Return Value:\r
477                 // Return non-zero to prevent the wizard from finishing.\r
478                 // Version 5.80. and later. Return a window handle to prevent the wizard from finishing. The wizard will set the focus to that window. The window must be owned by the wizard page.\r
479                 // Return 0 to allow the wizard to finish.\r
480 \r
481                 return 0; // Allow wizard to finish\r
482         }\r
483 \r
484         inline int CPropertyPage::OnWizardNext()\r
485         {\r
486                 // This function is called when the Next button is pressed on a wizard page\r
487                 // Override this function in your derived class if required.\r
488 \r
489                 // Return 0 to allow the wizard to go to the next page. Return -1 to prevent the wizard from\r
490                 // changing pages. To display a particular page, return its dialog resource identifier.\r
491 \r
492                 return 0;\r
493         }\r
494 \r
495         inline BOOL CPropertyPage::PreTranslateMessage(MSG* pMsg)\r
496         {\r
497                 // allow the tab control to translate keyboard input\r
498                 if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&\r
499                         (pMsg->wParam == VK_TAB || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT))\r
500                 {\r
501                         CWnd* pWndParent = GetParent();\r
502                         if (pWndParent->SendMessage(PSM_ISDIALOGMESSAGE, 0L, (LPARAM)pMsg))\r
503                                 return TRUE;\r
504                 }\r
505 \r
506                 // allow the dialog to translate keyboard input\r
507                 if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))\r
508                 {\r
509                         if (IsDialogMessage(pMsg))\r
510                                 return TRUE;\r
511                 }\r
512 \r
513                 return CWnd::PreTranslateMessage(pMsg);\r
514         }\r
515 \r
516         inline LRESULT CPropertyPage::QuerySiblings(WPARAM wParam, LPARAM lParam) const\r
517         {\r
518                 // Sent to a property sheet, which then forwards the message to each of its pages.\r
519                 // Set wParam and lParam to values you want passed to the property pages.\r
520                 // Returns the nonzero value from a page in the property sheet, or zero if no page returns a nonzero value.\r
521 \r
522                 assert(::IsWindow(m_hWnd));\r
523                 return GetParent()->SendMessage(PSM_QUERYSIBLINGS, wParam, lParam);\r
524         }\r
525 \r
526         inline void CPropertyPage::SetModified(BOOL bChanged) const\r
527         {\r
528                 // The property sheet will enable the Apply button if bChanged is TRUE.\r
529 \r
530                 assert(::IsWindow(m_hWnd));\r
531 \r
532                 if (bChanged)\r
533                         GetParent()->SendMessage(PSM_CHANGED, (WPARAM)m_hWnd, 0L);\r
534                 else\r
535                         GetParent()->SendMessage(PSM_UNCHANGED, (WPARAM)m_hWnd, 0L);\r
536         }\r
537 \r
538         inline void CPropertyPage::SetTitle(LPCTSTR szTitle)\r
539         {\r
540                 if (szTitle)\r
541                 {\r
542                         m_Title = szTitle;\r
543                         m_PSP.dwFlags |= PSP_USETITLE;\r
544                 }\r
545                 else\r
546                 {\r
547                         m_Title.Empty();\r
548                         m_PSP.dwFlags &= ~PSP_USETITLE;\r
549                 }\r
550 \r
551                 m_PSP.pszTitle = m_Title;\r
552         }\r
553 \r
554         inline void CPropertyPage::SetWizardButtons(DWORD dwFlags) const\r
555         {\r
556                 // dwFlags:  A value that specifies which wizard buttons are enabled. You can combine one or more of the following flags.\r
557                 //      PSWIZB_BACK                             Enable the Back button. If this flag is not set, the Back button is displayed as disabled.\r
558                 //      PSWIZB_DISABLEDFINISH   Display a disabled Finish button.\r
559                 //      PSWIZB_FINISH                   Display an enabled Finish button.\r
560                 //      PSWIZB_NEXT                             Enable the Next button. If this flag is not set, the Next button is displayed as disabled.\r
561 \r
562                 assert (::IsWindow(m_hWnd));\r
563                 PropSheet_SetWizButtons(::GetParent(m_hWnd), dwFlags);\r
564         }\r
565 \r
566         inline UINT CALLBACK CPropertyPage::StaticPropSheetPageProc(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)\r
567         {\r
568                 assert( GetApp() );\r
569                 UNREFERENCED_PARAMETER(hwnd);\r
570 \r
571                 // Note: the hwnd is always NULL\r
572 \r
573                 switch (uMsg)\r
574                 {\r
575                 case PSPCB_CREATE:\r
576                         {\r
577                                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
578                                 assert(pTLSData);\r
579 \r
580                                 // Store the CPropertyPage pointer in Thread Local Storage\r
581                                 pTLSData->pCWnd = (CWnd*)ppsp->lParam;\r
582                         }\r
583                         break;\r
584                 }\r
585 \r
586                 return TRUE;\r
587         }\r
588 \r
589         inline INT_PTR CALLBACK CPropertyPage::StaticDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
590         {\r
591                 assert( GetApp() );\r
592 \r
593                 // Find matching CWnd pointer for this HWND\r
594                 CPropertyPage* pPage = (CPropertyPage*)GetApp()->GetCWndFromMap(hwndDlg);\r
595                 if (0 == pPage)\r
596                 {\r
597                         // matching CWnd pointer not found, so add it to HWNDMap now\r
598                         TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
599                         pPage = (CPropertyPage*)pTLSData->pCWnd;\r
600 \r
601                         // Set the hWnd members and call DialogProc for this message\r
602                         pPage->m_hWnd = hwndDlg;\r
603                         pPage->AddToMap();\r
604                 }\r
605 \r
606                 return pPage->DialogProc(uMsg, wParam, lParam);\r
607         }\r
608 \r
609 \r
610         ///////////////////////////////////////////\r
611         // Definitions for the CPropertySheet class\r
612         //\r
613         inline CPropertySheet::CPropertySheet(UINT nIDCaption, CWnd* pParent /* = NULL*/)\r
614         {\r
615                 ZeroMemory(&m_PSH, sizeof (PROPSHEETHEADER));\r
616                 SetTitle(LoadString(nIDCaption));\r
617                 m_bInitialUpdate = FALSE;\r
618 \r
619 #ifdef _WIN32_WCE\r
620                 m_PSH.dwSize = sizeof(PROPSHEETHEADER);\r
621 #else\r
622                 if (GetComCtlVersion() >= 471)\r
623                         m_PSH.dwSize = sizeof(PROPSHEETHEADER);\r
624                 else\r
625                         m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;\r
626 #endif\r
627 \r
628                 m_PSH.dwFlags          = PSH_PROPSHEETPAGE | PSH_USECALLBACK;\r
629                 m_PSH.hwndParent       = pParent? pParent->GetHwnd() : 0;\r
630                 m_PSH.hInstance        = GetApp()->GetInstanceHandle();\r
631                 m_PSH.pfnCallback      = (PFNPROPSHEETCALLBACK)CPropertySheet::Callback;\r
632         }\r
633 \r
634         inline CPropertySheet::CPropertySheet(LPCTSTR pszCaption /*= NULL*/, CWnd* pParent /* = NULL*/)\r
635         {\r
636                 ZeroMemory(&m_PSH, sizeof (PROPSHEETHEADER));\r
637                 SetTitle(pszCaption);\r
638                 m_bInitialUpdate = FALSE;\r
639 \r
640 #ifdef _WIN32_WCE\r
641                 m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;\r
642 #else\r
643                 if (GetComCtlVersion() >= 471)\r
644                         m_PSH.dwSize = sizeof(PROPSHEETHEADER);\r
645                 else\r
646                         m_PSH.dwSize = PROPSHEETHEADER_V1_SIZE;\r
647 #endif\r
648 \r
649                 m_PSH.dwFlags          = PSH_PROPSHEETPAGE | PSH_USECALLBACK;\r
650                 m_PSH.hwndParent       = pParent? pParent->GetHwnd() : 0;;\r
651                 m_PSH.hInstance        = GetApp()->GetInstanceHandle();\r
652                 m_PSH.pfnCallback      = (PFNPROPSHEETCALLBACK)CPropertySheet::Callback;\r
653         }\r
654 \r
655         inline CPropertyPage* CPropertySheet::AddPage(CPropertyPage* pPage)\r
656         // Adds a Property Page to the Property Sheet\r
657         {\r
658                 assert(NULL != pPage);\r
659 \r
660                 m_vPages.push_back(PropertyPagePtr(pPage));\r
661 \r
662                 if (m_hWnd)\r
663                 {\r
664                         // property sheet already exists, so add page to it\r
665                         PROPSHEETPAGE psp = pPage->GetPSP();\r
666                         HPROPSHEETPAGE hpsp = ::CreatePropertySheetPage(&psp);\r
667                         PropSheet_AddPage(m_hWnd, hpsp);\r
668                 }\r
669 \r
670                 m_PSH.nPages = (int)m_vPages.size();\r
671 \r
672                 return pPage;\r
673         }\r
674 \r
675         inline void CPropertySheet::BuildPageArray()\r
676         // Builds the PROPSHEETPAGE array\r
677         {\r
678                 m_vPSP.clear();\r
679                 std::vector<PropertyPagePtr>::iterator iter;\r
680                 for (iter = m_vPages.begin(); iter < m_vPages.end(); ++iter)\r
681                         m_vPSP.push_back((*iter)->GetPSP());\r
682 \r
683                 PROPSHEETPAGE* pPSPArray = &m_vPSP.front();     // Array of PROPSHEETPAGE\r
684                 m_PSH.ppsp = pPSPArray;\r
685         }\r
686 \r
687         inline void CALLBACK CPropertySheet::Callback(HWND hwnd, UINT uMsg, LPARAM lParam)\r
688         {\r
689                 assert( GetApp() );\r
690 \r
691                 switch(uMsg)\r
692                 {\r
693                 //called before the dialog is created, hwnd = NULL, lParam points to dialog resource\r
694                 case PSCB_PRECREATE:\r
695                         {\r
696                                 LPDLGTEMPLATE  lpTemplate = (LPDLGTEMPLATE)lParam;\r
697 \r
698                                 if(!(lpTemplate->style & WS_SYSMENU))\r
699                                 {\r
700                                         lpTemplate->style |= WS_SYSMENU;\r
701                                 }\r
702                         }\r
703                         break;\r
704 \r
705                 //called after the dialog is created\r
706                 case PSCB_INITIALIZED:\r
707                         {\r
708                                 // Retrieve pointer to CWnd object from Thread Local Storage\r
709                                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
710                                 assert(pTLSData);\r
711 \r
712                                 CPropertySheet* w = (CPropertySheet*)pTLSData->pCWnd;\r
713                                 assert(w);\r
714 \r
715                                 w->Attach(hwnd);\r
716                                 w->OnCreate();\r
717                         }\r
718                         break;\r
719                 }\r
720         }\r
721 \r
722 \r
723         inline HWND CPropertySheet::Create(CWnd* pParent /*= 0*/)\r
724         // Creates a modeless Property Sheet\r
725         {\r
726                 assert( GetApp() );\r
727 \r
728                 if (pParent)\r
729                 {\r
730                         m_PSH.hwndParent = pParent->GetHwnd();\r
731                 }\r
732 \r
733                 BuildPageArray();\r
734                 PROPSHEETPAGE* pPSPArray = &m_vPSP.front();\r
735                 m_PSH.ppsp = pPSPArray;\r
736 \r
737                 // Create a modeless Property Sheet\r
738                 m_PSH.dwFlags &= ~PSH_WIZARD;\r
739                 m_PSH.dwFlags |= PSH_MODELESS;\r
740                 HWND hWnd = (HWND)CreatePropertySheet(&m_PSH);\r
741 \r
742                 return hWnd;\r
743         }\r
744 \r
745         inline INT_PTR CPropertySheet::CreatePropertySheet(LPCPROPSHEETHEADER ppsph)\r
746         {\r
747                 assert( GetApp() );\r
748 \r
749                 INT_PTR ipResult = 0;\r
750 \r
751                 // Only one window per CWnd instance allowed\r
752                 assert(!::IsWindow(m_hWnd));\r
753 \r
754                 // Ensure this thread has the TLS index set\r
755                 TLSData* pTLSData = GetApp()->SetTlsIndex();\r
756 \r
757                 // Store the 'this' pointer in Thread Local Storage\r
758                 pTLSData->pCWnd = this;\r
759 \r
760                 // Create the property sheet\r
761                 ipResult = PropertySheet(ppsph);\r
762 \r
763                 return ipResult;\r
764         }\r
765 \r
766         inline void CPropertySheet::DestroyButton(int IDButton)\r
767         {\r
768                 assert(::IsWindow(m_hWnd));\r
769 \r
770                 HWND hwndButton = ::GetDlgItem(m_hWnd, IDButton);\r
771                 if (hwndButton != NULL)\r
772                 {\r
773                         // Hide and disable the button\r
774                         ::ShowWindow(hwndButton, SW_HIDE);\r
775                         ::EnableWindow(hwndButton, FALSE);\r
776                 }\r
777         }\r
778 \r
779         inline void CPropertySheet::Destroy()\r
780         {\r
781                 CWnd::Destroy();\r
782                 m_vPages.clear();\r
783         }\r
784 \r
785         inline int CPropertySheet::DoModal()\r
786         {\r
787                 assert( GetApp() );\r
788 \r
789                 BuildPageArray();\r
790                 PROPSHEETPAGE* pPSPArray = &m_vPSP.front();\r
791                 m_PSH.ppsp = pPSPArray;\r
792 \r
793                 // Create the Property Sheet\r
794                 int nResult = (int)CreatePropertySheet(&m_PSH);\r
795 \r
796                 m_vPages.clear();\r
797 \r
798                 return nResult;\r
799         }\r
800 \r
801         inline CPropertyPage* CPropertySheet::GetActivePage() const\r
802         {\r
803                 assert(::IsWindow(m_hWnd));\r
804 \r
805                 CPropertyPage* pPage = NULL;\r
806                 if (m_hWnd != NULL)\r
807                 {\r
808                         HWND hPage = (HWND)SendMessage(PSM_GETCURRENTPAGEHWND, 0L, 0L);\r
809                         pPage = (CPropertyPage*)FromHandle(hPage);\r
810                 }\r
811 \r
812                 return pPage;\r
813         }\r
814 \r
815         inline int CPropertySheet::GetPageCount() const\r
816         // Returns the number of Property Pages in this Property Sheet\r
817         {\r
818                 assert(::IsWindow(m_hWnd));\r
819                 return (int)m_vPages.size();\r
820         }\r
821 \r
822         inline int CPropertySheet::GetPageIndex(CPropertyPage* pPage) const\r
823         {\r
824                 assert(::IsWindow(m_hWnd));\r
825 \r
826                 for (int i = 0; i < GetPageCount(); i++)\r
827                 {\r
828                         if (m_vPages[i].get() == pPage)\r
829                                 return i;\r
830                 }\r
831                 return -1;\r
832         }\r
833 \r
834         inline HWND CPropertySheet::GetTabControl() const\r
835         // Returns the handle to the Property Sheet's tab control\r
836         {\r
837                 assert(::IsWindow(m_hWnd));\r
838                 return (HWND)SendMessage(PSM_GETTABCONTROL, 0L, 0L);\r
839         }\r
840 \r
841         inline BOOL CPropertySheet::IsModeless() const\r
842         {\r
843                 return (m_PSH.dwFlags & PSH_MODELESS);\r
844         }\r
845 \r
846         inline BOOL CPropertySheet::IsWizard() const\r
847         {\r
848                 return (m_PSH.dwFlags & PSH_WIZARD);\r
849         }\r
850 \r
851         inline void CPropertySheet::RemovePage(CPropertyPage* pPage)\r
852         // Removes a Property Page from the Property Sheet\r
853         {\r
854                 assert(::IsWindow(m_hWnd));\r
855 \r
856                 int nPage = GetPageIndex(pPage);\r
857                 if (m_hWnd != NULL)\r
858                         SendMessage(m_hWnd, PSM_REMOVEPAGE, nPage, 0L);\r
859 \r
860                 m_vPages.erase(m_vPages.begin() + nPage, m_vPages.begin() + nPage+1);\r
861                 m_PSH.nPages = (int)m_vPages.size();\r
862         }\r
863 \r
864         inline BOOL CPropertySheet::PreTranslateMessage(MSG* pMsg)\r
865         {\r
866                 // allow sheet to translate Ctrl+Tab, Shift+Ctrl+Tab, Ctrl+PageUp, and Ctrl+PageDown\r
867                 if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&\r
868                         (pMsg->wParam == VK_TAB || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT))\r
869                 {\r
870                         if (SendMessage(PSM_ISDIALOGMESSAGE, 0L, (LPARAM)pMsg))\r
871                                 return TRUE;\r
872                 }\r
873 \r
874                 // allow the dialog to translate keyboard input\r
875                 if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))\r
876                 {\r
877                         return GetActivePage()->PreTranslateMessage(pMsg);\r
878                 }\r
879 \r
880                 return CWnd::PreTranslateMessage(pMsg);\r
881         }\r
882 \r
883         inline BOOL CPropertySheet::SetActivePage(int nPage)\r
884         {\r
885                 assert(::IsWindow(m_hWnd));\r
886                 return (BOOL)SendMessage(m_hWnd, PSM_SETCURSEL, nPage, 0L);\r
887         }\r
888 \r
889         inline BOOL CPropertySheet::SetActivePage(CPropertyPage* pPage)\r
890         {\r
891                 assert(::IsWindow(m_hWnd));\r
892                 int nPage = GetPageIndex(pPage);\r
893                 if ((nPage >= 0))\r
894                         return SetActivePage(nPage);\r
895 \r
896                 return FALSE;\r
897         }\r
898 \r
899         inline void CPropertySheet::SetIcon(UINT idIcon)\r
900         {\r
901                 m_PSH.pszIcon = MAKEINTRESOURCE(idIcon);\r
902                 m_PSH.dwFlags |= PSH_USEICONID;\r
903         }\r
904 \r
905         inline void CPropertySheet::SetTitle(LPCTSTR szTitle)\r
906         {\r
907                 if (szTitle)\r
908                         m_Title = szTitle;\r
909                 else\r
910                         m_Title.Empty();\r
911 \r
912                 m_PSH.pszCaption = m_Title;\r
913         }\r
914 \r
915         inline void CPropertySheet::SetWizardMode(BOOL bWizard)\r
916         {\r
917                 if (bWizard)\r
918                         m_PSH.dwFlags |= PSH_WIZARD;\r
919                 else\r
920                         m_PSH.dwFlags &= ~PSH_WIZARD;\r
921         }\r
922 \r
923         inline LRESULT CPropertySheet::WndProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
924         {\r
925                 switch (uMsg)\r
926                 {\r
927 \r
928                 case WM_WINDOWPOSCHANGED:\r
929                         {\r
930                                 LPWINDOWPOS lpWinPos = (LPWINDOWPOS)lParam;\r
931                                 if (lpWinPos->flags & SWP_SHOWWINDOW)\r
932                                 {\r
933                                         if (!m_bInitialUpdate)\r
934                                                 // The first window positioning with the window visible\r
935                                                 OnInitialUpdate();\r
936                                         m_bInitialUpdate = TRUE;\r
937                                 }\r
938                         }\r
939                         break;\r
940 \r
941                 case WM_DESTROY:\r
942                         m_bInitialUpdate = FALSE;\r
943                         break;\r
944 \r
945                 case WM_SYSCOMMAND:\r
946                         if ((SC_CLOSE == wParam) && (m_PSH.dwFlags &  PSH_MODELESS))\r
947                         {\r
948                                 Destroy();\r
949                                 return 0L;\r
950                         }\r
951                         break;\r
952                 }\r
953 \r
954                 // pass unhandled messages on for default processing\r
955                 return CWnd::WndProcDefault(uMsg, wParam, lParam);\r
956         }\r
957 \r
958 }\r
959 \r
960 #endif // _WIN32XX_PROPERTYSHEET_H_\r

UCC git Repository :: git.ucc.asn.au