Commit before breaking everything
[matches/honours.git] / research / transmission_spectroscopy / TOF / Win32++ / include / dialog.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 // dialog.h\r
40 //  Declaration of the CDialog class\r
41 \r
42 // CDialog adds support for dialogs to Win32++. Dialogs are specialised\r
43 // windows which are a parent window for common controls. Common controls\r
44 // are special window types such as buttons, edit controls, tree views,\r
45 // list views, static text etc.\r
46 \r
47 // The layout of a dialog is typically defined in a resource script file\r
48 // (often Resource.rc). While this script file can be constructed manually,\r
49 // it is often created using a resource editor. If your compiler doesn't\r
50 // include a resource editor, you might find ResEdit useful. It is a free\r
51 // resource editor available for download at:\r
52 // http://www.resedit.net/\r
53 \r
54 // CDialog supports modal and modeless dialogs. It also supports the creation\r
55 // of dialogs defined in a resource script file, as well as those defined in\r
56 // a dialog template.\r
57 \r
58 // Use the Dialog generic program as the starting point for your own dialog\r
59 // applications.\r
60 // The DlgSubclass sample demonstrates how to use subclassing to customise\r
61 // the behaviour of common controls in a dialog.\r
62 \r
63 \r
64 #ifndef _WIN32XX_DIALOG_H_\r
65 #define _WIN32XX_DIALOG_H_\r
66 \r
67 #include "wincore.h"\r
68 \r
69 #ifndef SWP_NOCOPYBITS\r
70         #define SWP_NOCOPYBITS      0x0100\r
71 #endif\r
72 \r
73 #define IDLE_TIMER_ID 300\r
74 \r
75 namespace Win32xx\r
76 {\r
77 \r
78         class CDialog : public CWnd\r
79         {\r
80         public:\r
81                 CDialog(UINT nResID, CWnd* pParent = NULL);\r
82                 CDialog(LPCTSTR lpszResName, CWnd* pParent = NULL);\r
83                 CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent = NULL);\r
84                 virtual ~CDialog();\r
85 \r
86                 // You probably won't need to override these functions\r
87                 virtual void AttachItem(int nID, CWnd& Wnd);\r
88                 virtual HWND Create(CWnd* pParent = NULL);\r
89                 virtual INT_PTR DoModal();\r
90                 virtual HWND DoModeless();\r
91                 virtual void SetDlgParent(CWnd* pParent);\r
92                 BOOL IsModal() const { return m_IsModal; }\r
93                 BOOL IsIndirect() const { return (NULL != m_lpTemplate); }\r
94 \r
95         protected:\r
96                 // These are the functions you might wish to override\r
97                 virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
98                 virtual INT_PTR DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
99                 virtual void EndDialog(INT_PTR nResult);\r
100                 virtual void OnCancel();\r
101                 virtual BOOL OnInitDialog();\r
102                 virtual void OnOK();\r
103                 virtual BOOL PreTranslateMessage(MSG* pMsg);\r
104 \r
105                 // Can't override these functions\r
106                 static INT_PTR CALLBACK StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);\r
107 \r
108         #ifndef _WIN32_WCE\r
109                 static LRESULT CALLBACK StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam);\r
110         #endif\r
111 \r
112         private:\r
113                 CDialog(const CDialog&);                          // Disable copy construction\r
114                 CDialog& operator = (const CDialog&); // Disable assignment operator\r
115 \r
116                 BOOL m_IsModal;                                 // a flag for modal dialogs\r
117                 LPCTSTR m_lpszResName;                  // the resource name for the dialog\r
118                 LPCDLGTEMPLATE m_lpTemplate;    // the dialog template for indirect dialogs\r
119                 HWND m_hParent;                                 // handle to the dialogs's parent window\r
120         };\r
121 \r
122 \r
123 #ifndef _WIN32_WCE\r
124 \r
125     //////////////////////////////////////\r
126     // Declaration of the CResizer class\r
127     //\r
128     // The CResizer class can be used to rearrange a dialog's child\r
129     // windows when the dialog is resized.\r
130 \r
131     // To use CResizer, follow the following steps:\r
132     // 1) Use Initialize to specify the dialog's CWnd, and min and max size.\r
133     // 3) Use AddChild for each child window\r
134     // 4) Call HandleMessage from within DialogProc.\r
135     //\r
136 \r
137         // Resize Dialog Styles\r
138 #define RD_STRETCH_WIDTH                0x0001  // The item has a variable width\r
139 #define RD_STRETCH_HEIGHT               0x0002  // The item has a variable height\r
140 \r
141         // Resize Dialog alignments\r
142         enum Alignment { topleft, topright, bottomleft, bottomright };\r
143 \r
144     class CResizer\r
145     {\r
146         public:\r
147                 CResizer() : m_pParent(0), m_xScrollPos(0), m_yScrollPos(0) {}\r
148                 virtual ~CResizer() {}\r
149 \r
150         virtual void AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle);\r
151                 virtual void AddChild(HWND hWnd, Alignment corner, DWORD dwStyle);\r
152                 virtual void HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam);\r
153         virtual void Initialize(CWnd* pParent, RECT rcMin, RECT rcMax = CRect(0,0,0,0));\r
154                 virtual void OnHScroll(WPARAM wParam, LPARAM lParam);\r
155                 virtual void OnVScroll(WPARAM wParam, LPARAM lParam);\r
156                 virtual void RecalcLayout();\r
157                 CRect GetMinRect() const { return m_rcMin; }\r
158                 CRect GetMaxRect() const { return m_rcMax; }\r
159 \r
160                 struct ResizeData\r
161                 {\r
162                         CRect rcInit;\r
163                         CRect rcOld;\r
164                         Alignment corner;\r
165                         BOOL bFixedWidth;\r
166                         BOOL bFixedHeight;\r
167                 HWND hWnd;\r
168                 };\r
169 \r
170     private:\r
171         CWnd* m_pParent;\r
172         std::vector<ResizeData> m_vResizeData;\r
173 \r
174         CRect m_rcInit;\r
175         CRect m_rcMin;\r
176         CRect m_rcMax;\r
177 \r
178                 int m_xScrollPos;\r
179                 int m_yScrollPos;\r
180     };\r
181 \r
182 #endif\r
183 \r
184 }\r
185 \r
186 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
187 \r
188 \r
189 namespace Win32xx\r
190 {\r
191     ////////////////////////////////////\r
192         // Definitions for the CDialog class\r
193         //\r
194         inline CDialog::CDialog(LPCTSTR lpszResName, CWnd* pParent/* = NULL*/)\r
195                 : m_IsModal(TRUE), m_lpszResName(lpszResName), m_lpTemplate(NULL)\r
196         {\r
197                 m_hParent = pParent? pParent->GetHwnd() : NULL;\r
198                 ::InitCommonControls();\r
199         }\r
200 \r
201         inline CDialog::CDialog(UINT nResID, CWnd* pParent/* = NULL*/)\r
202                 : m_IsModal(TRUE), m_lpszResName(MAKEINTRESOURCE (nResID)), m_lpTemplate(NULL)\r
203         {\r
204                 m_hParent = pParent? pParent->GetHwnd() : NULL;\r
205                 ::InitCommonControls();\r
206         }\r
207 \r
208         //For indirect dialogs - created from a dialog box template in memory.\r
209         inline CDialog::CDialog(LPCDLGTEMPLATE lpTemplate, CWnd* pParent/* = NULL*/)\r
210                 : m_IsModal(TRUE), m_lpszResName(NULL), m_lpTemplate(lpTemplate)\r
211         {\r
212                 m_hParent = pParent? pParent->GetHwnd() : NULL;\r
213                 ::InitCommonControls();\r
214         }\r
215 \r
216         inline CDialog::~CDialog()\r
217         {\r
218                 if (m_hWnd != NULL)\r
219                 {\r
220                         if (IsModal())\r
221                                 ::EndDialog(m_hWnd, 0);\r
222                         else\r
223                                 Destroy();\r
224                 }\r
225         }\r
226 \r
227         inline void CDialog::AttachItem(int nID, CWnd& Wnd)\r
228         // Attach a dialog item to a CWnd\r
229         {\r
230                 Wnd.AttachDlgItem(nID, this);\r
231         }\r
232 \r
233         inline HWND CDialog::Create(CWnd* pParent /* = NULL */)\r
234         {\r
235                 // Allow a dialog to be used as a child window\r
236 \r
237                 assert(GetApp());\r
238                 SetDlgParent(pParent);\r
239                 return DoModeless();\r
240         }\r
241 \r
242         inline INT_PTR CDialog::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
243         {\r
244                 // Override this function in your class derrived from CDialog if you wish to handle messages\r
245                 // A typical function might look like this:\r
246 \r
247                 //      switch (uMsg)\r
248                 //      {\r
249                 //      case MESSAGE1:          // Some Windows API message\r
250                 //              OnMessage1();   // A user defined function\r
251                 //              break;                  // Also do default processing\r
252                 //      case MESSAGE2:\r
253                 //              OnMessage2();\r
254                 //              return x;               // Don't do default processing, but instead return\r
255                 //                                              //  a value recommended by the Windows API documentation\r
256                 //      }\r
257 \r
258                 // Always pass unhandled messages on to DialogProcDefault\r
259                 return DialogProcDefault(uMsg, wParam, lParam);\r
260         }\r
261 \r
262         inline INT_PTR CDialog::DialogProcDefault(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
263         // All DialogProc functions should pass unhandled messages to this function\r
264         {\r
265                 LRESULT lr = 0;\r
266 \r
267                 switch (uMsg)\r
268             {\r
269                         case WM_TIMER:\r
270                                 if (wParam == IDLE_TIMER_ID)\r
271                                         GetApp()->CleanupTemps();\r
272                         return 0L;\r
273                 case UWM_CLEANUPTEMPS:\r
274                         {\r
275                                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
276                                 pTLSData->vTmpWnds.clear();\r
277                         }\r
278                         break;\r
279             case WM_INITDIALOG:\r
280                         {\r
281                                 // Center the dialog\r
282                                 CenterWindow();\r
283                                 if (IsModal())\r
284                                         SetTimer(IDLE_TIMER_ID, 1000, 0);\r
285                         }\r
286                     return OnInitDialog();\r
287             case WM_COMMAND:\r
288                 switch (LOWORD (wParam))\r
289                 {\r
290                 case IDOK:\r
291                                 OnOK();\r
292                                 return TRUE;\r
293                         case IDCANCEL:\r
294                                 OnCancel();\r
295                                 return TRUE;\r
296                         default:\r
297                                 {\r
298                                         // Refelect this message if it's from a control\r
299                                         CWnd* pWnd = GetApp()->GetCWndFromMap((HWND)lParam);\r
300                                         if (pWnd != NULL)\r
301                                                 lr = pWnd->OnCommand(wParam, lParam);\r
302 \r
303                                         // Handle user commands\r
304                                         if (!lr)\r
305                                                 lr =  OnCommand(wParam, lParam);\r
306 \r
307                                         if (lr) return 0L;\r
308                                 }\r
309                                 break;  // Some commands require default processing\r
310                 }\r
311                 break;\r
312 \r
313                 case WM_NOTIFY:\r
314                         {\r
315                                 // Do Notification reflection if it came from a CWnd object\r
316                                 HWND hwndFrom = ((LPNMHDR)lParam)->hwndFrom;\r
317                                 CWnd* pWndFrom = GetApp()->GetCWndFromMap(hwndFrom);\r
318 \r
319                                 if (pWndFrom != NULL)\r
320                                         lr = pWndFrom->OnNotifyReflect(wParam, lParam);\r
321                                 else\r
322                                 {\r
323                                         // Some controls (eg ListView) have child windows.\r
324                                         // Reflect those notifications too.\r
325                                         CWnd* pWndFromParent = GetApp()->GetCWndFromMap(::GetParent(hwndFrom));\r
326                                         if (pWndFromParent != NULL)\r
327                                                 lr = pWndFromParent->OnNotifyReflect(wParam, lParam);\r
328                                 }\r
329         \r
330                                 // Handle user notifications\r
331                                 if (!lr) lr = OnNotify(wParam, lParam);\r
332 \r
333                                 // Set the return code for notifications\r
334                                 if (IsWindow())\r
335                                         SetWindowLongPtr(DWLP_MSGRESULT, (LONG_PTR)lr);\r
336 \r
337                                 return (BOOL)lr;\r
338                         }\r
339 \r
340                 case WM_PAINT:\r
341                         {\r
342                                 if (::GetUpdateRect(m_hWnd, NULL, FALSE))\r
343                                 {\r
344                                         CPaintDC dc(this);\r
345                                         OnDraw(&dc);\r
346                                 }\r
347                                 else\r
348                                 // RedrawWindow can require repainting without an update rect\r
349                                 {\r
350                                         CClientDC dc(this);\r
351                                         OnDraw(&dc);\r
352                                 }\r
353 \r
354                                 break;\r
355                         }\r
356 \r
357                 case WM_ERASEBKGND:\r
358                         {\r
359                                 CDC dc((HDC)wParam);\r
360                                 BOOL bResult = OnEraseBkgnd(&dc);\r
361                                 dc.Detach();\r
362                                 if (bResult) return TRUE;\r
363                         }\r
364                         break;\r
365 \r
366                 // A set of messages to be reflected back to the control that generated them\r
367                 case WM_CTLCOLORBTN:\r
368                 case WM_CTLCOLOREDIT:\r
369                 case WM_CTLCOLORDLG:\r
370                 case WM_CTLCOLORLISTBOX:\r
371                 case WM_CTLCOLORSCROLLBAR:\r
372                 case WM_CTLCOLORSTATIC:\r
373                 case WM_DRAWITEM:\r
374                 case WM_MEASUREITEM:\r
375                 case WM_DELETEITEM:\r
376                 case WM_COMPAREITEM:\r
377                 case WM_CHARTOITEM:\r
378                 case WM_VKEYTOITEM:\r
379                 case WM_HSCROLL:\r
380                 case WM_VSCROLL:\r
381                 case WM_PARENTNOTIFY:\r
382                         return MessageReflect(m_hWnd, uMsg, wParam, lParam);\r
383 \r
384             } // switch(uMsg)\r
385             return FALSE;\r
386 \r
387         } // INT_PTR CALLBACK CDialog::DialogProc(...)\r
388 \r
389         inline INT_PTR CDialog::DoModal()\r
390         {\r
391                 // Create a modal dialog\r
392                 // A modal dialog box must be closed by the user before the application continues\r
393 \r
394                 assert( GetApp() );             // Test if Win32++ has been started\r
395                 assert(!::IsWindow(m_hWnd));    // Only one window per CWnd instance allowed\r
396 \r
397                 INT_PTR nResult = 0;\r
398 \r
399                 try\r
400                 {\r
401                         m_IsModal=TRUE;\r
402 \r
403                         // Ensure this thread has the TLS index set\r
404                         TLSData* pTLSData = GetApp()->SetTlsIndex();\r
405 \r
406                 #ifndef _WIN32_WCE\r
407                         BOOL IsHookedHere = FALSE;\r
408                         if (NULL == pTLSData->hHook )\r
409                         {\r
410                                 pTLSData->hHook = ::SetWindowsHookEx(WH_MSGFILTER, (HOOKPROC)StaticMsgHook, NULL, ::GetCurrentThreadId());\r
411                                 IsHookedHere = TRUE;\r
412                         }\r
413                 #endif\r
414 \r
415                         HINSTANCE hInstance = GetApp()->GetInstanceHandle();\r
416                         pTLSData->pCWnd = this;\r
417 \r
418                         // Create a modal dialog\r
419                         if (IsIndirect())\r
420                                 nResult = ::DialogBoxIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc);\r
421                         else\r
422                         {\r
423                                 if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG))\r
424                                         hInstance = GetApp()->GetResourceHandle();\r
425                                 nResult = ::DialogBox(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc);\r
426                         }\r
427 \r
428                         // Tidy up\r
429                         m_hWnd = NULL;\r
430                         pTLSData->pCWnd = NULL;\r
431                         GetApp()->CleanupTemps();\r
432 \r
433                 #ifndef _WIN32_WCE\r
434                         if (IsHookedHere)\r
435                         {\r
436                                 ::UnhookWindowsHookEx(pTLSData->hHook);\r
437                                 pTLSData->hHook = NULL;\r
438                         }\r
439                 #endif\r
440 \r
441                         if (nResult == -1)\r
442                                 throw CWinException(_T("Failed to create modal dialog box"));\r
443 \r
444                 }\r
445 \r
446                 catch (const CWinException &e)\r
447                 {\r
448                         TRACE(_T("\n*** Failed to create dialog ***\n"));\r
449                         e.what();       // Display the last error message.\r
450 \r
451                         // eat the exception (don't rethrow)\r
452                 }\r
453 \r
454                 return nResult;\r
455         }\r
456 \r
457         inline HWND CDialog::DoModeless()\r
458         {\r
459                 assert( GetApp() );             // Test if Win32++ has been started\r
460                 assert(!::IsWindow(m_hWnd));    // Only one window per CWnd instance allowed\r
461 \r
462                 try\r
463                 {\r
464                         m_IsModal=FALSE;\r
465 \r
466                         // Ensure this thread has the TLS index set\r
467                         TLSData* pTLSData = GetApp()->SetTlsIndex();\r
468 \r
469                         // Store the CWnd pointer in Thread Local Storage\r
470                         pTLSData->pCWnd = this;\r
471 \r
472                         HINSTANCE hInstance = GetApp()->GetInstanceHandle();\r
473 \r
474                         // Create a modeless dialog\r
475                         if (IsIndirect())\r
476                                 m_hWnd = ::CreateDialogIndirect(hInstance, m_lpTemplate, m_hParent, (DLGPROC)CDialog::StaticDialogProc);\r
477                         else\r
478                         {\r
479                                 if (::FindResource(GetApp()->GetResourceHandle(), m_lpszResName, RT_DIALOG))\r
480                                         hInstance = GetApp()->GetResourceHandle();\r
481 \r
482                                 m_hWnd = ::CreateDialog(hInstance, m_lpszResName, m_hParent, (DLGPROC)CDialog::StaticDialogProc);\r
483                         }\r
484 \r
485                         // Tidy up\r
486                         pTLSData->pCWnd = NULL;\r
487 \r
488                         // Now handle dialog creation failure\r
489                         if (!m_hWnd)\r
490                                 throw CWinException(_T("Failed to create dialog"));\r
491                 }\r
492 \r
493                 catch (const CWinException &e)\r
494                 {\r
495                         TRACE(_T("\n*** Failed to create dialog ***\n"));\r
496                         e.what();       // Display the last error message.\r
497 \r
498                         // eat the exception (don't rethrow)\r
499                 }\r
500 \r
501                 return m_hWnd;\r
502         }\r
503 \r
504         inline void CDialog::EndDialog(INT_PTR nResult)\r
505         {\r
506                 assert(::IsWindow(m_hWnd));\r
507 \r
508                 if (IsModal())\r
509                         ::EndDialog(m_hWnd, nResult);\r
510                 else\r
511                         Destroy();\r
512 \r
513                 m_hWnd = NULL;\r
514         }\r
515 \r
516         inline void CDialog::OnCancel()\r
517         {\r
518                 // Override to customize OnCancel behaviour\r
519                 EndDialog(IDCANCEL);\r
520         }\r
521 \r
522         inline BOOL CDialog::OnInitDialog()\r
523         {\r
524                 // Called when the dialog is initialized\r
525                 // Override it in your derived class to automatically perform tasks\r
526                 // The return value is used by WM_INITDIALOG\r
527 \r
528                 return TRUE;\r
529         }\r
530 \r
531         inline void CDialog::OnOK()\r
532         {\r
533                 // Override to customize OnOK behaviour\r
534                 if ( IsWindow() )\r
535                         EndDialog(IDOK);\r
536         }\r
537 \r
538         inline BOOL CDialog::PreTranslateMessage(MSG* pMsg)\r
539         {\r
540                 // allow the dialog to translate keyboard input\r
541                 if ((pMsg->message >= WM_KEYFIRST) && (pMsg->message <= WM_KEYLAST))\r
542                 {\r
543                         // Process dialog keystrokes for modeless dialogs\r
544                         if (!IsModal())\r
545                         {\r
546                                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
547                                 if (NULL == pTLSData->hHook)\r
548                                 {\r
549                                         if (IsDialogMessage(pMsg))\r
550                                                 return TRUE;\r
551                                 }\r
552                                 else\r
553                                 {\r
554                                         // A modal message loop is running so we can't do IsDialogMessage.\r
555                                         // Avoid having modal dialogs create other windows, because those\r
556                                         // windows will then use the modal dialog's special message loop.\r
557                                         // If you need the dialog to create another window, put it in a\r
558                                         // different thread.\r
559                                 }\r
560                         }\r
561                 }\r
562 \r
563                 return FALSE;\r
564         }\r
565 \r
566         inline void CDialog::SetDlgParent(CWnd* pParent)\r
567         // Allows the parent of the dialog to be set before the dialog is created\r
568         {\r
569                 m_hParent = pParent? pParent->GetHwnd() : NULL;\r
570         }\r
571 \r
572         inline INT_PTR CALLBACK CDialog::StaticDialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)\r
573         {\r
574                 // Find the CWnd pointer mapped to this HWND\r
575                 CDialog* w = (CDialog*)GetApp()->GetCWndFromMap(hWnd);\r
576                 if (0 == w)\r
577                 {\r
578                         // The HWND wasn't in the map, so add it now\r
579                         TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
580                         assert(pTLSData);\r
581 \r
582                         // Retrieve pointer to CWnd object from Thread Local Storage TLS\r
583                         w = (CDialog*)pTLSData->pCWnd;\r
584                         assert(w);\r
585                         pTLSData->pCWnd = NULL;\r
586 \r
587                         // Store the Window pointer into the HWND map\r
588                         w->m_hWnd = hWnd;\r
589                         w->AddToMap();\r
590                 }\r
591 \r
592                 return w->DialogProc(uMsg, wParam, lParam);\r
593 \r
594         } // INT_PTR CALLBACK CDialog::StaticDialogProc(...)\r
595 \r
596 #ifndef _WIN32_WCE\r
597         inline LRESULT CALLBACK CDialog::StaticMsgHook(int nCode, WPARAM wParam, LPARAM lParam)\r
598         {\r
599                 // Used by Modal Dialogs to PreTranslate Messages\r
600                 TLSData* pTLSData = (TLSData*)TlsGetValue(GetApp()->GetTlsIndex());\r
601 \r
602                 if (nCode == MSGF_DIALOGBOX)\r
603                 {\r
604                         MSG* lpMsg = (MSG*) lParam;\r
605 \r
606                         // only pre-translate keyboard events\r
607                         if ((lpMsg->message >= WM_KEYFIRST && lpMsg->message <= WM_KEYLAST))\r
608                         {\r
609                                 for (HWND hWnd = lpMsg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))\r
610                                 {\r
611                                         CDialog* pDialog = (CDialog*)GetApp()->GetCWndFromMap(hWnd);\r
612                                         if (pDialog && (lstrcmp(pDialog->GetClassName(), _T("#32770")) == 0))   // only for dialogs\r
613                                         {\r
614                                                 pDialog->PreTranslateMessage(lpMsg);\r
615                                                 break;\r
616                                         }\r
617                                 }\r
618                         }\r
619                 }\r
620 \r
621                 return ::CallNextHookEx(pTLSData->hHook, nCode, wParam, lParam);\r
622         }\r
623 #endif\r
624 \r
625 \r
626 \r
627 #ifndef _WIN32_WCE\r
628 \r
629     /////////////////////////////////////\r
630         // Definitions for the CResizer class\r
631         //\r
632 \r
633         void inline CResizer::AddChild(CWnd* pWnd, Alignment corner, DWORD dwStyle)\r
634     // Adds a child window (usually a dialog control) to the set of windows managed by\r
635         // the Resizer.\r
636         //\r
637         // The alignment corner should be set to the closest corner of the dialog. Allowed\r
638         // values are topleft, topright, bottomleft, and bottomright.\r
639         // Set bFixedWidth to TRUE if the width should be fixed instead of variable.\r
640         // Set bFixedHeight to TRUE if the height should be fixed instead of variable.\r
641         {\r
642         ResizeData rd;\r
643         rd.corner = corner;\r
644         rd.bFixedWidth  = !(dwStyle & RD_STRETCH_WIDTH);\r
645         rd.bFixedHeight = !(dwStyle & RD_STRETCH_HEIGHT);\r
646                 CRect rcInit = pWnd->GetWindowRect();\r
647                 m_pParent->ScreenToClient(rcInit);\r
648                 rd.rcInit = rcInit;\r
649                 rd.hWnd = pWnd->GetHwnd();\r
650 \r
651                 m_vResizeData.insert(m_vResizeData.begin(), rd);\r
652     }\r
653 \r
654         void inline CResizer::AddChild(HWND hWnd, Alignment corner, DWORD dwStyle)\r
655     // Adds a child window (usually a dialog control) to the set of windows managed by\r
656         // the Resizer. \r
657         {\r
658                 AddChild(FromHandle(hWnd), corner, dwStyle);\r
659         }\r
660 \r
661         inline void CResizer::HandleMessage(UINT uMsg, WPARAM wParam, LPARAM lParam)\r
662         {\r
663                 switch (uMsg)\r
664                 {\r
665                 case WM_SIZE:\r
666                         RecalcLayout();\r
667                         break;\r
668 \r
669                 case WM_HSCROLL:\r
670                         if (0 == lParam)\r
671                                 OnHScroll(wParam, lParam);\r
672                         break;\r
673 \r
674                 case WM_VSCROLL:\r
675                         if (0 == lParam)\r
676                                 OnVScroll(wParam, lParam);\r
677                         break;\r
678                 }\r
679         }\r
680 \r
681     void inline CResizer::Initialize(CWnd* pParent, RECT rcMin, RECT rcMax)\r
682         // Sets up the Resizer by specifying the parent window (usually a dialog),\r
683         //  and the minimum and maximum allowed rectangle sizes.\r
684     {\r
685         assert (NULL != pParent);\r
686 \r
687         m_pParent = pParent;\r
688         m_rcInit = pParent->GetClientRect();\r
689         m_rcMin = rcMin;\r
690         m_rcMax = rcMax;\r
691 \r
692                 // Add scroll bar support to the parent window\r
693                 DWORD dwStyle = (DWORD)m_pParent->GetClassLongPtr(GCL_STYLE);\r
694                 dwStyle |= WS_HSCROLL | WS_VSCROLL;\r
695                 m_pParent->SetClassLongPtr(GCL_STYLE, dwStyle);\r
696     }\r
697 \r
698         void inline CResizer::OnHScroll(WPARAM wParam, LPARAM /*lParam*/)\r
699         {\r
700                 int xNewPos;\r
701 \r
702                 switch (LOWORD(wParam))\r
703                 {\r
704                         case SB_PAGEUP: // User clicked the scroll bar shaft left of the scroll box.\r
705                                 xNewPos = m_xScrollPos - 50;\r
706                                 break;\r
707 \r
708                         case SB_PAGEDOWN: // User clicked the scroll bar shaft right of the scroll box.\r
709                                 xNewPos = m_xScrollPos + 50;\r
710                                 break;\r
711 \r
712                         case SB_LINEUP: // User clicked the left arrow.\r
713                                 xNewPos = m_xScrollPos - 5;\r
714                                 break;\r
715 \r
716                         case SB_LINEDOWN: // User clicked the right arrow.\r
717                                 xNewPos = m_xScrollPos + 5;\r
718                                 break;\r
719 \r
720                         case SB_THUMBPOSITION: // User dragged the scroll box.\r
721                                 xNewPos = HIWORD(wParam);\r
722                                 break;\r
723 \r
724                         case SB_THUMBTRACK: // User dragging the scroll box.\r
725                                 xNewPos = HIWORD(wParam);\r
726                                 break;\r
727 \r
728                         default:\r
729                                 xNewPos = m_xScrollPos;\r
730                 }\r
731 \r
732                 // Scroll the window.\r
733                 xNewPos = MAX(0, xNewPos);\r
734                 xNewPos = MIN( xNewPos, GetMinRect().Width() - m_pParent->GetClientRect().Width() );\r
735                 int xDelta = xNewPos - m_xScrollPos;\r
736                 m_xScrollPos = xNewPos;\r
737                 m_pParent->ScrollWindow(-xDelta, 0, NULL, NULL);\r
738 \r
739                 // Reset the scroll bar.\r
740                 SCROLLINFO si = {0};\r
741                 si.cbSize = sizeof(si);\r
742                 si.fMask  = SIF_POS;\r
743                 si.nPos   = m_xScrollPos;\r
744                 m_pParent->SetScrollInfo(SB_HORZ, si, TRUE);\r
745         }\r
746 \r
747         void inline CResizer::OnVScroll(WPARAM wParam, LPARAM /*lParam*/)\r
748         {\r
749                 int yNewPos;\r
750 \r
751                 switch (LOWORD(wParam))\r
752                 {\r
753                         case SB_PAGEUP: // User clicked the scroll bar shaft above the scroll box.\r
754                                 yNewPos = m_yScrollPos - 50;\r
755                                 break;\r
756 \r
757                         case SB_PAGEDOWN: // User clicked the scroll bar shaft below the scroll box.\r
758                                 yNewPos = m_yScrollPos + 50;\r
759                                 break;\r
760 \r
761                         case SB_LINEUP: // User clicked the top arrow.\r
762                                 yNewPos = m_yScrollPos - 5;\r
763                                 break;\r
764 \r
765                         case SB_LINEDOWN: // User clicked the bottom arrow.\r
766                                 yNewPos = m_yScrollPos + 5;\r
767                                 break;\r
768 \r
769                         case SB_THUMBPOSITION: // User dragged the scroll box.\r
770                                 yNewPos = HIWORD(wParam);\r
771                                 break;\r
772 \r
773                         case SB_THUMBTRACK: // User dragging the scroll box.\r
774                                 yNewPos = HIWORD(wParam);\r
775                                 break;\r
776 \r
777                         default:\r
778                                 yNewPos = m_yScrollPos;\r
779                 }\r
780 \r
781                 // Scroll the window.\r
782                 yNewPos = MAX(0, yNewPos);\r
783                 yNewPos = MIN( yNewPos, GetMinRect().Height() - m_pParent->GetClientRect().Height() );\r
784                 int yDelta = yNewPos - m_yScrollPos;\r
785                 m_yScrollPos = yNewPos;\r
786                 m_pParent->ScrollWindow(0, -yDelta, NULL, NULL);\r
787 \r
788                 // Reset the scroll bar.\r
789                 SCROLLINFO si = {0};\r
790                 si.cbSize = sizeof(si);\r
791                 si.fMask  = SIF_POS;\r
792                 si.nPos   = m_yScrollPos;\r
793                 m_pParent->SetScrollInfo(SB_VERT, si, TRUE);\r
794         }\r
795 \r
796     void inline CResizer::RecalcLayout()\r
797     // Repositions the child windows. Call this function when handling\r
798         // the WM_SIZE message in the parent window.\r
799         {\r
800         assert (m_rcInit.Width() > 0 && m_rcInit.Height() > 0);\r
801         assert (NULL != m_pParent);\r
802 \r
803                 CRect rcCurrent = m_pParent->GetClientRect();\r
804 \r
805                 // Adjust the scrolling if required\r
806                 m_xScrollPos = MIN(m_xScrollPos, MAX(0, m_rcMin.Width()  - rcCurrent.Width() ) );\r
807                 m_yScrollPos = MIN(m_yScrollPos, MAX(0, m_rcMin.Height() - rcCurrent.Height()) );\r
808                 SCROLLINFO si = {0};\r
809                 si.cbSize = sizeof(si);\r
810                 si.fMask  = SIF_RANGE | SIF_PAGE | SIF_POS;\r
811                 si.nMax   =     m_rcMin.Width();\r
812                 si.nPage  = rcCurrent.Width();\r
813                 si.nPos   = m_xScrollPos;\r
814                 m_pParent->SetScrollInfo(SB_HORZ, si, TRUE);\r
815                 si.nMax   =     m_rcMin.Height();\r
816                 si.nPage  = rcCurrent.Height();\r
817                 si.nPos   = m_yScrollPos;\r
818                 m_pParent->SetScrollInfo(SB_VERT, si, TRUE);\r
819 \r
820         rcCurrent.right  = MAX( rcCurrent.Width(),  m_rcMin.Width() );\r
821         rcCurrent.bottom = MAX( rcCurrent.Height(), m_rcMin.Height() );\r
822         if (!m_rcMax.IsRectEmpty())\r
823         {\r
824                 rcCurrent.right  = MIN( rcCurrent.Width(),  m_rcMax.Width() );\r
825                 rcCurrent.bottom = MIN( rcCurrent.Height(), m_rcMax.Height() );\r
826         }\r
827 \r
828                 // Declare an iterator to step through the vector\r
829                 std::vector<ResizeData>::iterator iter;\r
830 \r
831         for (iter = m_vResizeData.begin(); iter < m_vResizeData.end(); ++iter)\r
832         {\r
833                 int left   = 0;\r
834                 int top    = 0;\r
835                 int width  = 0;\r
836                 int height = 0;\r
837 \r
838                 // Calculate the new size and position of the child window\r
839                         switch( (*iter).corner )\r
840                 {\r
841                 case topleft:\r
842                                 width  = (*iter).bFixedWidth?  (*iter).rcInit.Width()  : (*iter).rcInit.Width()  - m_rcInit.Width() + rcCurrent.Width();\r
843                         height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();\r
844                         left   = (*iter).rcInit.left;\r
845                         top    = (*iter).rcInit.top;\r
846                         break;\r
847                 case topright:\r
848                         width  = (*iter).bFixedWidth?  (*iter).rcInit.Width()  : (*iter).rcInit.Width()  - m_rcInit.Width() + rcCurrent.Width();\r
849                         height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();\r
850                         left   = (*iter).rcInit.right - width - m_rcInit.Width() + rcCurrent.Width();\r
851                         top    = (*iter).rcInit.top;\r
852                         break;\r
853                 case bottomleft:\r
854                                 width  = (*iter).bFixedWidth?  (*iter).rcInit.Width()  : (*iter).rcInit.Width()  - m_rcInit.Width() + rcCurrent.Width();\r
855                         height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();\r
856                         left   = (*iter).rcInit.left;\r
857                         top    = (*iter).rcInit.bottom - height - m_rcInit.Height() + rcCurrent.Height();\r
858                         break;\r
859                 case bottomright:\r
860                         width  = (*iter).bFixedWidth?  (*iter).rcInit.Width()  : (*iter).rcInit.Width()  - m_rcInit.Width() + rcCurrent.Width();\r
861                         height = (*iter).bFixedHeight? (*iter).rcInit.Height() : (*iter).rcInit.Height() - m_rcInit.Height() + rcCurrent.Height();\r
862                         left   = (*iter).rcInit.right   - width - m_rcInit.Width() + rcCurrent.Width();\r
863                         top    = (*iter).rcInit.bottom  - height - m_rcInit.Height() + rcCurrent.Height();\r
864                         break;\r
865                 }\r
866 \r
867                         // Position the child window.\r
868                         CRect rc(left - m_xScrollPos, top - m_yScrollPos, left + width - m_xScrollPos, top + height - m_yScrollPos);\r
869                         if ( rc != (*iter).rcOld)\r
870                         {\r
871                                 CWnd* pWnd = FromHandle((*iter).hWnd);\r
872                                 CWnd *pWndPrev = pWnd->GetWindow(GW_HWNDPREV); // Trick to maintain the original tab order.\r
873                         //      HWND hWnd = pWndPrev ? pWndPrev->GetHwnd():NULL;\r
874                                 pWnd->SetWindowPos(pWndPrev, rc, SWP_NOCOPYBITS);\r
875                                 (*iter).rcOld = rc;\r
876                         }\r
877         }\r
878     }\r
879 \r
880 #endif // #ifndef _WIN32_WCE\r
881 \r
882 } // namespace Win32xx\r
883 \r
884 \r
885 \r
886 #endif // _WIN32XX_DIALOG_H_\r
887 \r

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