| OLD | NEW | 
| (Empty) |  | 
 |     1 // Windows Template Library - WTL version 8.0 | 
 |     2 // Copyright (C) Microsoft Corporation. All rights reserved. | 
 |     3 // | 
 |     4 // This file is a part of the Windows Template Library. | 
 |     5 // The use and distribution terms for this software are covered by the | 
 |     6 // Microsoft Permissive License (Ms-PL) which can be found in the file | 
 |     7 // Ms-PL.txt at the root of this distribution. | 
 |     8  | 
 |     9 #ifndef __ATLFRAME_H__ | 
 |    10 #define __ATLFRAME_H__ | 
 |    11  | 
 |    12 #pragma once | 
 |    13  | 
 |    14 #ifndef __cplusplus | 
 |    15         #error ATL requires C++ compilation (use a .cpp suffix) | 
 |    16 #endif | 
 |    17  | 
 |    18 #ifndef __ATLAPP_H__ | 
 |    19         #error atlframe.h requires atlapp.h to be included first | 
 |    20 #endif | 
 |    21  | 
 |    22 #ifndef __ATLWIN_H__ | 
 |    23         #error atlframe.h requires atlwin.h to be included first | 
 |    24 #endif | 
 |    25  | 
 |    26  | 
 |    27 /////////////////////////////////////////////////////////////////////////////// | 
 |    28 // Classes in this file: | 
 |    29 // | 
 |    30 // CFrameWindowImpl<T, TBase, TWinTraits> | 
 |    31 // CMDIWindow | 
 |    32 // CMDIFrameWindowImpl<T, TBase, TWinTraits> | 
 |    33 // CMDIChildWindowImpl<T, TBase, TWinTraits> | 
 |    34 // COwnerDraw<T> | 
 |    35 // CUpdateUIBase | 
 |    36 // CUpdateUI<T> | 
 |    37 // CDynamicUpdateUI<T> | 
 |    38 // CDialogResize<T> | 
 |    39 // CDoubleBufferImpl<T> | 
 |    40 // CDoubleBufferWindowImpl<T, TBase, TWinTraits> | 
 |    41 // | 
 |    42 // Global functions: | 
 |    43 //   AtlCreateSimpleToolBar() | 
 |    44  | 
 |    45  | 
 |    46 namespace WTL | 
 |    47 { | 
 |    48  | 
 |    49 /////////////////////////////////////////////////////////////////////////////// | 
 |    50 // CFrameWndClassInfo - Manages frame window Windows class information | 
 |    51  | 
 |    52 class CFrameWndClassInfo | 
 |    53 { | 
 |    54 public: | 
 |    55 #ifndef _WIN32_WCE | 
 |    56         enum { cchAutoName = 5 + sizeof(void*) * 2 };   // sizeof(void*) * 2 is 
      the number of digits %p outputs | 
 |    57         WNDCLASSEX m_wc; | 
 |    58 #else // CE specific | 
 |    59         enum { cchAutoName = MAX_PATH };   // MAX_PATH because this can be set i
      n the wizard generated CMainFrame::ActivatePreviousInstance to a user defined st
      ring. | 
 |    60         WNDCLASS m_wc; | 
 |    61 #endif // !_WIN32_WCE | 
 |    62         LPCTSTR m_lpszOrigName; | 
 |    63         WNDPROC pWndProc; | 
 |    64         LPCTSTR m_lpszCursorID; | 
 |    65         BOOL m_bSystemCursor; | 
 |    66         ATOM m_atom; | 
 |    67         TCHAR m_szAutoName[cchAutoName]; | 
 |    68         UINT m_uCommonResourceID; | 
 |    69  | 
 |    70 #ifndef _WIN32_WCE | 
 |    71         ATOM Register(WNDPROC* pProc) | 
 |    72         { | 
 |    73                 if (m_atom == 0) | 
 |    74                 { | 
 |    75                         CWindowCreateCriticalSectionLock lock; | 
 |    76                         if(FAILED(lock.Lock())) | 
 |    77                         { | 
 |    78                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CFrameWndClassInfo::Register.\n")); | 
 |    79                                 ATLASSERT(FALSE); | 
 |    80                                 return 0; | 
 |    81                         } | 
 |    82  | 
 |    83                         if(m_atom == 0) | 
 |    84                         { | 
 |    85                                 HINSTANCE hInst = ModuleHelper::GetModuleInstanc
      e(); | 
 |    86  | 
 |    87                                 if (m_lpszOrigName != NULL) | 
 |    88                                 { | 
 |    89                                         ATLASSERT(pProc != NULL); | 
 |    90                                         LPCTSTR lpsz = m_wc.lpszClassName; | 
 |    91                                         WNDPROC proc = m_wc.lpfnWndProc; | 
 |    92  | 
 |    93                                         WNDCLASSEX wc = { 0 }; | 
 |    94                                         wc.cbSize = sizeof(WNDCLASSEX); | 
 |    95                                         // try process local class first | 
 |    96                                         if(!::GetClassInfoEx(ModuleHelper::GetMo
      duleInstance(), m_lpszOrigName, &wc)) | 
 |    97                                         { | 
 |    98                                                 // try global class | 
 |    99                                                 if(!::GetClassInfoEx(NULL, m_lps
      zOrigName, &wc)) | 
 |   100                                                 { | 
 |   101                                                         lock.Unlock(); | 
 |   102                                                         return 0; | 
 |   103                                                 } | 
 |   104                                         } | 
 |   105                                         m_wc = wc; | 
 |   106                                         pWndProc = m_wc.lpfnWndProc; | 
 |   107                                         m_wc.lpszClassName = lpsz; | 
 |   108                                         m_wc.lpfnWndProc = proc; | 
 |   109                                 } | 
 |   110                                 else | 
 |   111                                 { | 
 |   112                                         m_wc.hCursor = ::LoadCursor(m_bSystemCur
      sor ? NULL : hInst, m_lpszCursorID); | 
 |   113                                 } | 
 |   114  | 
 |   115                                 m_wc.hInstance = hInst; | 
 |   116                                 m_wc.style &= ~CS_GLOBALCLASS;   // we don't reg
      ister global classes | 
 |   117                                 if (m_wc.lpszClassName == NULL) | 
 |   118                                 { | 
 |   119 #if (_WIN32_WINNT >= 0x0500) || defined(_WIN64) | 
 |   120                                         SecureHelper::wsprintf_x(m_szAutoName, c
      chAutoName, _T("ATL:%p"), &m_wc); | 
 |   121 #else // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) | 
 |   122                                         SecureHelper::wsprintf_x(m_szAutoName, c
      chAutoName, _T("ATL:%8.8X"), (DWORD_PTR)&m_wc); | 
 |   123 #endif // !((_WIN32_WINNT >= 0x0500) || defined(_WIN64)) | 
 |   124                                         m_wc.lpszClassName = m_szAutoName; | 
 |   125                                 } | 
 |   126  | 
 |   127                                 WNDCLASSEX wcTemp = m_wc; | 
 |   128                                 m_atom = (ATOM)::GetClassInfoEx(m_wc.hInstance, 
      m_wc.lpszClassName, &wcTemp); | 
 |   129                                 if (m_atom == 0) | 
 |   130                                 { | 
 |   131                                         if(m_uCommonResourceID != 0)   // use it
       if not zero | 
 |   132                                         { | 
 |   133                                                 m_wc.hIcon = (HICON)::LoadImage(
      ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE
      _ICON, 32, 32, LR_DEFAULTCOLOR); | 
 |   134                                                 m_wc.hIconSm = (HICON)::LoadImag
      e(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMA
      GE_ICON, 16, 16, LR_DEFAULTCOLOR); | 
 |   135                                         } | 
 |   136                                         m_atom = ::RegisterClassEx(&m_wc); | 
 |   137                                 } | 
 |   138                         } | 
 |   139  | 
 |   140                         lock.Unlock(); | 
 |   141                 } | 
 |   142  | 
 |   143                 if (m_lpszOrigName != NULL) | 
 |   144                 { | 
 |   145                         ATLASSERT(pProc != NULL); | 
 |   146                         ATLASSERT(pWndProc != NULL); | 
 |   147                         *pProc = pWndProc; | 
 |   148                 } | 
 |   149  | 
 |   150                 return m_atom; | 
 |   151         } | 
 |   152 #else // CE specific | 
 |   153         ATOM Register(WNDPROC* pProc) | 
 |   154         { | 
 |   155                 if (m_atom == 0) | 
 |   156                 { | 
 |   157                         CWindowCreateCriticalSectionLock lock; | 
 |   158                         if(FAILED(lock.Lock())) | 
 |   159                         { | 
 |   160                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CFrameWndClassInfo::Register.\n")); | 
 |   161                                 ATLASSERT(FALSE); | 
 |   162                                 return 0; | 
 |   163                         } | 
 |   164  | 
 |   165                         if(m_atom == 0) | 
 |   166                         { | 
 |   167                                 HINSTANCE hInst = ModuleHelper::GetModuleInstanc
      e(); | 
 |   168  | 
 |   169                                 if (m_lpszOrigName != NULL) | 
 |   170                                 { | 
 |   171                                         ATLASSERT(pProc != NULL); | 
 |   172                                         LPCTSTR lpsz = m_wc.lpszClassName; | 
 |   173                                         WNDPROC proc = m_wc.lpfnWndProc; | 
 |   174  | 
 |   175                                         WNDCLASS wc = { 0 }; | 
 |   176                                         // try process local class first | 
 |   177                                         if(!::GetClassInfo(ModuleHelper::GetModu
      leInstance(), m_lpszOrigName, &wc)) | 
 |   178                                         { | 
 |   179                                                 // try global class | 
 |   180                                                 if(!::GetClassInfo(NULL, m_lpszO
      rigName, &wc)) | 
 |   181                                                 { | 
 |   182                                                         lock.Unlock(); | 
 |   183                                                         return 0; | 
 |   184                                                 } | 
 |   185                                         } | 
 |   186                                         m_wc = wc; | 
 |   187                                         pWndProc = m_wc.lpfnWndProc; | 
 |   188                                         m_wc.lpszClassName = lpsz; | 
 |   189                                         m_wc.lpfnWndProc = proc; | 
 |   190                                 } | 
 |   191                                 else | 
 |   192                                 { | 
 |   193 #if defined(GWES_CURSOR) || defined(GWES_MCURSOR) | 
 |   194                                         m_wc.hCursor = ::LoadCursor(m_bSystemCur
      sor ? NULL : hInst, m_lpszCursorID); | 
 |   195 #else // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) | 
 |   196                                         m_wc.hCursor = NULL; | 
 |   197 #endif // !(defined(GWES_CURSOR) || defined(GWES_MCURSOR)) | 
 |   198                                 } | 
 |   199  | 
 |   200                                 m_wc.hInstance = hInst; | 
 |   201                                 m_wc.style &= ~CS_GLOBALCLASS;   // we don't reg
      ister global classes | 
 |   202                                 if (m_wc.lpszClassName == NULL) | 
 |   203                                 { | 
 |   204                                         wsprintf(m_szAutoName, _T("ATL:%8.8X"), 
      (DWORD_PTR)&m_wc); | 
 |   205                                         m_wc.lpszClassName = m_szAutoName; | 
 |   206                                 } | 
 |   207  | 
 |   208                                 WNDCLASS wcTemp = m_wc; | 
 |   209                                 m_atom = (ATOM)::GetClassInfo(m_wc.hInstance, m_
      wc.lpszClassName, &wcTemp); | 
 |   210                                 if (m_atom == 0) | 
 |   211                                 { | 
 |   212                                         if(m_uCommonResourceID != 0)   // use it
       if not zero | 
 |   213                                                 m_wc.hIcon = (HICON)::LoadImage(
      ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(m_uCommonResourceID), IMAGE
      _ICON, 32, 32, LR_DEFAULTCOLOR); | 
 |   214                                         m_atom = ::RegisterClass(&m_wc); | 
 |   215                                 } | 
 |   216                         } | 
 |   217  | 
 |   218                         lock.Unlock(); | 
 |   219                 } | 
 |   220  | 
 |   221                 if (m_lpszOrigName != NULL) | 
 |   222                 { | 
 |   223                         ATLASSERT(pProc != NULL); | 
 |   224                         ATLASSERT(pWndProc != NULL); | 
 |   225                         *pProc = pWndProc; | 
 |   226                 } | 
 |   227  | 
 |   228                 return m_atom; | 
 |   229         } | 
 |   230 #endif // _WIN32_WCE | 
 |   231 }; | 
 |   232  | 
 |   233  | 
 |   234 /////////////////////////////////////////////////////////////////////////////// | 
 |   235 // Macros for declaring frame window WNDCLASS | 
 |   236  | 
 |   237 #ifndef _WIN32_WCE | 
 |   238  | 
 |   239 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ | 
 |   240 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   241 { \ | 
 |   242         static WTL::CFrameWndClassInfo wc = \ | 
 |   243         { \ | 
 |   244                 { sizeof(WNDCLASSEX), 0, StartWindowProc, \ | 
 |   245                   0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndC
      lassName, NULL }, \ | 
 |   246                 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ | 
 |   247         }; \ | 
 |   248         return wc; \ | 
 |   249 } | 
 |   250  | 
 |   251 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd
      ) \ | 
 |   252 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   253 { \ | 
 |   254         static WTL::CFrameWndClassInfo wc = \ | 
 |   255         { \ | 
 |   256                 { sizeof(WNDCLASSEX), style, StartWindowProc, \ | 
 |   257                   0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassNam
      e, NULL }, \ | 
 |   258                 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ | 
 |   259         }; \ | 
 |   260         return wc; \ | 
 |   261 } | 
 |   262  | 
 |   263 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonReso
      urceID) \ | 
 |   264 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   265 { \ | 
 |   266         static WTL::CFrameWndClassInfo wc = \ | 
 |   267         { \ | 
 |   268                 { sizeof(WNDCLASSEX), 0, StartWindowProc, \ | 
 |   269                   0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName, NULL }, \ | 
 |   270                 OrigWndClassName, NULL, NULL, TRUE, 0, _T(""), uCommonResourceID
       \ | 
 |   271         }; \ | 
 |   272         return wc; \ | 
 |   273 } | 
 |   274  | 
 |   275 #else // CE specific | 
 |   276  | 
 |   277 #define DECLARE_FRAME_WND_CLASS(WndClassName, uCommonResourceID) \ | 
 |   278 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   279 { \ | 
 |   280         static WTL::CFrameWndClassInfo wc = \ | 
 |   281         { \ | 
 |   282                 { 0, StartWindowProc, \ | 
 |   283                   0, 0, NULL, NULL, NULL, (HBRUSH)(COLOR_WINDOW + 1), NULL, WndC
      lassName }, \ | 
 |   284                 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ | 
 |   285         }; \ | 
 |   286         return wc; \ | 
 |   287 } | 
 |   288  | 
 |   289 #define DECLARE_FRAME_WND_CLASS_EX(WndClassName, uCommonResourceID, style, bkgnd
      ) \ | 
 |   290 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   291 { \ | 
 |   292         static WTL::CFrameWndClassInfo wc = \ | 
 |   293         { \ | 
 |   294                 { style, StartWindowProc, \ | 
 |   295                   0, 0, NULL, NULL, NULL, (HBRUSH)(bkgnd + 1), NULL, WndClassNam
      e }, \ | 
 |   296                 NULL, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResourceID \ | 
 |   297         }; \ | 
 |   298         return wc; \ | 
 |   299 } | 
 |   300  | 
 |   301 #define DECLARE_FRAME_WND_SUPERCLASS(WndClassName, OrigWndClassName, uCommonReso
      urceID) \ | 
 |   302 static WTL::CFrameWndClassInfo& GetWndClassInfo() \ | 
 |   303 { \ | 
 |   304         static WTL::CFrameWndClassInfo wc = \ | 
 |   305         { \ | 
 |   306                 { NULL, StartWindowProc, \ | 
 |   307                   0, 0, NULL, NULL, NULL, NULL, NULL, WndClassName }, \ | 
 |   308                 OrigWndClassName, NULL, IDC_ARROW, TRUE, 0, _T(""), uCommonResou
      rceID \ | 
 |   309         }; \ | 
 |   310         return wc; \ | 
 |   311 } | 
 |   312  | 
 |   313 #endif // !_WIN32_WCE | 
 |   314  | 
 |   315  | 
 |   316 /////////////////////////////////////////////////////////////////////////////// | 
 |   317 // CFrameWindowImpl | 
 |   318  | 
 |   319 // Client window command chaining macro (only for frame windows) | 
 |   320 #define CHAIN_CLIENT_COMMANDS() \ | 
 |   321         if(uMsg == WM_COMMAND && m_hWndClient != NULL) \ | 
 |   322                 ::SendMessage(m_hWndClient, uMsg, wParam, lParam); | 
 |   323  | 
 |   324 // standard toolbar styles | 
 |   325 #define ATL_SIMPLE_TOOLBAR_STYLE \ | 
 |   326         (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | TBSTYLE_TOO
      LTIPS) | 
 |   327 // toolbar in a rebar pane | 
 |   328 #define ATL_SIMPLE_TOOLBAR_PANE_STYLE \ | 
 |   329         (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CCS_NODIVID
      ER | CCS_NORESIZE | CCS_NOPARENTALIGN | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT) | 
 |   330 // standard rebar styles | 
 |   331 #if (_WIN32_IE >= 0x0400) | 
 |   332   #define ATL_SIMPLE_REBAR_STYLE \ | 
 |   333         (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
       RBS_VARHEIGHT | RBS_BANDBORDERS | RBS_AUTOSIZE) | 
 |   334 #else | 
 |   335   #define ATL_SIMPLE_REBAR_STYLE \ | 
 |   336         (WS_CHILD | WS_VISIBLE | WS_BORDER | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
       RBS_VARHEIGHT | RBS_BANDBORDERS) | 
 |   337 #endif // !(_WIN32_IE >= 0x0400) | 
 |   338 // rebar without borders | 
 |   339 #if (_WIN32_IE >= 0x0400) | 
 |   340   #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ | 
 |   341         (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIG
      HT | RBS_BANDBORDERS | RBS_AUTOSIZE | CCS_NODIVIDER) | 
 |   342 #else | 
 |   343   #define ATL_SIMPLE_REBAR_NOBORDER_STYLE \ | 
 |   344         (WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | RBS_VARHEIG
      HT | RBS_BANDBORDERS | CCS_NODIVIDER) | 
 |   345 #endif // !(_WIN32_IE >= 0x0400) | 
 |   346  | 
 |   347 // command bar support | 
 |   348 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) | 
 |   349  | 
 |   350 #define CBRM_GETCMDBAR                  (WM_USER + 301) // returns command bar H
      WND | 
 |   351 #define CBRM_GETMENU                    (WM_USER + 302) // returns loaded or att
      ached menu | 
 |   352 #define CBRM_TRACKPOPUPMENU             (WM_USER + 303) // displays a popup menu | 
 |   353  | 
 |   354 struct _AtlFrameWnd_CmdBarPopupMenu | 
 |   355 { | 
 |   356         int cbSize; | 
 |   357         HMENU hMenu; | 
 |   358         UINT uFlags; | 
 |   359         int x; | 
 |   360         int y; | 
 |   361         LPTPMPARAMS lptpm; | 
 |   362 }; | 
 |   363  | 
 |   364 #define CBRPOPUPMENU _AtlFrameWnd_CmdBarPopupMenu | 
 |   365  | 
 |   366 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) | 
 |   367  | 
 |   368  | 
 |   369 template <class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWinTraits> | 
 |   370 class ATL_NO_VTABLE CFrameWindowImplBase : public ATL::CWindowImplBaseT< TBase, 
      TWinTraits > | 
 |   371 { | 
 |   372 public: | 
 |   373         DECLARE_FRAME_WND_CLASS(NULL, 0) | 
 |   374  | 
 |   375 // Data members | 
 |   376         HWND m_hWndToolBar; | 
 |   377         HWND m_hWndStatusBar; | 
 |   378         HWND m_hWndClient; | 
 |   379  | 
 |   380         HACCEL m_hAccel; | 
 |   381  | 
 |   382 #ifdef _WIN32_WCE | 
 |   383         HWND m_hWndCECommandBar; | 
 |   384 #endif // _WIN32_WCE | 
 |   385  | 
 |   386         struct _AtlToolBarData | 
 |   387         { | 
 |   388                 WORD wVersion; | 
 |   389                 WORD wWidth; | 
 |   390                 WORD wHeight; | 
 |   391                 WORD wItemCount; | 
 |   392                 //WORD aItems[wItemCount] | 
 |   393  | 
 |   394                 WORD* items() | 
 |   395                         { return (WORD*)(this+1); } | 
 |   396         }; | 
 |   397  | 
 |   398 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |   399         struct _ChevronMenuInfo | 
 |   400         { | 
 |   401                 HMENU hMenu; | 
 |   402                 LPNMREBARCHEVRON lpnm; | 
 |   403                 bool bCmdBar; | 
 |   404         }; | 
 |   405 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |   406  | 
 |   407 // Constructor | 
 |   408         CFrameWindowImplBase() :  | 
 |   409 #ifdef _WIN32_WCE | 
 |   410                 m_hWndCECommandBar(NULL), | 
 |   411 #endif // _WIN32_WCE | 
 |   412                 m_hWndToolBar(NULL),  | 
 |   413                 m_hWndStatusBar(NULL),  | 
 |   414                 m_hWndClient(NULL),  | 
 |   415                 m_hAccel(NULL) | 
 |   416         { } | 
 |   417  | 
 |   418 // Methods | 
 |   419         HWND Create(HWND hWndParent, ATL::_U_RECT rect, LPCTSTR szWindowName, DW
      ORD dwStyle, DWORD dwExStyle, ATL::_U_MENUorID MenuOrID, ATOM atom, LPVOID lpCre
      ateParam) | 
 |   420         { | 
 |   421                 ATLASSERT(m_hWnd == NULL); | 
 |   422  | 
 |   423                 if(atom == 0) | 
 |   424                         return NULL; | 
 |   425  | 
 |   426                 ModuleHelper::AddCreateWndData(&m_thunk.cd, this); | 
 |   427  | 
 |   428                 if(MenuOrID.m_hMenu == NULL && (dwStyle & WS_CHILD)) | 
 |   429                         MenuOrID.m_hMenu = (HMENU)(UINT_PTR)this; | 
 |   430                 if(rect.m_lpRect == NULL) | 
 |   431                         rect.m_lpRect = &TBase::rcDefault; | 
 |   432  | 
 |   433                 HWND hWnd = ::CreateWindowEx(dwExStyle, MAKEINTATOM(atom), szWin
      dowName, | 
 |   434                         dwStyle, rect.m_lpRect->left, rect.m_lpRect->top, rect.m
      _lpRect->right - rect.m_lpRect->left, | 
 |   435                         rect.m_lpRect->bottom - rect.m_lpRect->top, hWndParent, 
      MenuOrID.m_hMenu, | 
 |   436                         ModuleHelper::GetModuleInstance(), lpCreateParam); | 
 |   437  | 
 |   438                 ATLASSERT(hWnd == NULL || m_hWnd == hWnd); | 
 |   439  | 
 |   440                 return hWnd; | 
 |   441         } | 
 |   442  | 
 |   443         static HWND CreateSimpleToolBarCtrl(HWND hWndParent, UINT nResourceID, B
      OOL bInitialSeparator = FALSE,  | 
 |   444                         DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL
      _IDW_TOOLBAR) | 
 |   445         { | 
 |   446                 HINSTANCE hInst = ModuleHelper::GetResourceInstance(); | 
 |   447                 HRSRC hRsrc = ::FindResource(hInst, MAKEINTRESOURCE(nResourceID)
      , RT_TOOLBAR); | 
 |   448                 if (hRsrc == NULL) | 
 |   449                         return NULL; | 
 |   450  | 
 |   451                 HGLOBAL hGlobal = ::LoadResource(hInst, hRsrc); | 
 |   452                 if (hGlobal == NULL) | 
 |   453                         return NULL; | 
 |   454  | 
 |   455                 _AtlToolBarData* pData = (_AtlToolBarData*)::LockResource(hGloba
      l); | 
 |   456                 if (pData == NULL) | 
 |   457                         return NULL; | 
 |   458                 ATLASSERT(pData->wVersion == 1); | 
 |   459  | 
 |   460                 WORD* pItems = pData->items(); | 
 |   461                 int nItems = pData->wItemCount + (bInitialSeparator ? 1 : 0); | 
 |   462                 CTempBuffer<TBBUTTON, _WTL_STACK_ALLOC_THRESHOLD> buff; | 
 |   463                 TBBUTTON* pTBBtn = buff.Allocate(nItems); | 
 |   464                 ATLASSERT(pTBBtn != NULL); | 
 |   465                 if(pTBBtn == NULL) | 
 |   466                         return NULL; | 
 |   467  | 
 |   468                 const int cxSeparator = 8; | 
 |   469  | 
 |   470                 // set initial separator (half width) | 
 |   471                 if(bInitialSeparator) | 
 |   472                 { | 
 |   473                         pTBBtn[0].iBitmap = cxSeparator / 2; | 
 |   474                         pTBBtn[0].idCommand = 0; | 
 |   475                         pTBBtn[0].fsState = 0; | 
 |   476                         pTBBtn[0].fsStyle = TBSTYLE_SEP; | 
 |   477                         pTBBtn[0].dwData = 0; | 
 |   478                         pTBBtn[0].iString = 0; | 
 |   479                 } | 
 |   480  | 
 |   481                 int nBmp = 0; | 
 |   482                 for(int i = 0, j = bInitialSeparator ? 1 : 0; i < pData->wItemCo
      unt; i++, j++) | 
 |   483                 { | 
 |   484                         if(pItems[i] != 0) | 
 |   485                         { | 
 |   486                                 pTBBtn[j].iBitmap = nBmp++; | 
 |   487                                 pTBBtn[j].idCommand = pItems[i]; | 
 |   488                                 pTBBtn[j].fsState = TBSTATE_ENABLED; | 
 |   489                                 pTBBtn[j].fsStyle = TBSTYLE_BUTTON; | 
 |   490                                 pTBBtn[j].dwData = 0; | 
 |   491                                 pTBBtn[j].iString = 0; | 
 |   492                         } | 
 |   493                         else | 
 |   494                         { | 
 |   495                                 pTBBtn[j].iBitmap = cxSeparator; | 
 |   496                                 pTBBtn[j].idCommand = 0; | 
 |   497                                 pTBBtn[j].fsState = 0; | 
 |   498                                 pTBBtn[j].fsStyle = TBSTYLE_SEP; | 
 |   499                                 pTBBtn[j].dwData = 0; | 
 |   500                                 pTBBtn[j].iString = 0; | 
 |   501                         } | 
 |   502                 } | 
 |   503  | 
 |   504 #ifndef _WIN32_WCE | 
 |   505                 HWND hWnd = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, dwStyle,
       0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModuleIn
      stance(), NULL); | 
 |   506                 if(hWnd == NULL) | 
 |   507                 { | 
 |   508                         ATLASSERT(FALSE); | 
 |   509                         return NULL; | 
 |   510                 } | 
 |   511 #else // CE specific | 
 |   512                 dwStyle; | 
 |   513                 nID; | 
 |   514                 // The toolbar must go onto the existing CommandBar or MenuBar | 
 |   515                 HWND hWnd = hWndParent; | 
 |   516 #endif // _WIN32_WCE | 
 |   517  | 
 |   518                 ::SendMessage(hWnd, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0L); | 
 |   519  | 
 |   520                 // check if font is taller than our bitmaps | 
 |   521                 CFontHandle font = (HFONT)::SendMessage(hWnd, WM_GETFONT, 0, 0L)
      ; | 
 |   522                 if(font.IsNull()) | 
 |   523                         font = AtlGetDefaultGuiFont(); | 
 |   524                 LOGFONT lf = { 0 }; | 
 |   525                 font.GetLogFont(lf); | 
 |   526                 WORD cyFontHeight = (WORD)abs(lf.lfHeight); | 
 |   527  | 
 |   528 #ifndef _WIN32_WCE | 
 |   529                 WORD bitsPerPixel = AtlGetBitmapResourceBitsPerPixel(nResourceID
      ); | 
 |   530                 if(bitsPerPixel > 4) | 
 |   531                 { | 
 |   532                         COLORREF crMask = CLR_DEFAULT; | 
 |   533                         if(bitsPerPixel == 32) | 
 |   534                         { | 
 |   535                                 // 32-bit color bitmap with alpha channel (valid
       for Windows XP and later) | 
 |   536                                 crMask = CLR_NONE; | 
 |   537                         } | 
 |   538                         HIMAGELIST hImageList = ImageList_LoadImage(ModuleHelper
      ::GetResourceInstance(), MAKEINTRESOURCE(nResourceID), pData->wWidth, 1, crMask,
       IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); | 
 |   539                         ATLASSERT(hImageList != NULL); | 
 |   540                         ::SendMessage(hWnd, TB_SETIMAGELIST, 0, (LPARAM)hImageLi
      st); | 
 |   541                 } | 
 |   542                 else | 
 |   543 #endif // !_WIN32_WCE | 
 |   544                 { | 
 |   545                         TBADDBITMAP tbab = { 0 }; | 
 |   546                         tbab.hInst = hInst; | 
 |   547                         tbab.nID = nResourceID; | 
 |   548                         ::SendMessage(hWnd, TB_ADDBITMAP, nBmp, (LPARAM)&tbab); | 
 |   549                 } | 
 |   550  | 
 |   551                 ::SendMessage(hWnd, TB_ADDBUTTONS, nItems, (LPARAM)pTBBtn); | 
 |   552                 ::SendMessage(hWnd, TB_SETBITMAPSIZE, 0, MAKELONG(pData->wWidth,
       __max(pData->wHeight, cyFontHeight))); | 
 |   553                 const int cxyButtonMargin = 7; | 
 |   554                 ::SendMessage(hWnd, TB_SETBUTTONSIZE, 0, MAKELONG(pData->wWidth 
      + cxyButtonMargin, __max(pData->wHeight, cyFontHeight) + cxyButtonMargin)); | 
 |   555  | 
 |   556                 return hWnd; | 
 |   557         } | 
 |   558  | 
 |   559 #ifndef _WIN32_WCE | 
 |   560         static HWND CreateSimpleReBarCtrl(HWND hWndParent, DWORD dwStyle = ATL_S
      IMPLE_REBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) | 
 |   561         { | 
 |   562                 // Ensure style combinations for proper rebar painting | 
 |   563                 if(dwStyle & CCS_NODIVIDER && dwStyle & WS_BORDER) | 
 |   564                         dwStyle &= ~WS_BORDER; | 
 |   565                 else if(!(dwStyle & WS_BORDER) && !(dwStyle & CCS_NODIVIDER)) | 
 |   566                         dwStyle |= CCS_NODIVIDER; | 
 |   567  | 
 |   568                 // Create rebar window | 
 |   569                 HWND hWndReBar = ::CreateWindowEx(0, REBARCLASSNAME, NULL, dwSty
      le, 0, 0, 100, 100, hWndParent, (HMENU)LongToHandle(nID), ModuleHelper::GetModul
      eInstance(), NULL); | 
 |   570                 if(hWndReBar == NULL) | 
 |   571                 { | 
 |   572                         ATLTRACE2(atlTraceUI, 0, _T("Failed to create rebar.\n")
      ); | 
 |   573                         return NULL; | 
 |   574                 } | 
 |   575  | 
 |   576                 // Initialize and send the REBARINFO structure | 
 |   577                 REBARINFO rbi = { 0 }; | 
 |   578                 rbi.cbSize = sizeof(REBARINFO); | 
 |   579                 rbi.fMask  = 0; | 
 |   580                 if(!::SendMessage(hWndReBar, RB_SETBARINFO, 0, (LPARAM)&rbi)) | 
 |   581                 { | 
 |   582                         ATLTRACE2(atlTraceUI, 0, _T("Failed to initialize rebar.
      \n")); | 
 |   583                         ::DestroyWindow(hWndReBar); | 
 |   584                         return NULL; | 
 |   585                 } | 
 |   586  | 
 |   587                 return hWndReBar; | 
 |   588         } | 
 |   589  | 
 |   590         BOOL CreateSimpleReBar(DWORD dwStyle = ATL_SIMPLE_REBAR_STYLE, UINT nID 
      = ATL_IDW_TOOLBAR) | 
 |   591         { | 
 |   592                 ATLASSERT(!::IsWindow(m_hWndToolBar)); | 
 |   593                 m_hWndToolBar = CreateSimpleReBarCtrl(m_hWnd, dwStyle, nID); | 
 |   594                 return (m_hWndToolBar != NULL); | 
 |   595         } | 
 |   596  | 
 |   597         static BOOL AddSimpleReBarBandCtrl(HWND hWndReBar, HWND hWndBand, int nI
      D = 0, LPCTSTR lpstrTitle = NULL, BOOL bNewRow = FALSE, int cxWidth = 0, BOOL bF
      ullWidthAlways = FALSE) | 
 |   598         { | 
 |   599                 ATLASSERT(::IsWindow(hWndReBar));   // must be already created | 
 |   600 #ifdef _DEBUG | 
 |   601                 // block - check if this is really a rebar | 
 |   602                 { | 
 |   603                         TCHAR lpszClassName[sizeof(REBARCLASSNAME)] = { 0 }; | 
 |   604                         ::GetClassName(hWndReBar, lpszClassName, sizeof(REBARCLA
      SSNAME)); | 
 |   605                         ATLASSERT(lstrcmp(lpszClassName, REBARCLASSNAME) == 0); | 
 |   606                 } | 
 |   607 #endif // _DEBUG | 
 |   608                 ATLASSERT(::IsWindow(hWndBand));   // must be already created | 
 |   609  | 
 |   610                 // Get number of buttons on the toolbar | 
 |   611                 int nBtnCount = (int)::SendMessage(hWndBand, TB_BUTTONCOUNT, 0, 
      0L); | 
 |   612  | 
 |   613                 // Set band info structure | 
 |   614                 REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBANDINFO() }
      ; | 
 |   615 #if (_WIN32_IE >= 0x0400) | 
 |   616                 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBB
      IM_ID | RBBIM_SIZE | RBBIM_IDEALSIZE; | 
 |   617 #else | 
 |   618                 rbBand.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_STYLE | RBB
      IM_ID | RBBIM_SIZE; | 
 |   619 #endif // !(_WIN32_IE >= 0x0400) | 
 |   620                 if(lpstrTitle != NULL) | 
 |   621                         rbBand.fMask |= RBBIM_TEXT; | 
 |   622                 rbBand.fStyle = RBBS_CHILDEDGE; | 
 |   623 #if (_WIN32_IE >= 0x0500) | 
 |   624                 if(nBtnCount > 0)   // add chevron style for toolbar with button
      s | 
 |   625                         rbBand.fStyle |= RBBS_USECHEVRON; | 
 |   626 #endif // (_WIN32_IE >= 0x0500) | 
 |   627                 if(bNewRow) | 
 |   628                         rbBand.fStyle |= RBBS_BREAK; | 
 |   629  | 
 |   630                 rbBand.lpText = (LPTSTR)lpstrTitle; | 
 |   631                 rbBand.hwndChild = hWndBand; | 
 |   632                 if(nID == 0)   // calc band ID | 
 |   633                         nID = ATL_IDW_BAND_FIRST + (int)::SendMessage(hWndReBar,
       RB_GETBANDCOUNT, 0, 0L); | 
 |   634                 rbBand.wID = nID; | 
 |   635  | 
 |   636                 // Calculate the size of the band | 
 |   637                 BOOL bRet = FALSE; | 
 |   638                 RECT rcTmp = { 0 }; | 
 |   639                 if(nBtnCount > 0) | 
 |   640                 { | 
 |   641                         bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMRECT, nBt
      nCount - 1, (LPARAM)&rcTmp); | 
 |   642                         ATLASSERT(bRet); | 
 |   643                         rbBand.cx = (cxWidth != 0) ? cxWidth : rcTmp.right; | 
 |   644                         rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; | 
 |   645                         if(bFullWidthAlways) | 
 |   646                         { | 
 |   647                                 rbBand.cxMinChild = rbBand.cx; | 
 |   648                         } | 
 |   649                         else if(lpstrTitle == NULL) | 
 |   650                         { | 
 |   651                                 bRet = (BOOL)::SendMessage(hWndBand, TB_GETITEMR
      ECT, 0, (LPARAM)&rcTmp); | 
 |   652                                 ATLASSERT(bRet); | 
 |   653                                 rbBand.cxMinChild = rcTmp.right; | 
 |   654                         } | 
 |   655                         else | 
 |   656                         { | 
 |   657                                 rbBand.cxMinChild = 0; | 
 |   658                         } | 
 |   659                 } | 
 |   660                 else    // no buttons, either not a toolbar or really has no but
      tons | 
 |   661                 { | 
 |   662                         bRet = ::GetWindowRect(hWndBand, &rcTmp); | 
 |   663                         ATLASSERT(bRet); | 
 |   664                         rbBand.cx = (cxWidth != 0) ? cxWidth : (rcTmp.right - rc
      Tmp.left); | 
 |   665                         rbBand.cxMinChild = bFullWidthAlways ? rbBand.cx : 0; | 
 |   666                         rbBand.cyMinChild = rcTmp.bottom - rcTmp.top; | 
 |   667                 } | 
 |   668  | 
 |   669 #if (_WIN32_IE >= 0x0400) | 
 |   670                 rbBand.cxIdeal = rbBand.cx; | 
 |   671 #endif // (_WIN32_IE >= 0x0400) | 
 |   672  | 
 |   673                 // Add the band | 
 |   674                 LRESULT lRes = ::SendMessage(hWndReBar, RB_INSERTBAND, (WPARAM)-
      1, (LPARAM)&rbBand); | 
 |   675                 if(lRes == 0) | 
 |   676                 { | 
 |   677                         ATLTRACE2(atlTraceUI, 0, _T("Failed to add a band to the
       rebar.\n")); | 
 |   678                         return FALSE; | 
 |   679                 } | 
 |   680  | 
 |   681 #if (_WIN32_IE >= 0x0501) | 
 |   682                 DWORD dwExStyle = (DWORD)::SendMessage(hWndBand, TB_GETEXTENDEDS
      TYLE, 0, 0L); | 
 |   683                 ::SendMessage(hWndBand, TB_SETEXTENDEDSTYLE, 0, dwExStyle | TBST
      YLE_EX_HIDECLIPPEDBUTTONS); | 
 |   684 #endif // (_WIN32_IE >= 0x0501) | 
 |   685  | 
 |   686                 return TRUE; | 
 |   687         } | 
 |   688  | 
 |   689         BOOL AddSimpleReBarBand(HWND hWndBand, LPCTSTR lpstrTitle = NULL, BOOL b
      NewRow = FALSE, int cxWidth = 0, BOOL bFullWidthAlways = FALSE) | 
 |   690         { | 
 |   691                 ATLASSERT(::IsWindow(m_hWndToolBar));   // must be an existing r
      ebar | 
 |   692                 ATLASSERT(::IsWindow(hWndBand));        // must be created | 
 |   693                 return AddSimpleReBarBandCtrl(m_hWndToolBar, hWndBand, 0, lpstrT
      itle, bNewRow, cxWidth, bFullWidthAlways); | 
 |   694         } | 
 |   695  | 
 |   696 #if (_WIN32_IE >= 0x0400) | 
 |   697         void SizeSimpleReBarBands() | 
 |   698         { | 
 |   699                 ATLASSERT(::IsWindow(m_hWndToolBar));   // must be an existing r
      ebar | 
 |   700  | 
 |   701                 int nCount = (int)::SendMessage(m_hWndToolBar, RB_GETBANDCOUNT, 
      0, 0L); | 
 |   702  | 
 |   703                 for(int i = 0; i < nCount; i++) | 
 |   704                 { | 
 |   705                         REBARBANDINFO rbBand = { RunTimeHelper::SizeOf_REBARBAND
      INFO() }; | 
 |   706                         rbBand.fMask = RBBIM_SIZE; | 
 |   707                         BOOL bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_GETBAN
      DINFO, i, (LPARAM)&rbBand); | 
 |   708                         ATLASSERT(bRet); | 
 |   709                         RECT rect = { 0, 0, 0, 0 }; | 
 |   710                         ::SendMessage(m_hWndToolBar, RB_GETBANDBORDERS, i, (LPAR
      AM)&rect); | 
 |   711                         rbBand.cx += rect.left + rect.right; | 
 |   712                         bRet = (BOOL)::SendMessage(m_hWndToolBar, RB_SETBANDINFO
      , i, (LPARAM)&rbBand); | 
 |   713                         ATLASSERT(bRet); | 
 |   714                 } | 
 |   715         } | 
 |   716 #endif // (_WIN32_IE >= 0x0400) | 
 |   717 #endif // _WIN32_WCE | 
 |   718  | 
 |   719 #ifndef _WIN32_WCE | 
 |   720         BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD |
       WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRIP, UINT nID = ATL
      _IDW_STATUS_BAR) | 
 |   721 #else // CE specific | 
 |   722         BOOL CreateSimpleStatusBar(LPCTSTR lpstrText, DWORD dwStyle = WS_CHILD |
       WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL_IDW_STATUS_BAR) | 
 |   723 #endif // _WIN32_WCE | 
 |   724         { | 
 |   725                 ATLASSERT(!::IsWindow(m_hWndStatusBar)); | 
 |   726                 m_hWndStatusBar = ::CreateStatusWindow(dwStyle, lpstrText, m_hWn
      d, nID); | 
 |   727                 return (m_hWndStatusBar != NULL); | 
 |   728         } | 
 |   729  | 
 |   730 #ifndef _WIN32_WCE | 
 |   731         BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwS
      tyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | SBARS_SIZEGRI
      P, UINT nID = ATL_IDW_STATUS_BAR) | 
 |   732 #else // CE specific | 
 |   733         BOOL CreateSimpleStatusBar(UINT nTextID = ATL_IDS_IDLEMESSAGE, DWORD dwS
      tyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, UINT nID = ATL
      _IDW_STATUS_BAR) | 
 |   734 #endif // _WIN32_WCE | 
 |   735         { | 
 |   736                 const int cchMax = 128;   // max text length is 127 for status b
      ars (+1 for null) | 
 |   737                 TCHAR szText[cchMax]; | 
 |   738                 szText[0] = 0; | 
 |   739                 ::LoadString(ModuleHelper::GetResourceInstance(), nTextID, szTex
      t, cchMax); | 
 |   740                 return CreateSimpleStatusBar(szText, dwStyle, nID); | 
 |   741         } | 
 |   742  | 
 |   743 #ifdef _WIN32_WCE | 
 |   744         BOOL CreateSimpleCECommandBar(LPTSTR pszMenu = NULL, WORD iButton = 0, D
      WORD dwFlags = 0, int nCmdBarID = 1) | 
 |   745         { | 
 |   746                 ATLASSERT(m_hWndCECommandBar == NULL); | 
 |   747                 ATLASSERT(m_hWndToolBar == NULL); | 
 |   748  | 
 |   749                 m_hWndCECommandBar = ::CommandBar_Create(ModuleHelper::GetModule
      Instance(), m_hWnd, nCmdBarID); | 
 |   750                 if(m_hWndCECommandBar == NULL) | 
 |   751                         return FALSE; | 
 |   752  | 
 |   753                 m_hWndToolBar = m_hWndCECommandBar; | 
 |   754  | 
 |   755                 BOOL bRet = TRUE; | 
 |   756  | 
 |   757                 if(pszMenu != NULL) | 
 |   758                         bRet &= ::CommandBar_InsertMenubarEx(m_hWndCECommandBar,
       IS_INTRESOURCE(pszMenu) ? ModuleHelper::GetResourceInstance() : NULL, pszMenu, 
      iButton); | 
 |   759  | 
 |   760                 bRet &= ::CommandBar_AddAdornments(m_hWndCECommandBar, dwFlags, 
      0); | 
 |   761  | 
 |   762                 return bRet; | 
 |   763         } | 
 |   764  | 
 |   765 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) | 
 |   766         BOOL CreateSimpleCEMenuBar(UINT nToolBarId = ATL_IDW_MENU_BAR, DWORD dwF
      lags = 0, int nBmpId = 0, int cBmpImages = 0) | 
 |   767         { | 
 |   768                 ATLASSERT(m_hWndCECommandBar == NULL); | 
 |   769  | 
 |   770                 SHMENUBARINFO mbi = { 0 }; | 
 |   771                 mbi.cbSize = sizeof(mbi); | 
 |   772                 mbi.hwndParent = m_hWnd; | 
 |   773                 mbi.dwFlags = dwFlags; | 
 |   774                 mbi.nToolBarId = nToolBarId; | 
 |   775                 mbi.hInstRes  = ModuleHelper::GetResourceInstance(); | 
 |   776                 mbi.nBmpId = nBmpId; | 
 |   777                 mbi.cBmpImages = cBmpImages; | 
 |   778                 mbi.hwndMB = NULL;   // This gets set by SHCreateMenuBar | 
 |   779  | 
 |   780                 BOOL bRet = ::SHCreateMenuBar(&mbi); | 
 |   781                 if(bRet != FALSE) | 
 |   782                 { | 
 |   783                         m_hWndCECommandBar = mbi.hwndMB; | 
 |   784                         SizeToMenuBar(); | 
 |   785                 } | 
 |   786  | 
 |   787                 return bRet; | 
 |   788         } | 
 |   789  | 
 |   790         void SizeToMenuBar()   // for menu bar only | 
 |   791         { | 
 |   792                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   793                 ATLASSERT(::IsWindow(m_hWndCECommandBar)); | 
 |   794  | 
 |   795                 RECT rect = { 0 }; | 
 |   796                 GetWindowRect(&rect); | 
 |   797                 RECT rectMB = { 0 }; | 
 |   798                 ::GetWindowRect(m_hWndCECommandBar, &rectMB); | 
 |   799                 int cy = ::IsWindowVisible(m_hWndCECommandBar) ? rectMB.top - re
      ct.top : rectMB.bottom - rect.top; | 
 |   800                 SetWindowPos(NULL, 0, 0, rect.right - rect.left, cy, SWP_NOZORDE
      R | SWP_NOMOVE); | 
 |   801         } | 
 |   802 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) | 
 |   803 #endif // _WIN32_WCE | 
 |   804  | 
 |   805         void UpdateLayout(BOOL bResizeBars = TRUE) | 
 |   806         { | 
 |   807                 RECT rect = { 0 }; | 
 |   808                 GetClientRect(&rect); | 
 |   809  | 
 |   810                 // position bars and offset their dimensions | 
 |   811                 UpdateBarsPosition(rect, bResizeBars); | 
 |   812  | 
 |   813                 // resize client window | 
 |   814                 if(m_hWndClient != NULL) | 
 |   815                         ::SetWindowPos(m_hWndClient, NULL, rect.left, rect.top, | 
 |   816                                 rect.right - rect.left, rect.bottom - rect.top, | 
 |   817                                 SWP_NOZORDER | SWP_NOACTIVATE); | 
 |   818         } | 
 |   819  | 
 |   820         void UpdateBarsPosition(RECT& rect, BOOL bResizeBars = TRUE) | 
 |   821         { | 
 |   822                 // resize toolbar | 
 |   823                 if(m_hWndToolBar != NULL && ((DWORD)::GetWindowLong(m_hWndToolBa
      r, GWL_STYLE) & WS_VISIBLE)) | 
 |   824                 { | 
 |   825                         if(bResizeBars) | 
 |   826                         { | 
 |   827                                 ::SendMessage(m_hWndToolBar, WM_SIZE, 0, 0); | 
 |   828                                 ::InvalidateRect(m_hWndToolBar, NULL, FALSE); | 
 |   829                         } | 
 |   830                         RECT rectTB = { 0 }; | 
 |   831                         ::GetWindowRect(m_hWndToolBar, &rectTB); | 
 |   832                         rect.top += rectTB.bottom - rectTB.top; | 
 |   833                 } | 
 |   834  | 
 |   835                 // resize status bar | 
 |   836                 if(m_hWndStatusBar != NULL && ((DWORD)::GetWindowLong(m_hWndStat
      usBar, GWL_STYLE) & WS_VISIBLE)) | 
 |   837                 { | 
 |   838                         if(bResizeBars) | 
 |   839                                 ::SendMessage(m_hWndStatusBar, WM_SIZE, 0, 0); | 
 |   840                         RECT rectSB = { 0 }; | 
 |   841                         ::GetWindowRect(m_hWndStatusBar, &rectSB); | 
 |   842                         rect.bottom -= rectSB.bottom - rectSB.top; | 
 |   843                 } | 
 |   844         } | 
 |   845  | 
 |   846         BOOL PreTranslateMessage(MSG* pMsg) | 
 |   847         { | 
 |   848                 if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, 
      pMsg)) | 
 |   849                         return TRUE; | 
 |   850                 return FALSE; | 
 |   851         } | 
 |   852  | 
 |   853         BEGIN_MSG_MAP(CFrameWindowImplBase) | 
 |   854                 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) | 
 |   855 #ifndef _WIN32_WCE | 
 |   856                 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) | 
 |   857 #endif // !_WIN32_WCE | 
 |   858                 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) | 
 |   859                 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) | 
 |   860 #ifndef _WIN32_WCE | 
 |   861                 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOA, OnToolTipTextA) | 
 |   862                 NOTIFY_CODE_HANDLER(TTN_GETDISPINFOW, OnToolTipTextW) | 
 |   863 #endif // !_WIN32_WCE | 
 |   864         END_MSG_MAP() | 
 |   865  | 
 |   866         LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa
      ram*/, BOOL& bHandled) | 
 |   867         { | 
 |   868                 if(m_hWndClient != NULL)   // view will paint itself instead | 
 |   869                         return 1; | 
 |   870  | 
 |   871                 bHandled = FALSE; | 
 |   872                 return 0; | 
 |   873         } | 
 |   874  | 
 |   875 #ifndef _WIN32_WCE | 
 |   876         LRESULT OnMenuSelect(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& 
      bHandled) | 
 |   877         { | 
 |   878                 bHandled = FALSE; | 
 |   879  | 
 |   880                 if(m_hWndStatusBar == NULL) | 
 |   881                         return 1; | 
 |   882  | 
 |   883                 WORD wFlags = HIWORD(wParam); | 
 |   884                 if(wFlags == 0xFFFF && lParam == NULL)   // menu closing | 
 |   885                 { | 
 |   886                         ::SendMessage(m_hWndStatusBar, SB_SIMPLE, FALSE, 0L); | 
 |   887                 } | 
 |   888                 else | 
 |   889                 { | 
 |   890                         const int cchBuff = 256; | 
 |   891                         TCHAR szBuff[cchBuff]; | 
 |   892                         szBuff[0] = 0; | 
 |   893                         if(!(wFlags & MF_POPUP)) | 
 |   894                         { | 
 |   895                                 WORD wID = LOWORD(wParam); | 
 |   896                                 // check for special cases | 
 |   897                                 if(wID >= 0xF000 && wID < 0xF1F0)   // system me
      nu IDs | 
 |   898                                         wID = (WORD)(((wID - 0xF000) >> 4) + ATL
      _IDS_SCFIRST); | 
 |   899                                 else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FI
      LE_MRU_LAST)   // MRU items | 
 |   900                                         wID = ATL_IDS_MRU_FILE; | 
 |   901                                 else if(wID >= ATL_IDM_FIRST_MDICHILD && wID <= 
      ATL_IDM_LAST_MDICHILD)   // MDI child windows | 
 |   902                                         wID = ATL_IDS_MDICHILD; | 
 |   903  | 
 |   904                                 int nRet = ::LoadString(ModuleHelper::GetResourc
      eInstance(), wID, szBuff, cchBuff); | 
 |   905                                 for(int i = 0; i < nRet; i++) | 
 |   906                                 { | 
 |   907                                         if(szBuff[i] == _T('\n')) | 
 |   908                                         { | 
 |   909                                                 szBuff[i] = 0; | 
 |   910                                                 break; | 
 |   911                                         } | 
 |   912                                 } | 
 |   913                         } | 
 |   914                         ::SendMessage(m_hWndStatusBar, SB_SIMPLE, TRUE, 0L); | 
 |   915                         ::SendMessage(m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NO
      BORDERS), (LPARAM)szBuff); | 
 |   916                 } | 
 |   917  | 
 |   918                 return 1; | 
 |   919         } | 
 |   920 #endif // !_WIN32_WCE | 
 |   921  | 
 |   922         LRESULT OnSetFocus(UINT, WPARAM, LPARAM, BOOL& bHandled) | 
 |   923         { | 
 |   924                 if(m_hWndClient != NULL) | 
 |   925                         ::SetFocus(m_hWndClient); | 
 |   926  | 
 |   927                 bHandled = FALSE; | 
 |   928                 return 1; | 
 |   929         } | 
 |   930  | 
 |   931         LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL& bHandled) | 
 |   932         { | 
 |   933                 if((GetStyle() & (WS_CHILD | WS_POPUP)) == 0) | 
 |   934                         ::PostQuitMessage(1); | 
 |   935  | 
 |   936                 bHandled = FALSE; | 
 |   937                 return 1; | 
 |   938         } | 
 |   939  | 
 |   940 #ifndef _WIN32_WCE | 
 |   941         LRESULT OnToolTipTextA(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   942         { | 
 |   943                 LPNMTTDISPINFOA pDispInfo = (LPNMTTDISPINFOA)pnmh; | 
 |   944                 pDispInfo->szText[0] = 0; | 
 |   945  | 
 |   946                 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) | 
 |   947                 { | 
 |   948                         const int cchBuff = 256; | 
 |   949                         char szBuff[cchBuff]; | 
 |   950                         szBuff[0] = 0; | 
 |   951                         int nRet = ::LoadStringA(ModuleHelper::GetResourceInstan
      ce(), idCtrl, szBuff, cchBuff); | 
 |   952                         for(int i = 0; i < nRet; i++) | 
 |   953                         { | 
 |   954                                 if(szBuff[i] == '\n') | 
 |   955                                 { | 
 |   956                                         SecureHelper::strncpyA_x(pDispInfo->szTe
      xt, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); | 
 |   957                                         break; | 
 |   958                                 } | 
 |   959                         } | 
 |   960 #if (_WIN32_IE >= 0x0300) | 
 |   961                         if(nRet > 0)   // string was loaded, save it | 
 |   962                                 pDispInfo->uFlags |= TTF_DI_SETITEM; | 
 |   963 #endif // (_WIN32_IE >= 0x0300) | 
 |   964                 } | 
 |   965  | 
 |   966                 return 0; | 
 |   967         } | 
 |   968  | 
 |   969         LRESULT OnToolTipTextW(int idCtrl, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   970         { | 
 |   971                 LPNMTTDISPINFOW pDispInfo = (LPNMTTDISPINFOW)pnmh; | 
 |   972                 pDispInfo->szText[0] = 0; | 
 |   973  | 
 |   974                 if((idCtrl != 0) && !(pDispInfo->uFlags & TTF_IDISHWND)) | 
 |   975                 { | 
 |   976                         const int cchBuff = 256; | 
 |   977                         wchar_t szBuff[cchBuff]; | 
 |   978                         szBuff[0] = 0; | 
 |   979                         int nRet = ::LoadStringW(ModuleHelper::GetResourceInstan
      ce(), idCtrl, szBuff, cchBuff); | 
 |   980                         for(int i = 0; i < nRet; i++) | 
 |   981                         { | 
 |   982                                 if(szBuff[i] == L'\n') | 
 |   983                                 { | 
 |   984                                         SecureHelper::strncpyW_x(pDispInfo->szTe
      xt, _countof(pDispInfo->szText), &szBuff[i + 1], _TRUNCATE); | 
 |   985                                         break; | 
 |   986                                 } | 
 |   987                         } | 
 |   988 #if (_WIN32_IE >= 0x0300) | 
 |   989                         if(nRet > 0)   // string was loaded, save it | 
 |   990                                 pDispInfo->uFlags |= TTF_DI_SETITEM; | 
 |   991 #endif // (_WIN32_IE >= 0x0300) | 
 |   992                 } | 
 |   993  | 
 |   994                 return 0; | 
 |   995         } | 
 |   996 #endif // !_WIN32_WCE | 
 |   997  | 
 |   998 // Implementation - chevron menu support | 
 |   999 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1000         bool PrepareChevronMenu(_ChevronMenuInfo& cmi) | 
 |  1001         { | 
 |  1002                 // get rebar and toolbar | 
 |  1003                 REBARBANDINFO rbbi = { RunTimeHelper::SizeOf_REBARBANDINFO() }; | 
 |  1004                 rbbi.fMask = RBBIM_CHILD; | 
 |  1005                 BOOL bRet = (BOOL)::SendMessage(cmi.lpnm->hdr.hwndFrom, RB_GETBA
      NDINFO, cmi.lpnm->uBand, (LPARAM)&rbbi); | 
 |  1006                 ATLASSERT(bRet); | 
 |  1007  | 
 |  1008                 // assume the band is a toolbar | 
 |  1009                 ATL::CWindow wnd = rbbi.hwndChild; | 
 |  1010                 int nCount = (int)wnd.SendMessage(TB_BUTTONCOUNT); | 
 |  1011                 if(nCount <= 0)   // probably not a toolbar | 
 |  1012                         return false; | 
 |  1013  | 
 |  1014                 // check if it's a command bar | 
 |  1015                 CMenuHandle menuCmdBar = (HMENU)wnd.SendMessage(CBRM_GETMENU); | 
 |  1016                 cmi.bCmdBar = (menuCmdBar.m_hMenu != NULL); | 
 |  1017  | 
 |  1018                 // build a menu from hidden items | 
 |  1019                 CMenuHandle menu; | 
 |  1020                 bRet = menu.CreatePopupMenu(); | 
 |  1021                 ATLASSERT(bRet); | 
 |  1022                 RECT rcClient = { 0 }; | 
 |  1023                 bRet = wnd.GetClientRect(&rcClient); | 
 |  1024                 ATLASSERT(bRet); | 
 |  1025                 for(int i = 0; i < nCount; i++) | 
 |  1026                 { | 
 |  1027                         TBBUTTON tbb = { 0 }; | 
 |  1028                         bRet = (BOOL)wnd.SendMessage(TB_GETBUTTON, i, (LPARAM)&t
      bb); | 
 |  1029                         ATLASSERT(bRet); | 
 |  1030                         // skip hidden buttons | 
 |  1031                         if((tbb.fsState & TBSTATE_HIDDEN) != 0) | 
 |  1032                                 continue; | 
 |  1033                         RECT rcButton = { 0 }; | 
 |  1034                         bRet = (BOOL)wnd.SendMessage(TB_GETITEMRECT, i, (LPARAM)
      &rcButton); | 
 |  1035                         ATLASSERT(bRet); | 
 |  1036                         bool bEnabled = ((tbb.fsState & TBSTATE_ENABLED) != 0); | 
 |  1037                         if(rcButton.right > rcClient.right) | 
 |  1038                         { | 
 |  1039                                 if(tbb.fsStyle & BTNS_SEP) | 
 |  1040                                 { | 
 |  1041                                         if(menu.GetMenuItemCount() > 0) | 
 |  1042                                                 menu.AppendMenu(MF_SEPARATOR); | 
 |  1043                                 } | 
 |  1044                                 else if(cmi.bCmdBar) | 
 |  1045                                 { | 
 |  1046                                         const int cchBuff = 200; | 
 |  1047                                         TCHAR szBuff[cchBuff] = { 0 }; | 
 |  1048                                         CMenuItemInfo mii; | 
 |  1049                                         mii.fMask = MIIM_TYPE | MIIM_SUBMENU; | 
 |  1050                                         mii.dwTypeData = szBuff; | 
 |  1051                                         mii.cch = cchBuff; | 
 |  1052                                         bRet = menuCmdBar.GetMenuItemInfo(i, TRU
      E, &mii); | 
 |  1053                                         ATLASSERT(bRet); | 
 |  1054                                         // Note: CmdBar currently supports only 
      drop-down items | 
 |  1055                                         ATLASSERT(::IsMenu(mii.hSubMenu)); | 
 |  1056                                         bRet = menu.AppendMenu(MF_STRING | MF_PO
      PUP | (bEnabled ? MF_ENABLED : MF_GRAYED), (UINT_PTR)mii.hSubMenu, mii.dwTypeDat
      a); | 
 |  1057                                         ATLASSERT(bRet); | 
 |  1058                                 } | 
 |  1059                                 else | 
 |  1060                                 { | 
 |  1061                                         // get button's text | 
 |  1062                                         const int cchBuff = 200; | 
 |  1063                                         TCHAR szBuff[cchBuff] = { 0 }; | 
 |  1064                                         LPTSTR lpstrText = szBuff; | 
 |  1065                                         TBBUTTONINFO tbbi = { 0 }; | 
 |  1066                                         tbbi.cbSize = sizeof(TBBUTTONINFO); | 
 |  1067                                         tbbi.dwMask = TBIF_TEXT; | 
 |  1068                                         tbbi.pszText = szBuff; | 
 |  1069                                         tbbi.cchText = cchBuff; | 
 |  1070                                         if(wnd.SendMessage(TB_GETBUTTONINFO, tbb
      .idCommand, (LPARAM)&tbbi) == -1 || lstrlen(szBuff) == 0) | 
 |  1071                                         { | 
 |  1072                                                 // no text for this button, try 
      a resource string | 
 |  1073                                                 lpstrText = _T(""); | 
 |  1074                                                 int nRet = ::LoadString(ModuleHe
      lper::GetResourceInstance(), tbb.idCommand, szBuff, cchBuff); | 
 |  1075                                                 for(int n = 0; n < nRet; n++) | 
 |  1076                                                 { | 
 |  1077                                                         if(szBuff[n] == _T('\n')
      ) | 
 |  1078                                                         { | 
 |  1079                                                                 lpstrText = &szB
      uff[n + 1]; | 
 |  1080                                                                 break; | 
 |  1081                                                         } | 
 |  1082                                                 } | 
 |  1083                                         } | 
 |  1084                                         bRet = menu.AppendMenu(MF_STRING | (bEna
      bled ? MF_ENABLED : MF_GRAYED), tbb.idCommand, lpstrText); | 
 |  1085                                         ATLASSERT(bRet); | 
 |  1086                                 } | 
 |  1087                         } | 
 |  1088                 } | 
 |  1089  | 
 |  1090                 if(menu.GetMenuItemCount() == 0)   // no hidden buttons after al
      l | 
 |  1091                 { | 
 |  1092                         menu.DestroyMenu(); | 
 |  1093                         ::MessageBeep((UINT)-1); | 
 |  1094                         return false; | 
 |  1095                 } | 
 |  1096  | 
 |  1097                 cmi.hMenu = menu; | 
 |  1098                 return true; | 
 |  1099         } | 
 |  1100  | 
 |  1101         void DisplayChevronMenu(_ChevronMenuInfo& cmi) | 
 |  1102         { | 
 |  1103 #ifndef TPM_VERPOSANIMATION | 
 |  1104                 const UINT TPM_VERPOSANIMATION = 0x1000L;   // Menu animation fl
      ag | 
 |  1105 #endif | 
 |  1106                 // convert chevron rect to screen coordinates | 
 |  1107                 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; | 
 |  1108                 POINT pt = { cmi.lpnm->rc.left, cmi.lpnm->rc.bottom }; | 
 |  1109                 wndFrom.MapWindowPoints(NULL, &pt, 1); | 
 |  1110                 RECT rc = cmi.lpnm->rc; | 
 |  1111                 wndFrom.MapWindowPoints(NULL, &rc); | 
 |  1112                 // set up flags and rect | 
 |  1113                 UINT uMenuFlags = TPM_LEFTBUTTON | TPM_VERTICAL | TPM_LEFTALIGN 
      | TPM_TOPALIGN | (!AtlIsOldWindows() ? TPM_VERPOSANIMATION : 0); | 
 |  1114                 TPMPARAMS TPMParams = { 0 }; | 
 |  1115                 TPMParams.cbSize = sizeof(TPMPARAMS); | 
 |  1116                 TPMParams.rcExclude = rc; | 
 |  1117                 // check if this window has a command bar | 
 |  1118                 HWND hWndCmdBar = (HWND)::SendMessage(m_hWnd, CBRM_GETCMDBAR, 0,
       0L); | 
 |  1119                 if(::IsWindow(hWndCmdBar)) | 
 |  1120                 { | 
 |  1121                         CBRPOPUPMENU CBRPopupMenu = { sizeof(CBRPOPUPMENU), cmi.
      hMenu, uMenuFlags, pt.x, pt.y, &TPMParams }; | 
 |  1122                         ::SendMessage(hWndCmdBar, CBRM_TRACKPOPUPMENU, 0, (LPARA
      M)&CBRPopupMenu); | 
 |  1123                 } | 
 |  1124                 else | 
 |  1125                 { | 
 |  1126                         CMenuHandle menu = cmi.hMenu; | 
 |  1127                         menu.TrackPopupMenuEx(uMenuFlags, pt.x, pt.y, m_hWnd, &T
      PMParams); | 
 |  1128                 } | 
 |  1129         } | 
 |  1130  | 
 |  1131         void CleanupChevronMenu(_ChevronMenuInfo& cmi) | 
 |  1132         { | 
 |  1133                 CMenuHandle menu = cmi.hMenu; | 
 |  1134                 // if menu is from a command bar, detach submenus so they are no
      t destroyed | 
 |  1135                 if(cmi.bCmdBar) | 
 |  1136                 { | 
 |  1137                         for(int i = menu.GetMenuItemCount() - 1; i >=0; i--) | 
 |  1138                                 menu.RemoveMenu(i, MF_BYPOSITION); | 
 |  1139                 } | 
 |  1140                 // destroy menu | 
 |  1141                 menu.DestroyMenu(); | 
 |  1142                 // convert chevron rect to screen coordinates | 
 |  1143                 ATL::CWindow wndFrom = cmi.lpnm->hdr.hwndFrom; | 
 |  1144                 RECT rc = cmi.lpnm->rc; | 
 |  1145                 wndFrom.MapWindowPoints(NULL, &rc); | 
 |  1146                 // eat next message if click is on the same button | 
 |  1147                 MSG msg = { 0 }; | 
 |  1148                 if(::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDOWN, P
      M_NOREMOVE) && ::PtInRect(&rc, msg.pt)) | 
 |  1149                         ::PeekMessage(&msg, m_hWnd, WM_LBUTTONDOWN, WM_LBUTTONDO
      WN, PM_REMOVE); | 
 |  1150         } | 
 |  1151 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1152 }; | 
 |  1153  | 
 |  1154  | 
 |  1155 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CFrameWin
      Traits> | 
 |  1156 class ATL_NO_VTABLE CFrameWindowImpl : public CFrameWindowImplBase< TBase, TWinT
      raits > | 
 |  1157 { | 
 |  1158 public: | 
 |  1159         HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR sz
      WindowName = NULL, | 
 |  1160                         DWORD dwStyle = 0, DWORD dwExStyle = 0, | 
 |  1161                         HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) | 
 |  1162         { | 
 |  1163                 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc)
      ; | 
 |  1164  | 
 |  1165                 dwStyle = T::GetWndStyle(dwStyle); | 
 |  1166                 dwExStyle = T::GetWndExStyle(dwExStyle); | 
 |  1167  | 
 |  1168                 if(rect.m_lpRect == NULL) | 
 |  1169                         rect.m_lpRect = &TBase::rcDefault; | 
 |  1170  | 
 |  1171                 return CFrameWindowImplBase< TBase, TWinTraits >::Create(hWndPar
      ent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam
      ); | 
 |  1172         } | 
 |  1173  | 
 |  1174         HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dw
      Style = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) | 
 |  1175         { | 
 |  1176                 const int cchName = 256; | 
 |  1177                 TCHAR szWindowName[cchName]; | 
 |  1178                 szWindowName[0] = 0; | 
 |  1179 #ifndef _WIN32_WCE | 
 |  1180                 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass
      Info().m_uCommonResourceID, szWindowName, cchName); | 
 |  1181                 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MA
      KEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); | 
 |  1182 #else // CE specific | 
 |  1183                 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass
      Info().m_uCommonResourceID, szWindowName, cchName); | 
 |  1184  | 
 |  1185                 // This always needs to be NULL for Windows CE. | 
 |  1186                 // Frame Window menus have to go onto the CommandBar. | 
 |  1187                 // Use CreateSimpleCECommandBar | 
 |  1188                 HMENU hMenu = NULL; | 
 |  1189 #endif // _WIN32_WCE | 
 |  1190  | 
 |  1191                 T* pT = static_cast<T*>(this); | 
 |  1192                 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, 
      dwExStyle, hMenu, lpCreateParam); | 
 |  1193  | 
 |  1194                 if(hWnd != NULL) | 
 |  1195                         m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI
      nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); | 
 |  1196  | 
 |  1197                 return hWnd; | 
 |  1198         } | 
 |  1199  | 
 |  1200         BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL
      E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) | 
 |  1201         { | 
 |  1202                 if(nResourceID == 0) | 
 |  1203                         nResourceID = T::GetWndClassInfo().m_uCommonResourceID; | 
 |  1204 #ifndef _WIN32_WCE | 
 |  1205                 ATLASSERT(!::IsWindow(m_hWndToolBar)); | 
 |  1206                 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, 
      TRUE, dwStyle, nID); | 
 |  1207                 return (m_hWndToolBar != NULL); | 
 |  1208 #else // CE specific | 
 |  1209                 HWND hWnd= T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResou
      rceID, TRUE, dwStyle, nID); | 
 |  1210                 return (hWnd != NULL); | 
 |  1211 #endif // _WIN32_WCE | 
 |  1212         } | 
 |  1213  | 
 |  1214 #ifdef _WIN32_WCE | 
 |  1215         // CE specific variant that returns the handle of the toolbar | 
 |  1216         HWND CreateSimpleCEToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIM
      PLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) | 
 |  1217         { | 
 |  1218                 if(nResourceID == 0) | 
 |  1219                         nResourceID = T::GetWndClassInfo().m_uCommonResourceID; | 
 |  1220  | 
 |  1221                 return T::CreateSimpleToolBarCtrl(m_hWndCECommandBar, nResourceI
      D, TRUE, dwStyle, nID); | 
 |  1222         } | 
 |  1223 #endif // _WIN32_WCE | 
 |  1224  | 
 |  1225 // message map and handlers | 
 |  1226         typedef CFrameWindowImplBase< TBase, TWinTraits >   _baseClass; | 
 |  1227  | 
 |  1228         BEGIN_MSG_MAP(CFrameWindowImpl) | 
 |  1229                 MESSAGE_HANDLER(WM_SIZE, OnSize) | 
 |  1230 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1231 #if (_WIN32_IE >= 0x0400) | 
 |  1232                 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) | 
 |  1233 #endif // (_WIN32_IE >= 0x0400) | 
 |  1234 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1235                 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) | 
 |  1236 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1237 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1238                 CHAIN_MSG_MAP(_baseClass) | 
 |  1239         END_MSG_MAP() | 
 |  1240  | 
 |  1241         LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bH
      andled) | 
 |  1242         { | 
 |  1243                 if(wParam != SIZE_MINIMIZED) | 
 |  1244                 { | 
 |  1245                         T* pT = static_cast<T*>(this); | 
 |  1246                         pT->UpdateLayout(); | 
 |  1247                 } | 
 |  1248                 bHandled = FALSE; | 
 |  1249                 return 1; | 
 |  1250         } | 
 |  1251  | 
 |  1252 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1253 #if (_WIN32_IE >= 0x0400) | 
 |  1254         LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl
      ed*/) | 
 |  1255         { | 
 |  1256                 T* pT = static_cast<T*>(this); | 
 |  1257                 pT->UpdateLayout(FALSE); | 
 |  1258                 return 0; | 
 |  1259         } | 
 |  1260 #endif // (_WIN32_IE >= 0x0400) | 
 |  1261  | 
 |  1262 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1263         LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) | 
 |  1264         { | 
 |  1265                 T* pT = static_cast<T*>(this); | 
 |  1266                 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; | 
 |  1267                 if(!pT->PrepareChevronMenu(cmi)) | 
 |  1268                 { | 
 |  1269                         bHandled = FALSE; | 
 |  1270                         return 1; | 
 |  1271                 } | 
 |  1272                 // display a popup menu with hidden items | 
 |  1273                 pT->DisplayChevronMenu(cmi); | 
 |  1274                 // cleanup | 
 |  1275                 pT->CleanupChevronMenu(cmi); | 
 |  1276                 return 0; | 
 |  1277         } | 
 |  1278 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  1279 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1280 }; | 
 |  1281  | 
 |  1282  | 
 |  1283 /////////////////////////////////////////////////////////////////////////////// | 
 |  1284 // AtlCreateSimpleToolBar - helper for creating simple toolbars | 
 |  1285  | 
 |  1286 #ifndef _WIN32_WCE | 
 |  1287  | 
 |  1288 inline HWND AtlCreateSimpleToolBar(HWND hWndParent, UINT nResourceID, BOOL bInit
      ialSeparator = FALSE,  | 
 |  1289                 DWORD dwStyle = ATL_SIMPLE_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOO
      LBAR) | 
 |  1290 { | 
 |  1291         return CFrameWindowImplBase<>::CreateSimpleToolBarCtrl(hWndParent, nReso
      urceID, bInitialSeparator, dwStyle, nID); | 
 |  1292 } | 
 |  1293  | 
 |  1294 #endif // !_WIN32_WCE | 
 |  1295  | 
 |  1296  | 
 |  1297 /////////////////////////////////////////////////////////////////////////////// | 
 |  1298 // CMDIWindow | 
 |  1299  | 
 |  1300 #ifndef _WIN32_WCE | 
 |  1301  | 
 |  1302 #ifndef _WTL_MDIWINDOWMENU_TEXT | 
 |  1303 #define _WTL_MDIWINDOWMENU_TEXT _T("&Window") | 
 |  1304 #endif | 
 |  1305  | 
 |  1306 class CMDIWindow : public ATL::CWindow | 
 |  1307 { | 
 |  1308 public: | 
 |  1309 // Data members | 
 |  1310         HWND m_hWndMDIClient; | 
 |  1311         HMENU m_hMenu; | 
 |  1312  | 
 |  1313 // Constructors | 
 |  1314         CMDIWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd), m_hWndMDIClient(NULL)
      , m_hMenu(NULL) | 
 |  1315         { } | 
 |  1316  | 
 |  1317         CMDIWindow& operator =(HWND hWnd) | 
 |  1318         { | 
 |  1319                 m_hWnd = hWnd; | 
 |  1320                 return *this; | 
 |  1321         } | 
 |  1322  | 
 |  1323 // Operations | 
 |  1324         HWND MDIGetActive(BOOL* lpbMaximized = NULL) | 
 |  1325         { | 
 |  1326                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1327                 return (HWND)::SendMessage(m_hWndMDIClient, WM_MDIGETACTIVE, 0, 
      (LPARAM)lpbMaximized); | 
 |  1328         } | 
 |  1329  | 
 |  1330         void MDIActivate(HWND hWndChildToActivate) | 
 |  1331         { | 
 |  1332                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1333                 ATLASSERT(::IsWindow(hWndChildToActivate)); | 
 |  1334                 ::SendMessage(m_hWndMDIClient, WM_MDIACTIVATE, (WPARAM)hWndChild
      ToActivate, 0); | 
 |  1335         } | 
 |  1336  | 
 |  1337         void MDINext(HWND hWndChild, BOOL bPrevious = FALSE) | 
 |  1338         { | 
 |  1339                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1340                 ATLASSERT(hWndChild == NULL || ::IsWindow(hWndChild)); | 
 |  1341                 ::SendMessage(m_hWndMDIClient, WM_MDINEXT, (WPARAM)hWndChild, (L
      PARAM)bPrevious); | 
 |  1342         } | 
 |  1343  | 
 |  1344         void MDIMaximize(HWND hWndChildToMaximize) | 
 |  1345         { | 
 |  1346                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1347                 ATLASSERT(::IsWindow(hWndChildToMaximize)); | 
 |  1348                 ::SendMessage(m_hWndMDIClient, WM_MDIMAXIMIZE, (WPARAM)hWndChild
      ToMaximize, 0); | 
 |  1349         } | 
 |  1350  | 
 |  1351         void MDIRestore(HWND hWndChildToRestore) | 
 |  1352         { | 
 |  1353                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1354                 ATLASSERT(::IsWindow(hWndChildToRestore)); | 
 |  1355                 ::SendMessage(m_hWndMDIClient, WM_MDIRESTORE, (WPARAM)hWndChildT
      oRestore, 0); | 
 |  1356         } | 
 |  1357  | 
 |  1358         void MDIDestroy(HWND hWndChildToDestroy) | 
 |  1359         { | 
 |  1360                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1361                 ATLASSERT(::IsWindow(hWndChildToDestroy)); | 
 |  1362                 ::SendMessage(m_hWndMDIClient, WM_MDIDESTROY, (WPARAM)hWndChildT
      oDestroy, 0); | 
 |  1363         } | 
 |  1364  | 
 |  1365         BOOL MDICascade(UINT uFlags = 0) | 
 |  1366         { | 
 |  1367                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1368                 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDICASCADE, (WPAR
      AM)uFlags, 0); | 
 |  1369         } | 
 |  1370  | 
 |  1371         BOOL MDITile(UINT uFlags = MDITILE_HORIZONTAL) | 
 |  1372         { | 
 |  1373                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1374                 return (BOOL)::SendMessage(m_hWndMDIClient, WM_MDITILE, (WPARAM)
      uFlags, 0); | 
 |  1375         } | 
 |  1376  | 
 |  1377         void MDIIconArrange() | 
 |  1378         { | 
 |  1379                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1380                 ::SendMessage(m_hWndMDIClient, WM_MDIICONARRANGE, 0, 0); | 
 |  1381         } | 
 |  1382  | 
 |  1383         HMENU MDISetMenu(HMENU hMenuFrame, HMENU hMenuWindow) | 
 |  1384         { | 
 |  1385                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1386                 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDISETMENU, (WPA
      RAM)hMenuFrame, (LPARAM)hMenuWindow); | 
 |  1387         } | 
 |  1388  | 
 |  1389         HMENU MDIRefreshMenu() | 
 |  1390         { | 
 |  1391                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1392                 return (HMENU)::SendMessage(m_hWndMDIClient, WM_MDIREFRESHMENU, 
      0, 0); | 
 |  1393         } | 
 |  1394  | 
 |  1395 // Additional operations | 
 |  1396         static HMENU GetStandardWindowMenu(HMENU hMenu) | 
 |  1397         { | 
 |  1398                 int nCount = ::GetMenuItemCount(hMenu); | 
 |  1399                 if(nCount == -1) | 
 |  1400                         return NULL; | 
 |  1401                 int nLen = ::GetMenuString(hMenu, nCount - 2, NULL, 0, MF_BYPOSI
      TION); | 
 |  1402                 if(nLen == 0) | 
 |  1403                         return NULL; | 
 |  1404                 CTempBuffer<TCHAR, _WTL_STACK_ALLOC_THRESHOLD> buff; | 
 |  1405                 LPTSTR lpszText = buff.Allocate(nLen + 1); | 
 |  1406                 if(lpszText == NULL) | 
 |  1407                         return NULL; | 
 |  1408                 if(::GetMenuString(hMenu, nCount - 2, lpszText, nLen + 1, MF_BYP
      OSITION) != nLen) | 
 |  1409                         return NULL; | 
 |  1410                 if(lstrcmp(lpszText, _WTL_MDIWINDOWMENU_TEXT) != 0) | 
 |  1411                         return NULL; | 
 |  1412                 return ::GetSubMenu(hMenu, nCount - 2); | 
 |  1413         } | 
 |  1414  | 
 |  1415         void SetMDIFrameMenu() | 
 |  1416         { | 
 |  1417                 HMENU hWindowMenu = GetStandardWindowMenu(m_hMenu); | 
 |  1418                 MDISetMenu(m_hMenu, hWindowMenu); | 
 |  1419                 MDIRefreshMenu(); | 
 |  1420                 ::DrawMenuBar(GetMDIFrame()); | 
 |  1421         } | 
 |  1422  | 
 |  1423         HWND GetMDIFrame() const | 
 |  1424         { | 
 |  1425                 return ::GetParent(m_hWndMDIClient); | 
 |  1426         } | 
 |  1427 }; | 
 |  1428  | 
 |  1429 #endif // !_WIN32_WCE | 
 |  1430  | 
 |  1431  | 
 |  1432 /////////////////////////////////////////////////////////////////////////////// | 
 |  1433 // CMDIFrameWindowImpl | 
 |  1434  | 
 |  1435 #ifndef _WIN32_WCE | 
 |  1436  | 
 |  1437 // MDI child command chaining macro (only for MDI frame windows) | 
 |  1438 #define CHAIN_MDI_CHILD_COMMANDS() \ | 
 |  1439         if(uMsg == WM_COMMAND) \ | 
 |  1440         { \ | 
 |  1441                 HWND hWndChild = MDIGetActive(); \ | 
 |  1442                 if(hWndChild != NULL) \ | 
 |  1443                         ::SendMessage(hWndChild, uMsg, wParam, lParam); \ | 
 |  1444         } | 
 |  1445  | 
 |  1446 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CFrameWinTr
      aits> | 
 |  1447 class ATL_NO_VTABLE CMDIFrameWindowImpl : public CFrameWindowImplBase<TBase, TWi
      nTraits > | 
 |  1448 { | 
 |  1449 public: | 
 |  1450         HWND Create(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, LPCTSTR sz
      WindowName = NULL, | 
 |  1451                         DWORD dwStyle = 0, DWORD dwExStyle = 0, | 
 |  1452                         HMENU hMenu = NULL, LPVOID lpCreateParam = NULL) | 
 |  1453         { | 
 |  1454                 m_hMenu = hMenu; | 
 |  1455                 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc)
      ; | 
 |  1456  | 
 |  1457                 dwStyle = T::GetWndStyle(dwStyle); | 
 |  1458                 dwExStyle = T::GetWndExStyle(dwExStyle); | 
 |  1459  | 
 |  1460                 if(rect.m_lpRect == NULL) | 
 |  1461                         rect.m_lpRect = &TBase::rcDefault; | 
 |  1462  | 
 |  1463                 return CFrameWindowImplBase<TBase, TWinTraits >::Create(hWndPare
      nt, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, hMenu, atom, lpCreateParam)
      ; | 
 |  1464         } | 
 |  1465  | 
 |  1466         HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dw
      Style = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL) | 
 |  1467         { | 
 |  1468                 const int cchName = 256; | 
 |  1469                 TCHAR szWindowName[cchName]; | 
 |  1470                 szWindowName[0] = 0; | 
 |  1471                 ::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClass
      Info().m_uCommonResourceID, szWindowName, cchName); | 
 |  1472                 HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MA
      KEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); | 
 |  1473  | 
 |  1474                 T* pT = static_cast<T*>(this); | 
 |  1475                 HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, 
      dwExStyle, hMenu, lpCreateParam); | 
 |  1476  | 
 |  1477                 if(hWnd != NULL) | 
 |  1478                         m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI
      nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); | 
 |  1479  | 
 |  1480                 return hWnd; | 
 |  1481         } | 
 |  1482  | 
 |  1483         BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL
      E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) | 
 |  1484         { | 
 |  1485                 ATLASSERT(!::IsWindow(m_hWndToolBar)); | 
 |  1486                 if(nResourceID == 0) | 
 |  1487                         nResourceID = T::GetWndClassInfo().m_uCommonResourceID; | 
 |  1488                 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, 
      TRUE, dwStyle, nID); | 
 |  1489                 return (m_hWndToolBar != NULL); | 
 |  1490         } | 
 |  1491  | 
 |  1492         virtual WNDPROC GetWindowProc() | 
 |  1493         { | 
 |  1494                 return MDIFrameWindowProc; | 
 |  1495         } | 
 |  1496  | 
 |  1497         static LRESULT CALLBACK MDIFrameWindowProc(HWND hWnd, UINT uMsg, WPARAM 
      wParam, LPARAM lParam) | 
 |  1498         { | 
 |  1499                 CMDIFrameWindowImpl< T, TBase, TWinTraits >* pThis = (CMDIFrameW
      indowImpl< T, TBase, TWinTraits >*)hWnd; | 
 |  1500                 // set a ptr to this message and save the old value | 
 |  1501 #if (_ATL_VER >= 0x0700) | 
 |  1502                 ATL::_ATL_MSG msg(pThis->m_hWnd, uMsg, wParam, lParam); | 
 |  1503                 const ATL::_ATL_MSG* pOldMsg = pThis->m_pCurrentMsg; | 
 |  1504 #else // !(_ATL_VER >= 0x0700) | 
 |  1505                 MSG msg = { pThis->m_hWnd, uMsg, wParam, lParam, 0, { 0, 0 } }; | 
 |  1506                 const MSG* pOldMsg = pThis->m_pCurrentMsg; | 
 |  1507 #endif // !(_ATL_VER >= 0x0700) | 
 |  1508                 pThis->m_pCurrentMsg = &msg; | 
 |  1509                 // pass to the message map to process | 
 |  1510                 LRESULT lRes = 0; | 
 |  1511                 BOOL bRet = pThis->ProcessWindowMessage(pThis->m_hWnd, uMsg, wPa
      ram, lParam, lRes, 0); | 
 |  1512                 // restore saved value for the current message | 
 |  1513                 ATLASSERT(pThis->m_pCurrentMsg == &msg); | 
 |  1514                 pThis->m_pCurrentMsg = pOldMsg; | 
 |  1515                 // do the default processing if message was not handled | 
 |  1516                 if(!bRet) | 
 |  1517                 { | 
 |  1518                         if(uMsg != WM_NCDESTROY) | 
 |  1519                                 lRes = pThis->DefWindowProc(uMsg, wParam, lParam
      ); | 
 |  1520                         else | 
 |  1521                         { | 
 |  1522                                 // unsubclass, if needed | 
 |  1523                                 LONG_PTR pfnWndProc = ::GetWindowLongPtr(pThis->
      m_hWnd, GWLP_WNDPROC); | 
 |  1524                                 lRes = pThis->DefWindowProc(uMsg, wParam, lParam
      ); | 
 |  1525                                 if(pThis->m_pfnSuperWindowProc != ::DefWindowPro
      c && ::GetWindowLongPtr(pThis->m_hWnd, GWLP_WNDPROC) == pfnWndProc) | 
 |  1526                                         ::SetWindowLongPtr(pThis->m_hWnd, GWLP_W
      NDPROC, (LONG_PTR)pThis->m_pfnSuperWindowProc); | 
 |  1527 #if (_ATL_VER >= 0x0700) | 
 |  1528                                 // mark window as destryed | 
 |  1529                                 pThis->m_dwState |= WINSTATE_DESTROYED; | 
 |  1530 #else // !(_ATL_VER >= 0x0700) | 
 |  1531                                 // clear out window handle | 
 |  1532                                 HWND hWnd = pThis->m_hWnd; | 
 |  1533                                 pThis->m_hWnd = NULL; | 
 |  1534                                 // clean up after window is destroyed | 
 |  1535                                 pThis->OnFinalMessage(hWnd); | 
 |  1536 #endif // !(_ATL_VER >= 0x0700) | 
 |  1537                         } | 
 |  1538                 } | 
 |  1539 #if (_ATL_VER >= 0x0700) | 
 |  1540                 if(pThis->m_dwState & WINSTATE_DESTROYED && pThis->m_pCurrentMsg
       == NULL) | 
 |  1541                 { | 
 |  1542                         // clear out window handle | 
 |  1543                         HWND hWnd = pThis->m_hWnd; | 
 |  1544                         pThis->m_hWnd = NULL; | 
 |  1545                         pThis->m_dwState &= ~WINSTATE_DESTROYED; | 
 |  1546                         // clean up after window is destroyed | 
 |  1547                         pThis->OnFinalMessage(hWnd); | 
 |  1548                 } | 
 |  1549 #endif // (_ATL_VER >= 0x0700) | 
 |  1550                 return lRes; | 
 |  1551         } | 
 |  1552  | 
 |  1553         // Overriden to call DefWindowProc which uses DefFrameProc | 
 |  1554         LRESULT DefWindowProc() | 
 |  1555         { | 
 |  1556                 const MSG* pMsg = m_pCurrentMsg; | 
 |  1557                 LRESULT lRes = 0; | 
 |  1558                 if (pMsg != NULL) | 
 |  1559                         lRes = DefWindowProc(pMsg->message, pMsg->wParam, pMsg->
      lParam); | 
 |  1560                 return lRes; | 
 |  1561         } | 
 |  1562  | 
 |  1563         LRESULT DefWindowProc(UINT uMsg, WPARAM wParam, LPARAM lParam) | 
 |  1564         { | 
 |  1565                 return ::DefFrameProc(m_hWnd, m_hWndMDIClient, uMsg, wParam, lPa
      ram); | 
 |  1566         } | 
 |  1567  | 
 |  1568         BOOL PreTranslateMessage(MSG* pMsg) | 
 |  1569         { | 
 |  1570                 if(CFrameWindowImplBase<TBase, TWinTraits>::PreTranslateMessage(
      pMsg)) | 
 |  1571                         return TRUE; | 
 |  1572                 return ::TranslateMDISysAccel(m_hWndMDIClient, pMsg); | 
 |  1573         } | 
 |  1574  | 
 |  1575         HWND CreateMDIClient(HMENU hWindowMenu = NULL, UINT nID = ATL_IDW_CLIENT
      , UINT nFirstChildID = ATL_IDM_FIRST_MDICHILD) | 
 |  1576         { | 
 |  1577                 DWORD dwStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN | WS_CLI
      PSIBLINGS | MDIS_ALLCHILDSTYLES; | 
 |  1578                 DWORD dwExStyle = WS_EX_CLIENTEDGE; | 
 |  1579  | 
 |  1580                 CLIENTCREATESTRUCT ccs = { 0 }; | 
 |  1581                 ccs.hWindowMenu = hWindowMenu; | 
 |  1582                 ccs.idFirstChild = nFirstChildID; | 
 |  1583  | 
 |  1584                 if((GetStyle() & (WS_HSCROLL | WS_VSCROLL)) != 0) | 
 |  1585                 { | 
 |  1586                         // parent MDI frame's scroll styles move to the MDICLIEN
      T | 
 |  1587                         dwStyle |= (GetStyle() & (WS_HSCROLL | WS_VSCROLL)); | 
 |  1588  | 
 |  1589                         // fast way to turn off the scrollbar bits (without a re
      size) | 
 |  1590                         ModifyStyle(WS_HSCROLL | WS_VSCROLL, 0, SWP_NOREDRAW | S
      WP_FRAMECHANGED); | 
 |  1591                 } | 
 |  1592  | 
 |  1593                 // Create MDICLIENT window | 
 |  1594                 m_hWndClient = ::CreateWindowEx(dwExStyle, _T("MDIClient"), NULL
      , | 
 |  1595                         dwStyle, 0, 0, 1, 1, m_hWnd, (HMENU)LongToHandle(nID), | 
 |  1596                         ModuleHelper::GetModuleInstance(), (LPVOID)&ccs); | 
 |  1597                 if (m_hWndClient == NULL) | 
 |  1598                 { | 
 |  1599                         ATLTRACE2(atlTraceUI, 0, _T("MDI Frame failed to create 
      MDICLIENT.\n")); | 
 |  1600                         return NULL; | 
 |  1601                 } | 
 |  1602  | 
 |  1603                 // Move it to the top of z-order | 
 |  1604                 ::BringWindowToTop(m_hWndClient); | 
 |  1605  | 
 |  1606                 // set as MDI client window | 
 |  1607                 m_hWndMDIClient = m_hWndClient; | 
 |  1608  | 
 |  1609                 // update to proper size | 
 |  1610                 T* pT = static_cast<T*>(this); | 
 |  1611                 pT->UpdateLayout(); | 
 |  1612  | 
 |  1613                 return m_hWndClient; | 
 |  1614         } | 
 |  1615  | 
 |  1616         typedef CFrameWindowImplBase<TBase, TWinTraits >   _baseClass; | 
 |  1617  | 
 |  1618         BEGIN_MSG_MAP(CMDIFrameWindowImpl) | 
 |  1619                 MESSAGE_HANDLER(WM_SIZE, OnSize) | 
 |  1620                 MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus) | 
 |  1621                 MESSAGE_HANDLER(WM_MDISETMENU, OnMDISetMenu) | 
 |  1622 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1623 #if (_WIN32_IE >= 0x0400) | 
 |  1624                 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) | 
 |  1625 #endif // (_WIN32_IE >= 0x0400) | 
 |  1626 #if (_WIN32_IE >= 0x0500) | 
 |  1627                 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) | 
 |  1628 #endif // (_WIN32_IE >= 0x0500) | 
 |  1629 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1630                 CHAIN_MSG_MAP(_baseClass) | 
 |  1631         END_MSG_MAP() | 
 |  1632  | 
 |  1633         LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*
      bHandled*/) | 
 |  1634         { | 
 |  1635                 if(wParam != SIZE_MINIMIZED) | 
 |  1636                 { | 
 |  1637                         T* pT = static_cast<T*>(this); | 
 |  1638                         pT->UpdateLayout(); | 
 |  1639                 } | 
 |  1640                 // message must be handled, otherwise DefFrameProc would resize 
      the client again | 
 |  1641                 return 0; | 
 |  1642         } | 
 |  1643  | 
 |  1644         LRESULT OnSetFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHan
      dled*/) | 
 |  1645         { | 
 |  1646                 // don't allow CFrameWindowImplBase to handle this one | 
 |  1647                 return DefWindowProc(uMsg, wParam, lParam); | 
 |  1648         } | 
 |  1649  | 
 |  1650         LRESULT OnMDISetMenu(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
      , BOOL& /*bHandled*/) | 
 |  1651         { | 
 |  1652                 SetMDIFrameMenu(); | 
 |  1653                 return 0; | 
 |  1654         } | 
 |  1655  | 
 |  1656 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1657 #if (_WIN32_IE >= 0x0400) | 
 |  1658         LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl
      ed*/) | 
 |  1659         { | 
 |  1660                 T* pT = static_cast<T*>(this); | 
 |  1661                 pT->UpdateLayout(FALSE); | 
 |  1662                 return 0; | 
 |  1663         } | 
 |  1664 #endif // (_WIN32_IE >= 0x0400) | 
 |  1665  | 
 |  1666 #if (_WIN32_IE >= 0x0500) | 
 |  1667         LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) | 
 |  1668         { | 
 |  1669                 T* pT = static_cast<T*>(this); | 
 |  1670                 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; | 
 |  1671                 if(!pT->PrepareChevronMenu(cmi)) | 
 |  1672                 { | 
 |  1673                         bHandled = FALSE; | 
 |  1674                         return 1; | 
 |  1675                 } | 
 |  1676                 // display a popup menu with hidden items | 
 |  1677                 pT->DisplayChevronMenu(cmi); | 
 |  1678                 // cleanup | 
 |  1679                 pT->CleanupChevronMenu(cmi); | 
 |  1680                 return 0; | 
 |  1681         } | 
 |  1682 #endif // (_WIN32_IE >= 0x0500) | 
 |  1683 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1684 }; | 
 |  1685  | 
 |  1686 #endif // !_WIN32_WCE | 
 |  1687  | 
 |  1688  | 
 |  1689 /////////////////////////////////////////////////////////////////////////////// | 
 |  1690 // CMDIChildWindowImpl | 
 |  1691  | 
 |  1692 #ifndef _WIN32_WCE | 
 |  1693  | 
 |  1694 template <class T, class TBase = CMDIWindow, class TWinTraits = ATL::CMDIChildWi
      nTraits> | 
 |  1695 class ATL_NO_VTABLE CMDIChildWindowImpl : public CFrameWindowImplBase<TBase, TWi
      nTraits > | 
 |  1696 { | 
 |  1697 public: | 
 |  1698         HWND Create(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR szWindowN
      ame = NULL, | 
 |  1699                         DWORD dwStyle = 0, DWORD dwExStyle = 0, | 
 |  1700                         UINT nMenuID = 0, LPVOID lpCreateParam = NULL) | 
 |  1701         { | 
 |  1702                 ATOM atom = T::GetWndClassInfo().Register(&m_pfnSuperWindowProc)
      ; | 
 |  1703  | 
 |  1704                 if(nMenuID != 0) | 
 |  1705                         m_hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance()
      , MAKEINTRESOURCE(nMenuID)); | 
 |  1706  | 
 |  1707                 dwStyle = T::GetWndStyle(dwStyle); | 
 |  1708                 dwExStyle = T::GetWndExStyle(dwExStyle); | 
 |  1709  | 
 |  1710                 dwExStyle |= WS_EX_MDICHILD;   // force this one | 
 |  1711                 m_pfnSuperWindowProc = ::DefMDIChildProc; | 
 |  1712                 m_hWndMDIClient = hWndParent; | 
 |  1713                 ATLASSERT(::IsWindow(m_hWndMDIClient)); | 
 |  1714  | 
 |  1715                 if(rect.m_lpRect == NULL) | 
 |  1716                         rect.m_lpRect = &TBase::rcDefault; | 
 |  1717  | 
 |  1718                 // If the currently active MDI child is maximized, we want to cr
      eate this one maximized too | 
 |  1719                 ATL::CWindow wndParent = hWndParent; | 
 |  1720                 BOOL bMaximized = FALSE; | 
 |  1721                 wndParent.SendMessage(WM_MDIGETACTIVE, 0, (LPARAM)&bMaximized); | 
 |  1722                 if(bMaximized) | 
 |  1723                         wndParent.SetRedraw(FALSE); | 
 |  1724  | 
 |  1725                 HWND hWnd = CFrameWindowImplBase<TBase, TWinTraits >::Create(hWn
      dParent, rect.m_lpRect, szWindowName, dwStyle, dwExStyle, (UINT)0U, atom, lpCrea
      teParam); | 
 |  1726  | 
 |  1727                 if(bMaximized) | 
 |  1728                 { | 
 |  1729                         // Maximize and redraw everything | 
 |  1730                         if(hWnd != NULL) | 
 |  1731                                 MDIMaximize(hWnd); | 
 |  1732                         wndParent.SetRedraw(TRUE); | 
 |  1733                         wndParent.RedrawWindow(NULL, NULL, RDW_INVALIDATE | RDW_
      ALLCHILDREN); | 
 |  1734                         ::SetFocus(GetMDIFrame());   // focus will be set back t
      o this window | 
 |  1735                 } | 
 |  1736                 else if(hWnd != NULL && ::IsWindowVisible(m_hWnd) && !::IsChild(
      hWnd, ::GetFocus())) | 
 |  1737                 { | 
 |  1738                         ::SetFocus(hWnd); | 
 |  1739                 } | 
 |  1740  | 
 |  1741                 return hWnd; | 
 |  1742         } | 
 |  1743  | 
 |  1744         HWND CreateEx(HWND hWndParent, ATL::_U_RECT rect = NULL, LPCTSTR lpcstrW
      indowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam =
       NULL) | 
 |  1745         { | 
 |  1746                 const int cchName = 256; | 
 |  1747                 TCHAR szWindowName[cchName]; | 
 |  1748                 szWindowName[0] = 0; | 
 |  1749                 if(lpcstrWindowName == NULL) | 
 |  1750                 { | 
 |  1751                         ::LoadString(ModuleHelper::GetResourceInstance(), T::Get
      WndClassInfo().m_uCommonResourceID, szWindowName, cchName); | 
 |  1752                         lpcstrWindowName = szWindowName; | 
 |  1753                 } | 
 |  1754  | 
 |  1755                 T* pT = static_cast<T*>(this); | 
 |  1756                 HWND hWnd = pT->Create(hWndParent, rect, lpcstrWindowName, dwSty
      le, dwExStyle, T::GetWndClassInfo().m_uCommonResourceID, lpCreateParam); | 
 |  1757  | 
 |  1758                 if(hWnd != NULL) | 
 |  1759                         m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceI
      nstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID)); | 
 |  1760  | 
 |  1761                 return hWnd; | 
 |  1762         } | 
 |  1763  | 
 |  1764         BOOL CreateSimpleToolBar(UINT nResourceID = 0, DWORD dwStyle = ATL_SIMPL
      E_TOOLBAR_STYLE, UINT nID = ATL_IDW_TOOLBAR) | 
 |  1765         { | 
 |  1766                 ATLASSERT(!::IsWindow(m_hWndToolBar)); | 
 |  1767                 if(nResourceID == 0) | 
 |  1768                         nResourceID = T::GetWndClassInfo().m_uCommonResourceID; | 
 |  1769                 m_hWndToolBar = T::CreateSimpleToolBarCtrl(m_hWnd, nResourceID, 
      TRUE, dwStyle, nID); | 
 |  1770                 return (m_hWndToolBar != NULL); | 
 |  1771         } | 
 |  1772  | 
 |  1773         BOOL UpdateClientEdge(LPRECT lpRect = NULL) | 
 |  1774         { | 
 |  1775                 // only adjust for active MDI child window | 
 |  1776                 HWND hWndChild = MDIGetActive(); | 
 |  1777                 if(hWndChild != NULL && hWndChild != m_hWnd) | 
 |  1778                         return FALSE; | 
 |  1779  | 
 |  1780                 // need to adjust the client edge style as max/restore happens | 
 |  1781                 DWORD dwStyle = ::GetWindowLong(m_hWndMDIClient, GWL_EXSTYLE); | 
 |  1782                 DWORD dwNewStyle = dwStyle; | 
 |  1783                 if(hWndChild != NULL && ((GetExStyle() & WS_EX_CLIENTEDGE) == 0)
       && ((GetStyle() & WS_MAXIMIZE) != 0)) | 
 |  1784                         dwNewStyle &= ~(WS_EX_CLIENTEDGE); | 
 |  1785                 else | 
 |  1786                         dwNewStyle |= WS_EX_CLIENTEDGE; | 
 |  1787  | 
 |  1788                 if(dwStyle != dwNewStyle) | 
 |  1789                 { | 
 |  1790                         // SetWindowPos will not move invalid bits | 
 |  1791                         ::RedrawWindow(m_hWndMDIClient, NULL, NULL, | 
 |  1792                                 RDW_INVALIDATE | RDW_ALLCHILDREN); | 
 |  1793                         // remove/add WS_EX_CLIENTEDGE to MDI client area | 
 |  1794                         ::SetWindowLong(m_hWndMDIClient, GWL_EXSTYLE, dwNewStyle
      ); | 
 |  1795                         ::SetWindowPos(m_hWndMDIClient, NULL, 0, 0, 0, 0, | 
 |  1796                                 SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE |
       SWP_NOSIZE | | 
 |  1797                                 SWP_NOZORDER | SWP_NOCOPYBITS); | 
 |  1798  | 
 |  1799                         // return new client area | 
 |  1800                         if (lpRect != NULL) | 
 |  1801                                 ::GetClientRect(m_hWndMDIClient, lpRect); | 
 |  1802  | 
 |  1803                         return TRUE; | 
 |  1804                 } | 
 |  1805  | 
 |  1806                 return FALSE; | 
 |  1807         } | 
 |  1808  | 
 |  1809         typedef CFrameWindowImplBase<TBase, TWinTraits >   _baseClass; | 
 |  1810         BEGIN_MSG_MAP(CMDIChildWindowImpl) | 
 |  1811                 MESSAGE_HANDLER(WM_SIZE, OnSize) | 
 |  1812                 MESSAGE_HANDLER(WM_WINDOWPOSCHANGED, OnWindowPosChanged) | 
 |  1813                 MESSAGE_HANDLER(WM_MOUSEACTIVATE, OnMouseActivate) | 
 |  1814                 MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect) | 
 |  1815                 MESSAGE_HANDLER(WM_MDIACTIVATE, OnMDIActivate) | 
 |  1816                 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) | 
 |  1817 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1818 #if (_WIN32_IE >= 0x0400) | 
 |  1819                 NOTIFY_CODE_HANDLER(RBN_AUTOSIZE, OnReBarAutoSize) | 
 |  1820 #endif // (_WIN32_IE >= 0x0400) | 
 |  1821 #if (_WIN32_IE >= 0x0500) | 
 |  1822                 NOTIFY_CODE_HANDLER(RBN_CHEVRONPUSHED, OnChevronPushed) | 
 |  1823 #endif // (_WIN32_IE >= 0x0500) | 
 |  1824 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1825                 CHAIN_MSG_MAP(_baseClass) | 
 |  1826         END_MSG_MAP() | 
 |  1827  | 
 |  1828         LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled
      */) | 
 |  1829         { | 
 |  1830                 DefWindowProc(uMsg, wParam, lParam);   // needed for MDI childre
      n | 
 |  1831                 if(wParam != SIZE_MINIMIZED) | 
 |  1832                 { | 
 |  1833                         T* pT = static_cast<T*>(this); | 
 |  1834                         pT->UpdateLayout(); | 
 |  1835                 } | 
 |  1836                 return 0; | 
 |  1837         } | 
 |  1838  | 
 |  1839         LRESULT OnWindowPosChanged(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lPar
      am, BOOL& bHandled) | 
 |  1840         { | 
 |  1841                 // update MDI client edge and adjust MDI child rect | 
 |  1842                 LPWINDOWPOS lpWndPos = (LPWINDOWPOS)lParam; | 
 |  1843  | 
 |  1844                 if(!(lpWndPos->flags & SWP_NOSIZE)) | 
 |  1845                 { | 
 |  1846                         RECT rectClient; | 
 |  1847                         if(UpdateClientEdge(&rectClient) && ((GetStyle() & WS_MA
      XIMIZE) != 0)) | 
 |  1848                         { | 
 |  1849                                 ::AdjustWindowRectEx(&rectClient, GetStyle(), FA
      LSE, GetExStyle()); | 
 |  1850                                 lpWndPos->x = rectClient.left; | 
 |  1851                                 lpWndPos->y = rectClient.top; | 
 |  1852                                 lpWndPos->cx = rectClient.right - rectClient.lef
      t; | 
 |  1853                                 lpWndPos->cy = rectClient.bottom - rectClient.to
      p; | 
 |  1854                         } | 
 |  1855                 } | 
 |  1856  | 
 |  1857                 bHandled = FALSE; | 
 |  1858                 return 1; | 
 |  1859         } | 
 |  1860  | 
 |  1861         LRESULT OnMouseActivate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /
      *bHandled*/) | 
 |  1862         { | 
 |  1863                 LRESULT lRes = DefWindowProc(uMsg, wParam, lParam); | 
 |  1864  | 
 |  1865                 // Activate this MDI window if needed | 
 |  1866                 if(lRes == MA_ACTIVATE || lRes == MA_ACTIVATEANDEAT) | 
 |  1867                 { | 
 |  1868                         if(MDIGetActive() != m_hWnd) | 
 |  1869                                 MDIActivate(m_hWnd); | 
 |  1870                 } | 
 |  1871  | 
 |  1872                 return lRes; | 
 |  1873         } | 
 |  1874  | 
 |  1875         LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bH
      andled*/) | 
 |  1876         { | 
 |  1877                 return ::SendMessage(GetMDIFrame(), uMsg, wParam, lParam); | 
 |  1878         } | 
 |  1879  | 
 |  1880         LRESULT OnMDIActivate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B
      OOL& bHandled) | 
 |  1881         { | 
 |  1882                 if((HWND)lParam == m_hWnd && m_hMenu != NULL) | 
 |  1883                         SetMDIFrameMenu(); | 
 |  1884                 else if((HWND)lParam == NULL) | 
 |  1885                         ::SendMessage(GetMDIFrame(), WM_MDISETMENU, 0, 0); | 
 |  1886  | 
 |  1887                 bHandled = FALSE; | 
 |  1888                 return 1; | 
 |  1889         } | 
 |  1890  | 
 |  1891         LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, B
      OOL& bHandled) | 
 |  1892         { | 
 |  1893                 if(m_hMenu != NULL) | 
 |  1894                 { | 
 |  1895                         ::DestroyMenu(m_hMenu); | 
 |  1896                         m_hMenu = NULL; | 
 |  1897                 } | 
 |  1898                 UpdateClientEdge(); | 
 |  1899                 bHandled = FALSE; | 
 |  1900                 return 1; | 
 |  1901         } | 
 |  1902  | 
 |  1903 #ifndef _ATL_NO_REBAR_SUPPORT | 
 |  1904 #if (_WIN32_IE >= 0x0400) | 
 |  1905         LRESULT OnReBarAutoSize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandl
      ed*/) | 
 |  1906         { | 
 |  1907                 T* pT = static_cast<T*>(this); | 
 |  1908                 pT->UpdateLayout(FALSE); | 
 |  1909                 return 0; | 
 |  1910         } | 
 |  1911 #endif // (_WIN32_IE >= 0x0400) | 
 |  1912  | 
 |  1913 #if (_WIN32_IE >= 0x0500) | 
 |  1914         LRESULT OnChevronPushed(int /*idCtrl*/, LPNMHDR pnmh, BOOL& bHandled) | 
 |  1915         { | 
 |  1916                 T* pT = static_cast<T*>(this); | 
 |  1917                 _ChevronMenuInfo cmi = { NULL, (LPNMREBARCHEVRON)pnmh, false }; | 
 |  1918                 if(!pT->PrepareChevronMenu(cmi)) | 
 |  1919                 { | 
 |  1920                         bHandled = FALSE; | 
 |  1921                         return 1; | 
 |  1922                 } | 
 |  1923                 // display a popup menu with hidden items | 
 |  1924                 pT->DisplayChevronMenu(cmi); | 
 |  1925                 // cleanup | 
 |  1926                 pT->CleanupChevronMenu(cmi); | 
 |  1927                 return 0; | 
 |  1928         } | 
 |  1929 #endif // (_WIN32_IE >= 0x0500) | 
 |  1930 #endif // !_ATL_NO_REBAR_SUPPORT | 
 |  1931 }; | 
 |  1932  | 
 |  1933 #endif // !_WIN32_WCE | 
 |  1934  | 
 |  1935  | 
 |  1936 /////////////////////////////////////////////////////////////////////////////// | 
 |  1937 // COwnerDraw - MI class for owner-draw support | 
 |  1938  | 
 |  1939 template <class T> | 
 |  1940 class COwnerDraw | 
 |  1941 { | 
 |  1942 public: | 
 |  1943 #if (_ATL_VER < 0x0700) | 
 |  1944         BOOL m_bHandledOD; | 
 |  1945  | 
 |  1946         BOOL IsMsgHandled() const | 
 |  1947         { | 
 |  1948                 return m_bHandledOD; | 
 |  1949         } | 
 |  1950         void SetMsgHandled(BOOL bHandled) | 
 |  1951         { | 
 |  1952                 m_bHandledOD = bHandled; | 
 |  1953         } | 
 |  1954 #endif // (_ATL_VER < 0x0700) | 
 |  1955  | 
 |  1956 // Message map and handlers | 
 |  1957         BEGIN_MSG_MAP(COwnerDraw< T >) | 
 |  1958                 MESSAGE_HANDLER(WM_DRAWITEM, OnDrawItem) | 
 |  1959                 MESSAGE_HANDLER(WM_MEASUREITEM, OnMeasureItem) | 
 |  1960                 MESSAGE_HANDLER(WM_COMPAREITEM, OnCompareItem) | 
 |  1961                 MESSAGE_HANDLER(WM_DELETEITEM, OnDeleteItem) | 
 |  1962         ALT_MSG_MAP(1) | 
 |  1963                 MESSAGE_HANDLER(OCM_DRAWITEM, OnDrawItem) | 
 |  1964                 MESSAGE_HANDLER(OCM_MEASUREITEM, OnMeasureItem) | 
 |  1965                 MESSAGE_HANDLER(OCM_COMPAREITEM, OnCompareItem) | 
 |  1966                 MESSAGE_HANDLER(OCM_DELETEITEM, OnDeleteItem) | 
 |  1967         END_MSG_MAP() | 
 |  1968  | 
 |  1969         LRESULT OnDrawItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL
      & bHandled) | 
 |  1970         { | 
 |  1971                 T* pT = static_cast<T*>(this); | 
 |  1972                 pT->SetMsgHandled(TRUE); | 
 |  1973                 pT->DrawItem((LPDRAWITEMSTRUCT)lParam); | 
 |  1974                 bHandled = pT->IsMsgHandled(); | 
 |  1975                 return (LRESULT)TRUE; | 
 |  1976         } | 
 |  1977  | 
 |  1978         LRESULT OnMeasureItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B
      OOL& bHandled) | 
 |  1979         { | 
 |  1980                 T* pT = static_cast<T*>(this); | 
 |  1981                 pT->SetMsgHandled(TRUE); | 
 |  1982                 pT->MeasureItem((LPMEASUREITEMSTRUCT)lParam); | 
 |  1983                 bHandled = pT->IsMsgHandled(); | 
 |  1984                 return (LRESULT)TRUE; | 
 |  1985         } | 
 |  1986  | 
 |  1987         LRESULT OnCompareItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, B
      OOL& bHandled) | 
 |  1988         { | 
 |  1989                 T* pT = static_cast<T*>(this); | 
 |  1990                 pT->SetMsgHandled(TRUE); | 
 |  1991                 bHandled = pT->IsMsgHandled(); | 
 |  1992                 return (LRESULT)pT->CompareItem((LPCOMPAREITEMSTRUCT)lParam); | 
 |  1993         } | 
 |  1994  | 
 |  1995         LRESULT OnDeleteItem(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BO
      OL& bHandled) | 
 |  1996         { | 
 |  1997                 T* pT = static_cast<T*>(this); | 
 |  1998                 pT->SetMsgHandled(TRUE); | 
 |  1999                 pT->DeleteItem((LPDELETEITEMSTRUCT)lParam); | 
 |  2000                 bHandled = pT->IsMsgHandled(); | 
 |  2001                 return (LRESULT)TRUE; | 
 |  2002         } | 
 |  2003  | 
 |  2004 // Overrideables | 
 |  2005         void DrawItem(LPDRAWITEMSTRUCT /*lpDrawItemStruct*/) | 
 |  2006         { | 
 |  2007                 // must be implemented | 
 |  2008                 ATLASSERT(FALSE); | 
 |  2009         } | 
 |  2010  | 
 |  2011         void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) | 
 |  2012         { | 
 |  2013                 if(lpMeasureItemStruct->CtlType != ODT_MENU) | 
 |  2014                 { | 
 |  2015                         // return default height for a system font | 
 |  2016                         T* pT = static_cast<T*>(this); | 
 |  2017                         HWND hWnd = pT->GetDlgItem(lpMeasureItemStruct->CtlID); | 
 |  2018                         CClientDC dc(hWnd); | 
 |  2019                         TEXTMETRIC tm = { 0 }; | 
 |  2020                         dc.GetTextMetrics(&tm); | 
 |  2021  | 
 |  2022                         lpMeasureItemStruct->itemHeight = tm.tmHeight; | 
 |  2023                 } | 
 |  2024                 else | 
 |  2025                         lpMeasureItemStruct->itemHeight = ::GetSystemMetrics(SM_
      CYMENU); | 
 |  2026         } | 
 |  2027  | 
 |  2028         int CompareItem(LPCOMPAREITEMSTRUCT /*lpCompareItemStruct*/) | 
 |  2029         { | 
 |  2030                 // all items are equal | 
 |  2031                 return 0; | 
 |  2032         } | 
 |  2033  | 
 |  2034         void DeleteItem(LPDELETEITEMSTRUCT /*lpDeleteItemStruct*/) | 
 |  2035         { | 
 |  2036                 // default - nothing | 
 |  2037         } | 
 |  2038 }; | 
 |  2039  | 
 |  2040  | 
 |  2041 /////////////////////////////////////////////////////////////////////////////// | 
 |  2042 // Update UI macros | 
 |  2043  | 
 |  2044 // these build the Update UI map inside a class definition | 
 |  2045 #define BEGIN_UPDATE_UI_MAP(thisClass) \ | 
 |  2046         static const CUpdateUIBase::_AtlUpdateUIMap* GetUpdateUIMap() \ | 
 |  2047         { \ | 
 |  2048                 static const _AtlUpdateUIMap theMap[] = \ | 
 |  2049                 { | 
 |  2050  | 
 |  2051 #define UPDATE_ELEMENT(nID, wType) \ | 
 |  2052                         { nID,  wType }, | 
 |  2053  | 
 |  2054 #define END_UPDATE_UI_MAP() \ | 
 |  2055                         { (WORD)-1, 0 } \ | 
 |  2056                 }; \ | 
 |  2057                 return theMap; \ | 
 |  2058         } | 
 |  2059  | 
 |  2060 /////////////////////////////////////////////////////////////////////////////// | 
 |  2061 // CUpdateUI - manages UI elements updating | 
 |  2062  | 
 |  2063 class CUpdateUIBase | 
 |  2064 { | 
 |  2065 public: | 
 |  2066         // constants | 
 |  2067         enum | 
 |  2068         { | 
 |  2069                 // UI element type | 
 |  2070                 UPDUI_MENUPOPUP         = 0x0001, | 
 |  2071                 UPDUI_MENUBAR           = 0x0002, | 
 |  2072                 UPDUI_CHILDWINDOW       = 0x0004, | 
 |  2073                 UPDUI_TOOLBAR           = 0x0008, | 
 |  2074                 UPDUI_STATUSBAR         = 0x0010, | 
 |  2075                 // state | 
 |  2076                 UPDUI_ENABLED           = 0x0000, | 
 |  2077                 UPDUI_DISABLED          = 0x0100, | 
 |  2078                 UPDUI_CHECKED           = 0x0200, | 
 |  2079                 UPDUI_CHECKED2          = 0x0400, | 
 |  2080                 UPDUI_RADIO             = 0x0800, | 
 |  2081                 UPDUI_DEFAULT           = 0x1000, | 
 |  2082                 UPDUI_TEXT              = 0x2000, | 
 |  2083                 // internal state | 
 |  2084                 UPDUI_CLEARDEFAULT      = 0x4000, | 
 |  2085         }; | 
 |  2086  | 
 |  2087         // element data | 
 |  2088         struct _AtlUpdateUIElement | 
 |  2089         { | 
 |  2090                 HWND m_hWnd; | 
 |  2091                 WORD m_wType; | 
 |  2092  | 
 |  2093                 bool operator ==(const _AtlUpdateUIElement& e) const | 
 |  2094                 { return (m_hWnd == e.m_hWnd && m_wType == e.m_wType); } | 
 |  2095         }; | 
 |  2096  | 
 |  2097         // map data | 
 |  2098         struct _AtlUpdateUIMap | 
 |  2099         { | 
 |  2100                 WORD m_nID; | 
 |  2101                 WORD m_wType; | 
 |  2102  | 
 |  2103                 bool operator ==(const _AtlUpdateUIMap& e) const | 
 |  2104                 { return (m_nID == e.m_nID && m_wType == e.m_wType); } | 
 |  2105         }; | 
 |  2106  | 
 |  2107         // instance data | 
 |  2108         struct _AtlUpdateUIData | 
 |  2109         { | 
 |  2110                 WORD m_wState; | 
 |  2111                 union | 
 |  2112                 { | 
 |  2113                         void* m_lpData; | 
 |  2114                         LPTSTR m_lpstrText; | 
 |  2115                 }; | 
 |  2116  | 
 |  2117                 bool operator ==(const _AtlUpdateUIData& e) const | 
 |  2118                 { return (m_wState == e.m_wState && m_lpData == e.m_lpData); } | 
 |  2119         }; | 
 |  2120  | 
 |  2121         ATL::CSimpleArray<_AtlUpdateUIElement> m_UIElements;   // elements data | 
 |  2122         const _AtlUpdateUIMap* m_pUIMap;                       // static UI data | 
 |  2123         _AtlUpdateUIData* m_pUIData;                           // instance UI da
      ta | 
 |  2124         WORD m_wDirtyType;                                     // global dirty f
      lag | 
 |  2125  | 
 |  2126         bool m_bBlockAccelerators; | 
 |  2127  | 
 |  2128  | 
 |  2129 // Constructor, destructor | 
 |  2130         CUpdateUIBase() : m_pUIMap(NULL), m_pUIData(NULL), m_wDirtyType(0), m_bB
      lockAccelerators(false) | 
 |  2131         { } | 
 |  2132  | 
 |  2133         ~CUpdateUIBase() | 
 |  2134         { | 
 |  2135                 if(m_pUIMap != NULL && m_pUIData != NULL) | 
 |  2136                 { | 
 |  2137                         const _AtlUpdateUIMap* pUIMap = m_pUIMap; | 
 |  2138                         _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2139                         while(pUIMap->m_nID != (WORD)-1) | 
 |  2140                         { | 
 |  2141                                 if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2142                                         delete [] pUIData->m_lpstrText; | 
 |  2143                                 pUIMap++; | 
 |  2144                                 pUIData++; | 
 |  2145                         } | 
 |  2146                         delete [] m_pUIData; | 
 |  2147                 } | 
 |  2148         } | 
 |  2149  | 
 |  2150 // Check for disabled commands | 
 |  2151         bool UIGetBlockAccelerators() const | 
 |  2152         { | 
 |  2153                 return m_bBlockAccelerators; | 
 |  2154         } | 
 |  2155  | 
 |  2156         bool UISetBlockAccelerators(bool bBlock) | 
 |  2157         { | 
 |  2158                 bool bOld = m_bBlockAccelerators; | 
 |  2159                 m_bBlockAccelerators = bBlock; | 
 |  2160                 return bOld; | 
 |  2161         } | 
 |  2162  | 
 |  2163 // Add elements | 
 |  2164         BOOL UIAddMenuBar(HWND hWnd)                // menu bar (main menu) | 
 |  2165         { | 
 |  2166                 if(hWnd == NULL) | 
 |  2167                         return FALSE; | 
 |  2168                 _AtlUpdateUIElement e; | 
 |  2169                 e.m_hWnd = hWnd; | 
 |  2170                 e.m_wType = UPDUI_MENUBAR; | 
 |  2171                 return m_UIElements.Add(e); | 
 |  2172         } | 
 |  2173  | 
 |  2174         BOOL UIAddToolBar(HWND hWnd)                // toolbar | 
 |  2175         { | 
 |  2176                 if(hWnd == NULL) | 
 |  2177                         return FALSE; | 
 |  2178                 _AtlUpdateUIElement e; | 
 |  2179                 e.m_hWnd = hWnd; | 
 |  2180                 e.m_wType = UPDUI_TOOLBAR; | 
 |  2181                 return m_UIElements.Add(e); | 
 |  2182         } | 
 |  2183  | 
 |  2184         BOOL UIAddStatusBar(HWND hWnd)              // status bar | 
 |  2185         { | 
 |  2186                 if(hWnd == NULL) | 
 |  2187                         return FALSE; | 
 |  2188                 _AtlUpdateUIElement e; | 
 |  2189                 e.m_hWnd = hWnd; | 
 |  2190                 e.m_wType = UPDUI_STATUSBAR; | 
 |  2191                 return m_UIElements.Add(e); | 
 |  2192         } | 
 |  2193  | 
 |  2194         BOOL UIAddChildWindowContainer(HWND hWnd)   // child window | 
 |  2195         { | 
 |  2196                 if(hWnd == NULL) | 
 |  2197                         return FALSE; | 
 |  2198                 _AtlUpdateUIElement e; | 
 |  2199                 e.m_hWnd = hWnd; | 
 |  2200                 e.m_wType = UPDUI_CHILDWINDOW; | 
 |  2201                 return m_UIElements.Add(e); | 
 |  2202         } | 
 |  2203  | 
 |  2204 // Message map for popup menu updates and accelerator blocking | 
 |  2205         BEGIN_MSG_MAP(CUpdateUIBase) | 
 |  2206                 MESSAGE_HANDLER(WM_INITMENUPOPUP, OnInitMenuPopup) | 
 |  2207                 MESSAGE_HANDLER(WM_COMMAND, OnCommand) | 
 |  2208         END_MSG_MAP() | 
 |  2209  | 
 |  2210         LRESULT OnInitMenuPopup(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/,
       BOOL& bHandled) | 
 |  2211         { | 
 |  2212                 bHandled = FALSE; | 
 |  2213                 HMENU hMenu = (HMENU)wParam; | 
 |  2214                 if(hMenu == NULL) | 
 |  2215                         return 1; | 
 |  2216                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2217                 if(pUIData == NULL) | 
 |  2218                         return 1; | 
 |  2219                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2220                 while(pMap->m_nID != (WORD)-1) | 
 |  2221                 { | 
 |  2222                         if(pMap->m_wType & UPDUI_MENUPOPUP) | 
 |  2223                                 UIUpdateMenuBarElement(pMap->m_nID, pUIData, hMe
      nu); | 
 |  2224                         pMap++; | 
 |  2225                         pUIData++; | 
 |  2226                 } | 
 |  2227                 return 0; | 
 |  2228         } | 
 |  2229  | 
 |  2230         LRESULT OnCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL&
       bHandled) | 
 |  2231         { | 
 |  2232                 bHandled = FALSE; | 
 |  2233                 if(m_bBlockAccelerators && HIWORD(wParam) == 1)   // accelerator
      s only | 
 |  2234                 { | 
 |  2235                         int nID = LOWORD(wParam); | 
 |  2236                         if((UIGetState(nID) & UPDUI_DISABLED) == UPDUI_DISABLED) | 
 |  2237                         { | 
 |  2238                                 ATLTRACE2(atlTraceUI, 0, _T("CUpdateUIBase::OnCo
      mmand - blocked disabled command 0x%4.4X\n"), nID); | 
 |  2239                                 bHandled = TRUE;   // eat the command, UI item i
      s disabled | 
 |  2240                         } | 
 |  2241                 } | 
 |  2242                 return 0; | 
 |  2243         } | 
 |  2244  | 
 |  2245 // methods for setting UI element state | 
 |  2246         BOOL UIEnable(int nID, BOOL bEnable, BOOL bForceUpdate = FALSE) | 
 |  2247         { | 
 |  2248                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2249                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2250                 if(pUIData == NULL) | 
 |  2251                         return FALSE; | 
 |  2252  | 
 |  2253                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2254                 { | 
 |  2255                         if(nID == (int)pMap->m_nID) | 
 |  2256                         { | 
 |  2257                                 if(bEnable) | 
 |  2258                                 { | 
 |  2259                                         if(pUIData->m_wState & UPDUI_DISABLED) | 
 |  2260                                         { | 
 |  2261                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2262                                                 pUIData->m_wState &= ~UPDUI_DISA
      BLED; | 
 |  2263                                         } | 
 |  2264                                 } | 
 |  2265                                 else | 
 |  2266                                 { | 
 |  2267                                         if(!(pUIData->m_wState & UPDUI_DISABLED)
      ) | 
 |  2268                                         { | 
 |  2269                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2270                                                 pUIData->m_wState |= UPDUI_DISAB
      LED; | 
 |  2271                                         } | 
 |  2272                                 } | 
 |  2273  | 
 |  2274                                 if(bForceUpdate) | 
 |  2275                                         pUIData->m_wState |= pMap->m_wType; | 
 |  2276                                 if(pUIData->m_wState & pMap->m_wType) | 
 |  2277                                         m_wDirtyType |= pMap->m_wType; | 
 |  2278  | 
 |  2279                                 break;   // found | 
 |  2280                         } | 
 |  2281                 } | 
 |  2282  | 
 |  2283                 return TRUE; | 
 |  2284         } | 
 |  2285  | 
 |  2286         BOOL UISetCheck(int nID, int nCheck, BOOL bForceUpdate = FALSE) | 
 |  2287         { | 
 |  2288                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2289                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2290                 if(pUIData == NULL) | 
 |  2291                         return FALSE; | 
 |  2292  | 
 |  2293                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2294                 { | 
 |  2295                         if(nID == (int)pMap->m_nID) | 
 |  2296                         { | 
 |  2297                                 switch(nCheck) | 
 |  2298                                 { | 
 |  2299                                 case 0: | 
 |  2300                                         if((pUIData->m_wState & UPDUI_CHECKED) |
      | (pUIData->m_wState & UPDUI_CHECKED2)) | 
 |  2301                                         { | 
 |  2302                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2303                                                 pUIData->m_wState &= ~(UPDUI_CHE
      CKED | UPDUI_CHECKED2); | 
 |  2304                                         } | 
 |  2305                                         break; | 
 |  2306                                 case 1: | 
 |  2307                                         if(!(pUIData->m_wState & UPDUI_CHECKED)) | 
 |  2308                                         { | 
 |  2309                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2310                                                 pUIData->m_wState &= ~UPDUI_CHEC
      KED2; | 
 |  2311                                                 pUIData->m_wState |= UPDUI_CHECK
      ED; | 
 |  2312                                         } | 
 |  2313                                         break; | 
 |  2314                                 case 2: | 
 |  2315                                         if(!(pUIData->m_wState & UPDUI_CHECKED2)
      ) | 
 |  2316                                         { | 
 |  2317                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2318                                                 pUIData->m_wState &= ~UPDUI_CHEC
      KED; | 
 |  2319                                                 pUIData->m_wState |= UPDUI_CHECK
      ED2; | 
 |  2320                                         } | 
 |  2321                                         break; | 
 |  2322                                 } | 
 |  2323  | 
 |  2324                                 if(bForceUpdate) | 
 |  2325                                         pUIData->m_wState |= pMap->m_wType; | 
 |  2326                                 if(pUIData->m_wState & pMap->m_wType) | 
 |  2327                                         m_wDirtyType |= pMap->m_wType; | 
 |  2328  | 
 |  2329                                 break;   // found | 
 |  2330                         } | 
 |  2331                 } | 
 |  2332  | 
 |  2333                 return TRUE; | 
 |  2334         } | 
 |  2335  | 
 |  2336         // variant that supports bool (checked/not-checked, no intermediate stat
      e) | 
 |  2337         BOOL UISetCheck(int nID, bool bCheck, BOOL bForceUpdate = FALSE) | 
 |  2338         { | 
 |  2339                 return UISetCheck(nID, bCheck ? 1 : 0, bForceUpdate); | 
 |  2340         } | 
 |  2341  | 
 |  2342         BOOL UISetRadio(int nID, BOOL bRadio, BOOL bForceUpdate = FALSE) | 
 |  2343         { | 
 |  2344                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2345                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2346                 if(pUIData == NULL) | 
 |  2347                         return FALSE; | 
 |  2348  | 
 |  2349                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2350                 { | 
 |  2351                         if(nID == (int)pMap->m_nID) | 
 |  2352                         { | 
 |  2353                                 if(bRadio) | 
 |  2354                                 { | 
 |  2355                                         if(!(pUIData->m_wState & UPDUI_RADIO)) | 
 |  2356                                         { | 
 |  2357                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2358                                                 pUIData->m_wState |= UPDUI_RADIO
      ; | 
 |  2359                                         } | 
 |  2360                                 } | 
 |  2361                                 else | 
 |  2362                                 { | 
 |  2363                                         if(pUIData->m_wState & UPDUI_RADIO) | 
 |  2364                                         { | 
 |  2365                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2366                                                 pUIData->m_wState &= ~UPDUI_RADI
      O; | 
 |  2367                                         } | 
 |  2368                                 } | 
 |  2369  | 
 |  2370                                 if(bForceUpdate) | 
 |  2371                                         pUIData->m_wState |= pMap->m_wType; | 
 |  2372                                 if(pUIData->m_wState & pMap->m_wType) | 
 |  2373                                         m_wDirtyType |= pMap->m_wType; | 
 |  2374  | 
 |  2375                                 break;   // found | 
 |  2376                         } | 
 |  2377                 } | 
 |  2378  | 
 |  2379                 return TRUE; | 
 |  2380         } | 
 |  2381  | 
 |  2382         BOOL UISetText(int nID, LPCTSTR lpstrText, BOOL bForceUpdate = FALSE) | 
 |  2383         { | 
 |  2384                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2385                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2386                 if(pUIData == NULL) | 
 |  2387                         return FALSE; | 
 |  2388                 if(lpstrText == NULL) | 
 |  2389                         lpstrText = _T(""); | 
 |  2390  | 
 |  2391                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2392                 { | 
 |  2393                         if(nID == (int)pMap->m_nID) | 
 |  2394                         { | 
 |  2395                                 if(pUIData->m_lpstrText == NULL || lstrcmp(pUIDa
      ta->m_lpstrText, lpstrText)) | 
 |  2396                                 { | 
 |  2397                                         delete [] pUIData->m_lpstrText; | 
 |  2398                                         pUIData->m_lpstrText = NULL; | 
 |  2399                                         int nStrLen = lstrlen(lpstrText); | 
 |  2400                                         ATLTRY(pUIData->m_lpstrText = new TCHAR[
      nStrLen + 1]); | 
 |  2401                                         if(pUIData->m_lpstrText == NULL) | 
 |  2402                                         { | 
 |  2403                                                 ATLTRACE2(atlTraceUI, 0, _T("UIS
      etText - memory allocation failed\n")); | 
 |  2404                                                 break; | 
 |  2405                                         } | 
 |  2406                                         SecureHelper::strcpy_x(pUIData->m_lpstrT
      ext, nStrLen + 1, lpstrText); | 
 |  2407                                         pUIData->m_wState |= (UPDUI_TEXT | pMap-
      >m_wType); | 
 |  2408                                 } | 
 |  2409  | 
 |  2410                                 if(bForceUpdate) | 
 |  2411                                         pUIData->m_wState |= (UPDUI_TEXT | pMap-
      >m_wType); | 
 |  2412                                 if(pUIData->m_wState & pMap->m_wType) | 
 |  2413                                         m_wDirtyType |= pMap->m_wType; | 
 |  2414  | 
 |  2415                                 break;   // found | 
 |  2416                         } | 
 |  2417                 } | 
 |  2418  | 
 |  2419                 return TRUE; | 
 |  2420         } | 
 |  2421  | 
 |  2422         BOOL UISetDefault(int nID, BOOL bDefault, BOOL bForceUpdate = FALSE) | 
 |  2423         { | 
 |  2424                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2425                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2426                 if(pUIData == NULL) | 
 |  2427                         return FALSE; | 
 |  2428  | 
 |  2429                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2430                 { | 
 |  2431                         if(nID == (int)pMap->m_nID) | 
 |  2432                         { | 
 |  2433                                 if(bDefault) | 
 |  2434                                 { | 
 |  2435                                         if((pUIData->m_wState & UPDUI_DEFAULT) =
      = 0) | 
 |  2436                                         { | 
 |  2437                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2438                                                 pUIData->m_wState |= UPDUI_DEFAU
      LT; | 
 |  2439                                         } | 
 |  2440                                 } | 
 |  2441                                 else | 
 |  2442                                 { | 
 |  2443                                         if((pUIData->m_wState & UPDUI_DEFAULT) !
      = 0) | 
 |  2444                                         { | 
 |  2445                                                 pUIData->m_wState |= pMap->m_wTy
      pe; | 
 |  2446                                                 pUIData->m_wState &= ~UPDUI_DEFA
      ULT; | 
 |  2447                                                 pUIData->m_wState |= UPDUI_CLEAR
      DEFAULT; | 
 |  2448                                         } | 
 |  2449                                 } | 
 |  2450  | 
 |  2451                                 if(bForceUpdate) | 
 |  2452                                         pUIData->m_wState |= pMap->m_wType; | 
 |  2453                                 if(pUIData->m_wState & pMap->m_wType) | 
 |  2454                                         m_wDirtyType |= pMap->m_wType; | 
 |  2455  | 
 |  2456                                 break;   // found | 
 |  2457                         } | 
 |  2458                 } | 
 |  2459  | 
 |  2460                 return TRUE; | 
 |  2461         } | 
 |  2462  | 
 |  2463 // methods for complete state set/get | 
 |  2464         BOOL UISetState(int nID, DWORD dwState) | 
 |  2465         { | 
 |  2466                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2467                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2468                 if(pUIData == NULL) | 
 |  2469                         return FALSE; | 
 |  2470                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2471                 { | 
 |  2472                         if(nID == (int)pMap->m_nID) | 
 |  2473                         {                | 
 |  2474                                 pUIData->m_wState = (WORD)(dwState | pMap->m_wTy
      pe); | 
 |  2475                                 m_wDirtyType |= pMap->m_wType; | 
 |  2476                                 break;   // found | 
 |  2477                         } | 
 |  2478                 } | 
 |  2479                 return TRUE; | 
 |  2480         } | 
 |  2481  | 
 |  2482         DWORD UIGetState(int nID) | 
 |  2483         { | 
 |  2484                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2485                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2486                 if(pUIData == NULL) | 
 |  2487                         return 0; | 
 |  2488                 for( ; pMap->m_nID != (WORD)-1; pMap++, pUIData++) | 
 |  2489                 { | 
 |  2490                         if(nID == (int)pMap->m_nID) | 
 |  2491                                 return pUIData->m_wState; | 
 |  2492                 } | 
 |  2493                 return 0; | 
 |  2494         } | 
 |  2495  | 
 |  2496 // methods for updating UI | 
 |  2497 #ifndef _WIN32_WCE | 
 |  2498         BOOL UIUpdateMenuBar(BOOL bForceUpdate = FALSE, BOOL bMainMenu = FALSE) | 
 |  2499         { | 
 |  2500                 if(!(m_wDirtyType & UPDUI_MENUBAR) && !bForceUpdate) | 
 |  2501                         return TRUE; | 
 |  2502  | 
 |  2503                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2504                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2505                 if(pUIData == NULL) | 
 |  2506                         return FALSE; | 
 |  2507  | 
 |  2508                 while(pMap->m_nID != (WORD)-1) | 
 |  2509                 { | 
 |  2510                         for(int i = 0; i < m_UIElements.GetSize(); i++) | 
 |  2511                         { | 
 |  2512                                 if(m_UIElements[i].m_wType == UPDUI_MENUBAR) | 
 |  2513                                 { | 
 |  2514                                         HMENU hMenu = ::GetMenu(m_UIElements[i].
      m_hWnd); | 
 |  2515                                         if(hMenu != NULL && (pUIData->m_wState &
       UPDUI_MENUBAR) && (pMap->m_wType & UPDUI_MENUBAR)) | 
 |  2516                                                 UIUpdateMenuBarElement(pMap->m_n
      ID, pUIData, hMenu); | 
 |  2517                                 } | 
 |  2518                                 if(bMainMenu) | 
 |  2519                                         ::DrawMenuBar(m_UIElements[i].m_hWnd); | 
 |  2520                         } | 
 |  2521                         pMap++; | 
 |  2522                         pUIData->m_wState &= ~UPDUI_MENUBAR; | 
 |  2523                         if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2524                         { | 
 |  2525                                 delete [] pUIData->m_lpstrText; | 
 |  2526                                 pUIData->m_lpstrText = NULL; | 
 |  2527                                 pUIData->m_wState &= ~UPDUI_TEXT; | 
 |  2528                         } | 
 |  2529                         pUIData++; | 
 |  2530                 } | 
 |  2531  | 
 |  2532                 m_wDirtyType &= ~UPDUI_MENUBAR; | 
 |  2533                 return TRUE; | 
 |  2534         } | 
 |  2535 #endif // !_WIN32_WCE | 
 |  2536  | 
 |  2537         BOOL UIUpdateToolBar(BOOL bForceUpdate = FALSE) | 
 |  2538         { | 
 |  2539                 if(!(m_wDirtyType & UPDUI_TOOLBAR) && !bForceUpdate) | 
 |  2540                         return TRUE; | 
 |  2541  | 
 |  2542                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2543                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2544                 if(pUIData == NULL) | 
 |  2545                         return FALSE; | 
 |  2546  | 
 |  2547                 while(pMap->m_nID != (WORD)-1) | 
 |  2548                 { | 
 |  2549                         for(int i = 0; i < m_UIElements.GetSize(); i++) | 
 |  2550                         { | 
 |  2551                                 if(m_UIElements[i].m_wType == UPDUI_TOOLBAR) | 
 |  2552                                 { | 
 |  2553                                         if((pUIData->m_wState & UPDUI_TOOLBAR) &
      & (pMap->m_wType & UPDUI_TOOLBAR)) | 
 |  2554                                                 UIUpdateToolBarElement(pMap->m_n
      ID, pUIData, m_UIElements[i].m_hWnd); | 
 |  2555                                 } | 
 |  2556                         } | 
 |  2557                         pMap++; | 
 |  2558                         pUIData->m_wState &= ~UPDUI_TOOLBAR; | 
 |  2559                         pUIData++; | 
 |  2560                 } | 
 |  2561  | 
 |  2562                 m_wDirtyType &= ~UPDUI_TOOLBAR; | 
 |  2563                 return TRUE; | 
 |  2564         } | 
 |  2565  | 
 |  2566         BOOL UIUpdateStatusBar(BOOL bForceUpdate = FALSE) | 
 |  2567         { | 
 |  2568                 if(!(m_wDirtyType & UPDUI_STATUSBAR) && !bForceUpdate) | 
 |  2569                         return TRUE; | 
 |  2570  | 
 |  2571                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2572                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2573                 if(pUIData == NULL) | 
 |  2574                         return FALSE; | 
 |  2575  | 
 |  2576                 while(pMap->m_nID != (WORD)-1) | 
 |  2577                 { | 
 |  2578                         for(int i = 0; i < m_UIElements.GetSize(); i++) | 
 |  2579                         { | 
 |  2580                                 if(m_UIElements[i].m_wType == UPDUI_STATUSBAR) | 
 |  2581                                 { | 
 |  2582                                         if((pUIData->m_wState & UPDUI_STATUSBAR)
       && (pMap->m_wType & UPDUI_STATUSBAR)) | 
 |  2583                                                 UIUpdateStatusBarElement(pMap->m
      _nID, pUIData, m_UIElements[i].m_hWnd); | 
 |  2584                                 } | 
 |  2585                         } | 
 |  2586                         pMap++; | 
 |  2587                         pUIData->m_wState &= ~UPDUI_STATUSBAR; | 
 |  2588                         if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2589                         { | 
 |  2590                                 delete [] pUIData->m_lpstrText; | 
 |  2591                                 pUIData->m_lpstrText = NULL; | 
 |  2592                                 pUIData->m_wState &= ~UPDUI_TEXT; | 
 |  2593                         } | 
 |  2594                         pUIData++; | 
 |  2595                 } | 
 |  2596  | 
 |  2597                 m_wDirtyType &= ~UPDUI_STATUSBAR; | 
 |  2598                 return TRUE; | 
 |  2599         } | 
 |  2600  | 
 |  2601         BOOL UIUpdateChildWindows(BOOL bForceUpdate = FALSE) | 
 |  2602         { | 
 |  2603                 if(!(m_wDirtyType & UPDUI_CHILDWINDOW) && !bForceUpdate) | 
 |  2604                         return TRUE; | 
 |  2605  | 
 |  2606                 const _AtlUpdateUIMap* pMap = m_pUIMap; | 
 |  2607                 _AtlUpdateUIData* pUIData = m_pUIData; | 
 |  2608                 if(pUIData == NULL) | 
 |  2609                         return FALSE; | 
 |  2610  | 
 |  2611                 while(pMap->m_nID != (WORD)-1) | 
 |  2612                 { | 
 |  2613                         for(int i = 0; i < m_UIElements.GetSize(); i++) | 
 |  2614                         { | 
 |  2615                                 if(m_UIElements[i].m_wType == UPDUI_CHILDWINDOW) | 
 |  2616                                 { | 
 |  2617                                         if((pUIData->m_wState & UPDUI_CHILDWINDO
      W) && (pMap->m_wType & UPDUI_CHILDWINDOW)) | 
 |  2618                                                 UIUpdateChildWindow(pMap->m_nID,
       pUIData, m_UIElements[i].m_hWnd); | 
 |  2619                                 } | 
 |  2620                         } | 
 |  2621                         pMap++; | 
 |  2622                         pUIData->m_wState &= ~UPDUI_CHILDWINDOW; | 
 |  2623                         if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2624                         { | 
 |  2625                                 delete [] pUIData->m_lpstrText; | 
 |  2626                                 pUIData->m_lpstrText = NULL; | 
 |  2627                                 pUIData->m_wState &= ~UPDUI_TEXT; | 
 |  2628                         } | 
 |  2629                         pUIData++; | 
 |  2630                 } | 
 |  2631  | 
 |  2632                 m_wDirtyType &= ~UPDUI_CHILDWINDOW; | 
 |  2633                 return TRUE; | 
 |  2634         } | 
 |  2635  | 
 |  2636 // internal element specific methods | 
 |  2637         static void UIUpdateMenuBarElement(int nID, _AtlUpdateUIData* pUIData, H
      MENU hMenu) | 
 |  2638         { | 
 |  2639 #ifndef _WIN32_WCE | 
 |  2640                 if((pUIData->m_wState & UPDUI_CLEARDEFAULT) != 0) | 
 |  2641                 { | 
 |  2642                         ::SetMenuDefaultItem(hMenu, (UINT)-1, 0); | 
 |  2643                         pUIData->m_wState &= ~UPDUI_CLEARDEFAULT; | 
 |  2644                 } | 
 |  2645 #endif // !_WIN32_WCE | 
 |  2646  | 
 |  2647                 CMenuItemInfo mii; | 
 |  2648                 mii.fMask = MIIM_STATE; | 
 |  2649                 mii.wID = nID; | 
 |  2650  | 
 |  2651 #ifndef _WIN32_WCE | 
 |  2652                 if((pUIData->m_wState & UPDUI_DISABLED) != 0) | 
 |  2653                         mii.fState |= MFS_DISABLED | MFS_GRAYED; | 
 |  2654                 else | 
 |  2655                         mii.fState |= MFS_ENABLED; | 
 |  2656  | 
 |  2657                 if((pUIData->m_wState & UPDUI_CHECKED) != 0) | 
 |  2658                         mii.fState |= MFS_CHECKED; | 
 |  2659                 else | 
 |  2660                         mii.fState |= MFS_UNCHECKED; | 
 |  2661  | 
 |  2662                 if((pUIData->m_wState & UPDUI_DEFAULT) != 0) | 
 |  2663                         mii.fState |= MFS_DEFAULT; | 
 |  2664 #else // CE specific | 
 |  2665                 // ::SetMenuItemInfo() can't disable or check menu items | 
 |  2666                 // on Windows CE, so we have to do that directly | 
 |  2667                 UINT uEnable = MF_BYCOMMAND; | 
 |  2668                 if((pUIData->m_wState & UPDUI_DISABLED) != 0) | 
 |  2669                         uEnable |= MF_GRAYED; | 
 |  2670                 else | 
 |  2671                         uEnable |= MF_ENABLED; | 
 |  2672                 ::EnableMenuItem(hMenu, nID, uEnable); | 
 |  2673  | 
 |  2674                 UINT uCheck = MF_BYCOMMAND; | 
 |  2675                 if((pUIData->m_wState & UPDUI_CHECKED) != 0) | 
 |  2676                         uCheck |= MF_CHECKED; | 
 |  2677                 else | 
 |  2678                         uCheck |= MF_UNCHECKED; | 
 |  2679                 ::CheckMenuItem(hMenu, nID, uCheck); | 
 |  2680 #endif // _WIN32_WCE | 
 |  2681  | 
 |  2682                 if((pUIData->m_wState & UPDUI_TEXT) != 0) | 
 |  2683                 { | 
 |  2684                         CMenuItemInfo miiNow; | 
 |  2685                         miiNow.fMask = MIIM_TYPE; | 
 |  2686                         miiNow.wID = nID; | 
 |  2687                         if(::GetMenuItemInfo(hMenu, nID, FALSE, &miiNow)) | 
 |  2688                         { | 
 |  2689                                 mii.fMask |= MIIM_TYPE; | 
 |  2690                                 // MFT_BITMAP and MFT_SEPARATOR don't go togethe
      r with MFT_STRING | 
 |  2691 #ifndef _WIN32_WCE | 
 |  2692                                 mii.fType |= (miiNow.fType & ~(MFT_BITMAP | MFT_
      SEPARATOR)) | MFT_STRING; | 
 |  2693 #else // CE specific | 
 |  2694                                 mii.fType |= (miiNow.fType & ~(MFT_SEPARATOR)) |
       MFT_STRING; | 
 |  2695 #endif // _WIN32_WCE | 
 |  2696                                 mii.dwTypeData = pUIData->m_lpstrText; | 
 |  2697                         } | 
 |  2698                 } | 
 |  2699  | 
 |  2700                 ::SetMenuItemInfo(hMenu, nID, FALSE, &mii); | 
 |  2701         } | 
 |  2702  | 
 |  2703         static void UIUpdateToolBarElement(int nID, _AtlUpdateUIData* pUIData, H
      WND hWndToolBar) | 
 |  2704         { | 
 |  2705                 // Note: only handles enabled/disabled, checked state, and radio
       (press) | 
 |  2706                 ::SendMessage(hWndToolBar, TB_ENABLEBUTTON, nID, (LPARAM)(pUIDat
      a->m_wState & UPDUI_DISABLED) ? FALSE : TRUE); | 
 |  2707                 ::SendMessage(hWndToolBar, TB_CHECKBUTTON, nID, (LPARAM)(pUIData
      ->m_wState & UPDUI_CHECKED) ? TRUE : FALSE); | 
 |  2708                 ::SendMessage(hWndToolBar, TB_INDETERMINATE, nID, (LPARAM)(pUIDa
      ta->m_wState & UPDUI_CHECKED2) ? TRUE : FALSE); | 
 |  2709                 ::SendMessage(hWndToolBar, TB_PRESSBUTTON, nID, (LPARAM)(pUIData
      ->m_wState & UPDUI_RADIO) ? TRUE : FALSE); | 
 |  2710         } | 
 |  2711  | 
 |  2712         static void UIUpdateStatusBarElement(int nID, _AtlUpdateUIData* pUIData,
       HWND hWndStatusBar) | 
 |  2713         { | 
 |  2714                 // Note: only handles text | 
 |  2715                 if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2716                         ::SendMessage(hWndStatusBar, SB_SETTEXT, nID, (LPARAM)pU
      IData->m_lpstrText); | 
 |  2717         } | 
 |  2718  | 
 |  2719         static void UIUpdateChildWindow(int nID, _AtlUpdateUIData* pUIData, HWND
       hWnd) | 
 |  2720         { | 
 |  2721                 HWND hChild = ::GetDlgItem(hWnd, nID); | 
 |  2722  | 
 |  2723                 ::EnableWindow(hChild, (pUIData->m_wState & UPDUI_DISABLED) ? FA
      LSE : TRUE); | 
 |  2724                 // for check and radio, assume that window is a button | 
 |  2725                 int nCheck = BST_UNCHECKED; | 
 |  2726                 if(pUIData->m_wState & UPDUI_CHECKED || pUIData->m_wState & UPDU
      I_RADIO) | 
 |  2727                         nCheck = BST_CHECKED; | 
 |  2728                 else if(pUIData->m_wState & UPDUI_CHECKED2) | 
 |  2729                         nCheck = BST_INDETERMINATE; | 
 |  2730                 ::SendMessage(hChild, BM_SETCHECK, nCheck, 0L); | 
 |  2731                 if(pUIData->m_wState & UPDUI_DEFAULT) | 
 |  2732                 { | 
 |  2733                         DWORD dwRet = (DWORD)::SendMessage(hWnd, DM_GETDEFID, 0,
       0L); | 
 |  2734                         if(HIWORD(dwRet) == DC_HASDEFID) | 
 |  2735                         { | 
 |  2736                                 HWND hOldDef = ::GetDlgItem(hWnd, (int)(short)LO
      WORD(dwRet)); | 
 |  2737                                 // remove BS_DEFPUSHBUTTON | 
 |  2738                                 ::SendMessage(hOldDef, BM_SETSTYLE, BS_PUSHBUTTO
      N, MAKELPARAM(TRUE, 0)); | 
 |  2739                         } | 
 |  2740                         ::SendMessage(hWnd, DM_SETDEFID, nID, 0L); | 
 |  2741                 } | 
 |  2742                 if(pUIData->m_wState & UPDUI_TEXT) | 
 |  2743                         ::SetWindowText(hChild, pUIData->m_lpstrText); | 
 |  2744         } | 
 |  2745 }; | 
 |  2746  | 
 |  2747 template <class T> | 
 |  2748 class CUpdateUI : public CUpdateUIBase | 
 |  2749 { | 
 |  2750 public: | 
 |  2751         CUpdateUI() | 
 |  2752         { | 
 |  2753                 T* pT = static_cast<T*>(this); | 
 |  2754                 pT; | 
 |  2755                 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); | 
 |  2756                 m_pUIMap = pMap; | 
 |  2757                 ATLASSERT(m_pUIMap != NULL); | 
 |  2758                 int nCount; | 
 |  2759                 for(nCount = 1; pMap->m_nID != (WORD)-1; nCount++) | 
 |  2760                         pMap++; | 
 |  2761  | 
 |  2762                 // check for duplicates (debug only) | 
 |  2763 #ifdef _DEBUG | 
 |  2764                 for(int i = 0; i < nCount; i++) | 
 |  2765                 { | 
 |  2766                         for(int j = 0; j < nCount; j++) | 
 |  2767                         { | 
 |  2768                                 // shouldn't have duplicates in the update UI ma
      p | 
 |  2769                                 if(i != j) | 
 |  2770                                         ATLASSERT(m_pUIMap[j].m_nID != m_pUIMap[
      i].m_nID); | 
 |  2771                         } | 
 |  2772                 } | 
 |  2773 #endif // _DEBUG | 
 |  2774  | 
 |  2775                 ATLTRY(m_pUIData = new _AtlUpdateUIData[nCount]); | 
 |  2776                 ATLASSERT(m_pUIData != NULL); | 
 |  2777  | 
 |  2778                 if(m_pUIData != NULL) | 
 |  2779                         memset(m_pUIData, 0, sizeof(_AtlUpdateUIData) * nCount); | 
 |  2780         } | 
 |  2781 }; | 
 |  2782  | 
 |  2783  | 
 |  2784 /////////////////////////////////////////////////////////////////////////////// | 
 |  2785 // CDynamicUpdateUI - allows update elements to dynamically added and removed | 
 |  2786 //                    in addition to a static update UI map | 
 |  2787  | 
 |  2788 template <class T> | 
 |  2789 class CDynamicUpdateUI : public CUpdateUIBase | 
 |  2790 { | 
 |  2791 public: | 
 |  2792 // Data members | 
 |  2793         ATL::CSimpleArray<_AtlUpdateUIMap> m_arrUIMap;     // copy of the static
       UI data | 
 |  2794         ATL::CSimpleArray<_AtlUpdateUIData> m_arrUIData;   // instance UI data | 
 |  2795  | 
 |  2796 // Constructor/destructor | 
 |  2797         CDynamicUpdateUI() | 
 |  2798         { | 
 |  2799                 T* pT = static_cast<T*>(this); | 
 |  2800                 pT; | 
 |  2801                 const _AtlUpdateUIMap* pMap = pT->GetUpdateUIMap(); | 
 |  2802                 ATLASSERT(pMap != NULL); | 
 |  2803  | 
 |  2804                 for(;;) | 
 |  2805                 { | 
 |  2806                         BOOL bRet = m_arrUIMap.Add(*(_AtlUpdateUIMap*)pMap); | 
 |  2807                         ATLASSERT(bRet); | 
 |  2808  | 
 |  2809                         if(bRet != FALSE) | 
 |  2810                         { | 
 |  2811                                 _AtlUpdateUIData data = { 0, NULL }; | 
 |  2812                                 bRet = m_arrUIData.Add(data); | 
 |  2813                                 ATLASSERT(bRet); | 
 |  2814                         } | 
 |  2815  | 
 |  2816                         if(pMap->m_nID == (WORD)-1) | 
 |  2817                                 break; | 
 |  2818  | 
 |  2819                         pMap++; | 
 |  2820                 } | 
 |  2821  | 
 |  2822                 ATLASSERT(m_arrUIMap.GetSize() == m_arrUIData.GetSize()); | 
 |  2823  | 
 |  2824 #ifdef _DEBUG | 
 |  2825                 // check for duplicates (debug only) | 
 |  2826                 for(int i = 0; i < m_arrUIMap.GetSize(); i++) | 
 |  2827                 { | 
 |  2828                         for(int j = 0; j < m_arrUIMap.GetSize(); j++) | 
 |  2829                         { | 
 |  2830                                 // shouldn't have duplicates in the update UI ma
      p | 
 |  2831                                 if(i != j) | 
 |  2832                                         ATLASSERT(m_arrUIMap[j].m_nID != m_arrUI
      Map[i].m_nID); | 
 |  2833                         } | 
 |  2834                 } | 
 |  2835 #endif // _DEBUG | 
 |  2836  | 
 |  2837                 // Set internal data pointers to point to the new data arrays | 
 |  2838                 m_pUIMap = m_arrUIMap.m_aT; | 
 |  2839                 m_pUIData = m_arrUIData.m_aT; | 
 |  2840         } | 
 |  2841  | 
 |  2842         ~CDynamicUpdateUI() | 
 |  2843         { | 
 |  2844                 for(int i = 0; i < m_arrUIData.GetSize(); i++) | 
 |  2845                 { | 
 |  2846                         if((m_arrUIData[i].m_wState & UPDUI_TEXT) != 0) | 
 |  2847                                 delete [] m_arrUIData[i].m_lpstrText; | 
 |  2848                 } | 
 |  2849  | 
 |  2850                 // Reset internal data pointers (memory will be released by CSim
      pleArray d-tor) | 
 |  2851                 m_pUIMap = NULL; | 
 |  2852                 m_pUIData = NULL; | 
 |  2853         } | 
 |  2854  | 
 |  2855 // Methods for dynamically adding and removing update elements | 
 |  2856         bool UIAddUpdateElement(WORD nID, WORD wType) | 
 |  2857         { | 
 |  2858                 // check for duplicates | 
 |  2859                 for(int i = 0; i < m_arrUIMap.GetSize(); i++) | 
 |  2860                 { | 
 |  2861                         // shouldn't have duplicates in the update UI map | 
 |  2862                         ATLASSERT(m_arrUIMap[i].m_nID != nID); | 
 |  2863                         if(m_arrUIMap[i].m_nID == nID) | 
 |  2864                                 return false; | 
 |  2865                 } | 
 |  2866  | 
 |  2867                 bool bRetVal = false; | 
 |  2868  | 
 |  2869                 // Add new end element | 
 |  2870                 _AtlUpdateUIMap uumEnd = { (WORD)-1, 0 }; | 
 |  2871                 BOOL bRet = m_arrUIMap.Add(uumEnd); | 
 |  2872                 ATLASSERT(bRet); | 
 |  2873  | 
 |  2874                 if(bRet != FALSE) | 
 |  2875                 { | 
 |  2876                         _AtlUpdateUIData uud = { 0, NULL }; | 
 |  2877                         bRet = m_arrUIData.Add(uud); | 
 |  2878                         ATLASSERT(bRet); | 
 |  2879  | 
 |  2880                         // Set new data to the previous end element | 
 |  2881                         if(bRet != FALSE) | 
 |  2882                         { | 
 |  2883                                 int nSize = m_arrUIMap.GetSize(); | 
 |  2884                                 _AtlUpdateUIMap uum = { nID, wType }; | 
 |  2885                                 m_arrUIMap.SetAtIndex(nSize - 2, uum); | 
 |  2886                                 m_arrUIData.SetAtIndex(nSize - 2, uud); | 
 |  2887  | 
 |  2888                                 // Set internal data pointers again, just in cas
      e that memory moved | 
 |  2889                                 m_pUIMap = m_arrUIMap.m_aT; | 
 |  2890                                 m_pUIData = m_arrUIData.m_aT; | 
 |  2891  | 
 |  2892                                 bRetVal = true; | 
 |  2893                         } | 
 |  2894                 } | 
 |  2895  | 
 |  2896                 return bRetVal; | 
 |  2897         } | 
 |  2898  | 
 |  2899         bool UIRemoveUpdateElement(WORD nID) | 
 |  2900         { | 
 |  2901                 bool bRetVal = false; | 
 |  2902  | 
 |  2903                 for(int i = 0; i < m_arrUIMap.GetSize(); i++) | 
 |  2904                 { | 
 |  2905                         if(m_arrUIMap[i].m_nID == nID) | 
 |  2906                         { | 
 |  2907                                 BOOL bRet = m_arrUIMap.RemoveAt(i); | 
 |  2908                                 ATLASSERT(bRet); | 
 |  2909                                 bRet = m_arrUIData.RemoveAt(i); | 
 |  2910                                 ATLASSERT(bRet); | 
 |  2911  | 
 |  2912                                 bRetVal = true; | 
 |  2913                                 break; | 
 |  2914                         } | 
 |  2915                 } | 
 |  2916  | 
 |  2917                 return bRetVal; | 
 |  2918         } | 
 |  2919 }; | 
 |  2920  | 
 |  2921  | 
 |  2922 /////////////////////////////////////////////////////////////////////////////// | 
 |  2923 // CDialogResize - provides support for resizing dialog controls | 
 |  2924 //                 (works for any window that has child controls) | 
 |  2925  | 
 |  2926 // Put CDialogResize in the list of base classes for a dialog (or even plain win
      dow), | 
 |  2927 // then implement DLGRESIZE map by specifying controls and groups of control | 
 |  2928 // and using DLSZ_* values to specify how are they supposed to be resized. | 
 |  2929 // | 
 |  2930 // Notes: | 
 |  2931 // - Resizeable border (WS_THICKFRAME style) should be set in the dialog templat
      e | 
 |  2932 //   for top level dialogs (popup or overlapped), so that users can resize the d
      ialog. | 
 |  2933 // - Some flags cannot be combined; for instance DLSZ_CENTER_X overrides DLSZ_SI
      ZE_X, | 
 |  2934 //   DLSZ_SIZE_X overrides DLSZ_MOVE_X. X and Y flags can be combined. | 
 |  2935 // - Order of controls is important - group controls are resized and moved based | 
 |  2936 //   on the position of the previous control in a group. | 
 |  2937  | 
 |  2938 // dialog resize map macros | 
 |  2939 #define BEGIN_DLGRESIZE_MAP(thisClass) \ | 
 |  2940         static const _AtlDlgResizeMap* GetDlgResizeMap() \ | 
 |  2941         { \ | 
 |  2942                 static const _AtlDlgResizeMap theMap[] = \ | 
 |  2943                 { | 
 |  2944  | 
 |  2945 #define END_DLGRESIZE_MAP() \ | 
 |  2946                         { -1, 0 }, \ | 
 |  2947                 }; \ | 
 |  2948                 return theMap; \ | 
 |  2949         } | 
 |  2950  | 
 |  2951 #define DLGRESIZE_CONTROL(id, flags) \ | 
 |  2952                 { id, flags }, | 
 |  2953  | 
 |  2954 #define BEGIN_DLGRESIZE_GROUP() \ | 
 |  2955                 { -1, _DLSZ_BEGIN_GROUP }, | 
 |  2956  | 
 |  2957 #define END_DLGRESIZE_GROUP() \ | 
 |  2958                 { -1, _DLSZ_END_GROUP }, | 
 |  2959  | 
 |  2960  | 
 |  2961 template <class T> | 
 |  2962 class CDialogResize | 
 |  2963 { | 
 |  2964 public: | 
 |  2965 // Data declarations and members | 
 |  2966         enum | 
 |  2967         { | 
 |  2968                 DLSZ_SIZE_X             = 0x00000001, | 
 |  2969                 DLSZ_SIZE_Y             = 0x00000002, | 
 |  2970                 DLSZ_MOVE_X             = 0x00000004, | 
 |  2971                 DLSZ_MOVE_Y             = 0x00000008, | 
 |  2972                 DLSZ_REPAINT            = 0x00000010, | 
 |  2973                 DLSZ_CENTER_X           = 0x00000020, | 
 |  2974                 DLSZ_CENTER_Y           = 0x00000040, | 
 |  2975  | 
 |  2976                 // internal use only | 
 |  2977                 _DLSZ_BEGIN_GROUP       = 0x00001000, | 
 |  2978                 _DLSZ_END_GROUP         = 0x00002000, | 
 |  2979                 _DLSZ_GRIPPER           = 0x00004000 | 
 |  2980         }; | 
 |  2981  | 
 |  2982         struct _AtlDlgResizeMap | 
 |  2983         { | 
 |  2984                 int m_nCtlID; | 
 |  2985                 DWORD m_dwResizeFlags; | 
 |  2986         }; | 
 |  2987  | 
 |  2988         struct _AtlDlgResizeData | 
 |  2989         { | 
 |  2990                 int m_nCtlID; | 
 |  2991                 DWORD m_dwResizeFlags; | 
 |  2992                 RECT m_rect; | 
 |  2993  | 
 |  2994                 int GetGroupCount() const | 
 |  2995                 { | 
 |  2996                         return (int)LOBYTE(HIWORD(m_dwResizeFlags)); | 
 |  2997                 } | 
 |  2998  | 
 |  2999                 void SetGroupCount(int nCount) | 
 |  3000                 { | 
 |  3001                         ATLASSERT(nCount > 0 && nCount < 256); | 
 |  3002                         DWORD dwCount = (DWORD)MAKELONG(0, MAKEWORD(nCount, 0)); | 
 |  3003                         m_dwResizeFlags &= 0xFF00FFFF; | 
 |  3004                         m_dwResizeFlags |= dwCount; | 
 |  3005                 } | 
 |  3006  | 
 |  3007                 bool operator ==(const _AtlDlgResizeData& r) const | 
 |  3008                 { return (m_nCtlID == r.m_nCtlID && m_dwResizeFlags == r.m_dwRes
      izeFlags); } | 
 |  3009         }; | 
 |  3010  | 
 |  3011         ATL::CSimpleArray<_AtlDlgResizeData> m_arrData; | 
 |  3012         SIZE m_sizeDialog; | 
 |  3013         POINT m_ptMinTrackSize; | 
 |  3014         bool m_bGripper; | 
 |  3015  | 
 |  3016  | 
 |  3017 // Constructor | 
 |  3018         CDialogResize() : m_bGripper(false) | 
 |  3019         { | 
 |  3020                 m_sizeDialog.cx = 0; | 
 |  3021                 m_sizeDialog.cy = 0; | 
 |  3022                 m_ptMinTrackSize.x = -1; | 
 |  3023                 m_ptMinTrackSize.y = -1; | 
 |  3024         } | 
 |  3025  | 
 |  3026 // Operations | 
 |  3027         void DlgResize_Init(bool bAddGripper = true, bool bUseMinTrackSize = tru
      e, DWORD dwForceStyle = WS_CLIPCHILDREN) | 
 |  3028         { | 
 |  3029                 T* pT = static_cast<T*>(this); | 
 |  3030                 ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  3031  | 
 |  3032                 DWORD dwStyle = pT->GetStyle(); | 
 |  3033  | 
 |  3034 #ifdef _DEBUG | 
 |  3035                 // Debug only: Check if top level dialogs have a resizeable bord
      er. | 
 |  3036                 if(((dwStyle & WS_CHILD) == 0) && ((dwStyle & WS_THICKFRAME) == 
      0)) | 
 |  3037                         ATLTRACE2(atlTraceUI, 0, _T("DlgResize_Init - warning: t
      op level dialog without the WS_THICKFRAME style - user cannot resize it\n")); | 
 |  3038 #endif // _DEBUG | 
 |  3039  | 
 |  3040                 // Force specified styles (default WS_CLIPCHILDREN reduces flick
      er) | 
 |  3041                 if((dwStyle & dwForceStyle) != dwForceStyle) | 
 |  3042                         pT->ModifyStyle(0, dwForceStyle); | 
 |  3043  | 
 |  3044                 // Adding this style removes an empty icon that dialogs with WS_
      THICKFRAME have. | 
 |  3045                 // Setting icon to NULL is required when XP themes are active. | 
 |  3046                 // Note: This will not prevent adding an icon for the dialog usi
      ng SetIcon() | 
 |  3047                 if((dwStyle & WS_CHILD) == 0) | 
 |  3048                 { | 
 |  3049                         pT->ModifyStyleEx(0, WS_EX_DLGMODALFRAME); | 
 |  3050                         if(pT->GetIcon(FALSE) == NULL) | 
 |  3051                                 pT->SetIcon(NULL, FALSE); | 
 |  3052                 } | 
 |  3053  | 
 |  3054                 // Cleanup in case of multiple initialization | 
 |  3055                 // block: first check for the gripper control, destroy it if nee
      ded | 
 |  3056                 { | 
 |  3057                         ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_
      BAR); | 
 |  3058                         if(wndGripper.IsWindow() && m_arrData.GetSize() > 0 && (
      m_arrData[0].m_dwResizeFlags & _DLSZ_GRIPPER) != 0) | 
 |  3059                                 wndGripper.DestroyWindow(); | 
 |  3060                 } | 
 |  3061                 // clear out everything else | 
 |  3062                 m_arrData.RemoveAll(); | 
 |  3063                 m_sizeDialog.cx = 0; | 
 |  3064                 m_sizeDialog.cy = 0; | 
 |  3065                 m_ptMinTrackSize.x = -1; | 
 |  3066                 m_ptMinTrackSize.y = -1; | 
 |  3067  | 
 |  3068                 // Get initial dialog client size | 
 |  3069                 RECT rectDlg = { 0 }; | 
 |  3070                 pT->GetClientRect(&rectDlg); | 
 |  3071                 m_sizeDialog.cx = rectDlg.right; | 
 |  3072                 m_sizeDialog.cy = rectDlg.bottom; | 
 |  3073  | 
 |  3074 #ifndef _WIN32_WCE | 
 |  3075                 // Create gripper if requested | 
 |  3076                 m_bGripper = false; | 
 |  3077                 if(bAddGripper) | 
 |  3078                 { | 
 |  3079                         // shouldn't exist already | 
 |  3080                         ATLASSERT(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR)
      )); | 
 |  3081                         if(!::IsWindow(pT->GetDlgItem(ATL_IDW_STATUS_BAR))) | 
 |  3082                         { | 
 |  3083                                 ATL::CWindow wndGripper; | 
 |  3084                                 wndGripper.Create(_T("SCROLLBAR"), pT->m_hWnd, r
      ectDlg, NULL, WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | SBS_SIZEBOX | SBS_SIZEGR
      IP | SBS_SIZEBOXBOTTOMRIGHTALIGN, 0, ATL_IDW_STATUS_BAR); | 
 |  3085                                 ATLASSERT(wndGripper.IsWindow()); | 
 |  3086                                 if(wndGripper.IsWindow()) | 
 |  3087                                 { | 
 |  3088                                         m_bGripper = true; | 
 |  3089                                         RECT rectCtl = { 0 }; | 
 |  3090                                         wndGripper.GetWindowRect(&rectCtl); | 
 |  3091                                         ::MapWindowPoints(NULL, pT->m_hWnd, (LPP
      OINT)&rectCtl, 2); | 
 |  3092                                         _AtlDlgResizeData data = { ATL_IDW_STATU
      S_BAR, DLSZ_MOVE_X | DLSZ_MOVE_Y | DLSZ_REPAINT | _DLSZ_GRIPPER, { rectCtl.left,
       rectCtl.top, rectCtl.right, rectCtl.bottom } }; | 
 |  3093                                         m_arrData.Add(data); | 
 |  3094                                 } | 
 |  3095                         } | 
 |  3096                 } | 
 |  3097 #else // CE specific | 
 |  3098                 bAddGripper;   // avoid level 4 warning | 
 |  3099 #endif // _WIN32_WCE | 
 |  3100  | 
 |  3101                 // Get min track position if requested | 
 |  3102                 if(bUseMinTrackSize) | 
 |  3103                 { | 
 |  3104                         if((dwStyle & WS_CHILD) != 0) | 
 |  3105                         { | 
 |  3106                                 RECT rect = { 0 }; | 
 |  3107                                 pT->GetClientRect(&rect); | 
 |  3108                                 m_ptMinTrackSize.x = rect.right - rect.left; | 
 |  3109                                 m_ptMinTrackSize.y = rect.bottom - rect.top; | 
 |  3110                         } | 
 |  3111                         else | 
 |  3112                         { | 
 |  3113                                 RECT rect = { 0 }; | 
 |  3114                                 pT->GetWindowRect(&rect); | 
 |  3115                                 m_ptMinTrackSize.x = rect.right - rect.left; | 
 |  3116                                 m_ptMinTrackSize.y = rect.bottom - rect.top; | 
 |  3117                         } | 
 |  3118                 } | 
 |  3119  | 
 |  3120                 // Walk the map and initialize data | 
 |  3121                 const _AtlDlgResizeMap* pMap = pT->GetDlgResizeMap(); | 
 |  3122                 ATLASSERT(pMap != NULL); | 
 |  3123                 int nGroupStart = -1; | 
 |  3124                 for(int nCount = 1; !(pMap->m_nCtlID == -1 && pMap->m_dwResizeFl
      ags == 0); nCount++, pMap++) | 
 |  3125                 { | 
 |  3126                         if(pMap->m_nCtlID == -1) | 
 |  3127                         { | 
 |  3128                                 switch(pMap->m_dwResizeFlags) | 
 |  3129                                 { | 
 |  3130                                 case _DLSZ_BEGIN_GROUP: | 
 |  3131                                         ATLASSERT(nGroupStart == -1); | 
 |  3132                                         nGroupStart = m_arrData.GetSize(); | 
 |  3133                                         break; | 
 |  3134                                 case _DLSZ_END_GROUP: | 
 |  3135                                         { | 
 |  3136                                                 ATLASSERT(nGroupStart != -1); | 
 |  3137                                                 int nGroupCount = m_arrData.GetS
      ize() - nGroupStart; | 
 |  3138                                                 m_arrData[nGroupStart].SetGroupC
      ount(nGroupCount); | 
 |  3139                                                 nGroupStart = -1; | 
 |  3140                                         } | 
 |  3141                                         break; | 
 |  3142                                 default: | 
 |  3143                                         ATLASSERT(FALSE && _T("Invalid DLGRESIZE
       Map Entry")); | 
 |  3144                                         break; | 
 |  3145                                 } | 
 |  3146                         } | 
 |  3147                         else | 
 |  3148                         { | 
 |  3149                                 // this ID conflicts with the default gripper on
      e | 
 |  3150                                 ATLASSERT(m_bGripper ? (pMap->m_nCtlID != ATL_ID
      W_STATUS_BAR) : TRUE); | 
 |  3151  | 
 |  3152                                 ATL::CWindow ctl = pT->GetDlgItem(pMap->m_nCtlID
      ); | 
 |  3153                                 ATLASSERT(ctl.IsWindow()); | 
 |  3154                                 RECT rectCtl = { 0 }; | 
 |  3155                                 ctl.GetWindowRect(&rectCtl); | 
 |  3156                                 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&re
      ctCtl, 2); | 
 |  3157  | 
 |  3158                                 DWORD dwGroupFlag = (nGroupStart != -1 && m_arrD
      ata.GetSize() == nGroupStart) ? _DLSZ_BEGIN_GROUP : 0; | 
 |  3159                                 _AtlDlgResizeData data = { pMap->m_nCtlID, pMap-
      >m_dwResizeFlags | dwGroupFlag, { rectCtl.left, rectCtl.top, rectCtl.right, rect
      Ctl.bottom } }; | 
 |  3160                                 m_arrData.Add(data); | 
 |  3161                         } | 
 |  3162                 } | 
 |  3163                 ATLASSERT((nGroupStart == -1) && _T("No End Group Entry in the D
      LGRESIZE Map")); | 
 |  3164         } | 
 |  3165  | 
 |  3166         void DlgResize_UpdateLayout(int cxWidth, int cyHeight) | 
 |  3167         { | 
 |  3168                 T* pT = static_cast<T*>(this); | 
 |  3169                 ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  3170  | 
 |  3171                 // Restrict minimum size if requested | 
 |  3172                 if(((pT->GetStyle() & WS_CHILD) != 0) && m_ptMinTrackSize.x != -
      1 && m_ptMinTrackSize.y != -1) | 
 |  3173                 { | 
 |  3174                         if(cxWidth < m_ptMinTrackSize.x) | 
 |  3175                                 cxWidth = m_ptMinTrackSize.x; | 
 |  3176                         if(cyHeight < m_ptMinTrackSize.y) | 
 |  3177                                 cyHeight = m_ptMinTrackSize.y; | 
 |  3178                 } | 
 |  3179  | 
 |  3180                 BOOL bVisible = pT->IsWindowVisible(); | 
 |  3181                 if(bVisible) | 
 |  3182                         pT->SetRedraw(FALSE); | 
 |  3183  | 
 |  3184                 for(int i = 0; i < m_arrData.GetSize(); i++) | 
 |  3185                 { | 
 |  3186                         if((m_arrData[i].m_dwResizeFlags & _DLSZ_BEGIN_GROUP) !=
       0)   // start of a group | 
 |  3187                         { | 
 |  3188                                 int nGroupCount = m_arrData[i].GetGroupCount(); | 
 |  3189                                 ATLASSERT(nGroupCount > 0 && i + nGroupCount - 1
       < m_arrData.GetSize()); | 
 |  3190                                 RECT rectGroup = m_arrData[i].m_rect; | 
 |  3191  | 
 |  3192                                 int j = 1; | 
 |  3193                                 for(j = 1; j < nGroupCount; j++) | 
 |  3194                                 { | 
 |  3195                                         rectGroup.left = __min(rectGroup.left, m
      _arrData[i + j].m_rect.left); | 
 |  3196                                         rectGroup.top = __min(rectGroup.top, m_a
      rrData[i + j].m_rect.top); | 
 |  3197                                         rectGroup.right = __max(rectGroup.right,
       m_arrData[i + j].m_rect.right); | 
 |  3198                                         rectGroup.bottom = __max(rectGroup.botto
      m, m_arrData[i + j].m_rect.bottom); | 
 |  3199                                 } | 
 |  3200  | 
 |  3201                                 for(j = 0; j < nGroupCount; j++) | 
 |  3202                                 { | 
 |  3203                                         _AtlDlgResizeData* pDataPrev = NULL; | 
 |  3204                                         if(j > 0) | 
 |  3205                                                 pDataPrev = &(m_arrData[i + j - 
      1]); | 
 |  3206                                         pT->DlgResize_PositionControl(cxWidth, c
      yHeight, rectGroup, m_arrData[i + j], true, pDataPrev); | 
 |  3207                                 } | 
 |  3208  | 
 |  3209                                 i += nGroupCount - 1;   // increment to skip all
       group controls | 
 |  3210                         } | 
 |  3211                         else // one control entry | 
 |  3212                         { | 
 |  3213                                 RECT rectGroup = { 0, 0, 0, 0 }; | 
 |  3214                                 pT->DlgResize_PositionControl(cxWidth, cyHeight,
       rectGroup, m_arrData[i], false); | 
 |  3215                         } | 
 |  3216                 } | 
 |  3217  | 
 |  3218                 if(bVisible) | 
 |  3219                         pT->SetRedraw(TRUE); | 
 |  3220  | 
 |  3221                 pT->RedrawWindow(NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_UP
      DATENOW | RDW_ALLCHILDREN); | 
 |  3222         } | 
 |  3223  | 
 |  3224 // Message map and handlers | 
 |  3225         BEGIN_MSG_MAP(CDialogResize) | 
 |  3226                 MESSAGE_HANDLER(WM_SIZE, OnSize) | 
 |  3227 #ifndef _WIN32_WCE | 
 |  3228                 MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo) | 
 |  3229 #endif // _WIN32_WCE | 
 |  3230         END_MSG_MAP() | 
 |  3231  | 
 |  3232         LRESULT OnSize(UINT /*uMsg*/, WPARAM wParam, LPARAM lParam, BOOL& /*bHan
      dled*/) | 
 |  3233         { | 
 |  3234                 T* pT = static_cast<T*>(this); | 
 |  3235 #ifndef _WIN32_WCE | 
 |  3236                 if(m_bGripper) | 
 |  3237                 { | 
 |  3238                         ATL::CWindow wndGripper = pT->GetDlgItem(ATL_IDW_STATUS_
      BAR); | 
 |  3239                         if(wParam == SIZE_MAXIMIZED) | 
 |  3240                                 wndGripper.ShowWindow(SW_HIDE); | 
 |  3241                         else if(wParam == SIZE_RESTORED) | 
 |  3242                                 wndGripper.ShowWindow(SW_SHOW); | 
 |  3243                 } | 
 |  3244 #endif // _WIN32_WCE | 
 |  3245                 if(wParam != SIZE_MINIMIZED) | 
 |  3246                 { | 
 |  3247                         ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  3248                         pT->DlgResize_UpdateLayout(GET_X_LPARAM(lParam), GET_Y_L
      PARAM(lParam)); | 
 |  3249                 } | 
 |  3250                 return 0; | 
 |  3251         } | 
 |  3252  | 
 |  3253 #ifndef _WIN32_WCE | 
 |  3254         LRESULT OnGetMinMaxInfo(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam,
       BOOL& /*bHandled*/) | 
 |  3255         { | 
 |  3256                 if(m_ptMinTrackSize.x != -1 && m_ptMinTrackSize.y != -1) | 
 |  3257                 { | 
 |  3258                         LPMINMAXINFO lpMMI = (LPMINMAXINFO)lParam; | 
 |  3259                         lpMMI->ptMinTrackSize =  m_ptMinTrackSize; | 
 |  3260                 } | 
 |  3261                 return 0; | 
 |  3262         } | 
 |  3263 #endif // _WIN32_WCE | 
 |  3264  | 
 |  3265 // Implementation | 
 |  3266         bool DlgResize_PositionControl(int cxWidth, int cyHeight, RECT& rectGrou
      p, _AtlDlgResizeData& data, bool bGroup,  | 
 |  3267                                        _AtlDlgResizeData* pDataPrev = NULL) | 
 |  3268         { | 
 |  3269                 T* pT = static_cast<T*>(this); | 
 |  3270                 ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  3271                 ATL::CWindow ctl; | 
 |  3272                 RECT rectCtl = { 0 }; | 
 |  3273  | 
 |  3274                 ctl = pT->GetDlgItem(data.m_nCtlID); | 
 |  3275                 if(!ctl.GetWindowRect(&rectCtl)) | 
 |  3276                         return false; | 
 |  3277                 ::MapWindowPoints(NULL, pT->m_hWnd, (LPPOINT)&rectCtl, 2); | 
 |  3278  | 
 |  3279                 if(bGroup) | 
 |  3280                 { | 
 |  3281                         if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) | 
 |  3282                         { | 
 |  3283                                 int cxRight = rectGroup.right + cxWidth - m_size
      Dialog.cx; | 
 |  3284                                 int cxCtl = data.m_rect.right - data.m_rect.left
      ; | 
 |  3285                                 rectCtl.left = rectGroup.left + (cxRight - rectG
      roup.left - cxCtl) / 2; | 
 |  3286                                 rectCtl.right = rectCtl.left + cxCtl; | 
 |  3287                         } | 
 |  3288                         else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE
      _X)) != 0) | 
 |  3289                         { | 
 |  3290                                 rectCtl.left = rectGroup.left + ::MulDiv(data.m_
      rect.left - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidth - m_size
      Dialog.cx), rectGroup.right - rectGroup.left); | 
 |  3291  | 
 |  3292                                 if((data.m_dwResizeFlags & DLSZ_SIZE_X) != 0) | 
 |  3293                                 { | 
 |  3294                                         rectCtl.right = rectGroup.left + ::MulDi
      v(data.m_rect.right - rectGroup.left, rectGroup.right - rectGroup.left + (cxWidt
      h - m_sizeDialog.cx), rectGroup.right - rectGroup.left); | 
 |  3295  | 
 |  3296                                         if(pDataPrev != NULL) | 
 |  3297                                         { | 
 |  3298                                                 ATL::CWindow ctlPrev = pT->GetDl
      gItem(pDataPrev->m_nCtlID); | 
 |  3299                                                 RECT rcPrev = { 0 }; | 
 |  3300                                                 ctlPrev.GetWindowRect(&rcPrev); | 
 |  3301                                                 ::MapWindowPoints(NULL, pT->m_hW
      nd, (LPPOINT)&rcPrev, 2); | 
 |  3302                                                 int dxAdjust = (rectCtl.left - r
      cPrev.right) - (data.m_rect.left - pDataPrev->m_rect.right); | 
 |  3303                                                 rcPrev.right += dxAdjust; | 
 |  3304                                                 ctlPrev.SetWindowPos(NULL, &rcPr
      ev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); | 
 |  3305                                         } | 
 |  3306                                 } | 
 |  3307                                 else | 
 |  3308                                 { | 
 |  3309                                         rectCtl.right = rectCtl.left + (data.m_r
      ect.right - data.m_rect.left); | 
 |  3310                                 } | 
 |  3311                         } | 
 |  3312  | 
 |  3313                         if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) | 
 |  3314                         { | 
 |  3315                                 int cyBottom = rectGroup.bottom + cyHeight - m_s
      izeDialog.cy; | 
 |  3316                                 int cyCtl = data.m_rect.bottom - data.m_rect.top
      ; | 
 |  3317                                 rectCtl.top = rectGroup.top + (cyBottom - rectGr
      oup.top - cyCtl) / 2; | 
 |  3318                                 rectCtl.bottom = rectCtl.top + cyCtl; | 
 |  3319                         } | 
 |  3320                         else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE
      _Y)) != 0) | 
 |  3321                         { | 
 |  3322                                 rectCtl.top = rectGroup.top + ::MulDiv(data.m_re
      ct.top - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeight - m_sizeDia
      log.cy), rectGroup.bottom - rectGroup.top); | 
 |  3323  | 
 |  3324                                 if((data.m_dwResizeFlags & DLSZ_SIZE_Y) != 0) | 
 |  3325                                 { | 
 |  3326                                         rectCtl.bottom = rectGroup.top + ::MulDi
      v(data.m_rect.bottom - rectGroup.top, rectGroup.bottom - rectGroup.top + (cyHeig
      ht - m_sizeDialog.cy), rectGroup.bottom - rectGroup.top); | 
 |  3327  | 
 |  3328                                         if(pDataPrev != NULL) | 
 |  3329                                         { | 
 |  3330                                                 ATL::CWindow ctlPrev = pT->GetDl
      gItem(pDataPrev->m_nCtlID); | 
 |  3331                                                 RECT rcPrev = { 0 }; | 
 |  3332                                                 ctlPrev.GetWindowRect(&rcPrev); | 
 |  3333                                                 ::MapWindowPoints(NULL, pT->m_hW
      nd, (LPPOINT)&rcPrev, 2); | 
 |  3334                                                 int dxAdjust = (rectCtl.top - rc
      Prev.bottom) - (data.m_rect.top - pDataPrev->m_rect.bottom); | 
 |  3335                                                 rcPrev.bottom += dxAdjust; | 
 |  3336                                                 ctlPrev.SetWindowPos(NULL, &rcPr
      ev, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE); | 
 |  3337                                         } | 
 |  3338                                 } | 
 |  3339                                 else | 
 |  3340                                 { | 
 |  3341                                         rectCtl.bottom = rectCtl.top + (data.m_r
      ect.bottom - data.m_rect.top); | 
 |  3342                                 } | 
 |  3343                         } | 
 |  3344                 } | 
 |  3345                 else // no group | 
 |  3346                 { | 
 |  3347                         if((data.m_dwResizeFlags & DLSZ_CENTER_X) != 0) | 
 |  3348                         { | 
 |  3349                                 int cxCtl = data.m_rect.right - data.m_rect.left
      ; | 
 |  3350                                 rectCtl.left = (cxWidth - cxCtl) / 2; | 
 |  3351                                 rectCtl.right = rectCtl.left + cxCtl; | 
 |  3352                         } | 
 |  3353                         else if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_MOVE
      _X)) != 0) | 
 |  3354                         { | 
 |  3355                                 rectCtl.right = data.m_rect.right + (cxWidth - m
      _sizeDialog.cx); | 
 |  3356  | 
 |  3357                                 if((data.m_dwResizeFlags & DLSZ_MOVE_X) != 0) | 
 |  3358                                         rectCtl.left = rectCtl.right - (data.m_r
      ect.right - data.m_rect.left); | 
 |  3359                         } | 
 |  3360  | 
 |  3361                         if((data.m_dwResizeFlags & DLSZ_CENTER_Y) != 0) | 
 |  3362                         { | 
 |  3363                                 int cyCtl = data.m_rect.bottom - data.m_rect.top
      ; | 
 |  3364                                 rectCtl.top = (cyHeight - cyCtl) / 2; | 
 |  3365                                 rectCtl.bottom = rectCtl.top + cyCtl; | 
 |  3366                         } | 
 |  3367                         else if((data.m_dwResizeFlags & (DLSZ_SIZE_Y | DLSZ_MOVE
      _Y)) != 0) | 
 |  3368                         { | 
 |  3369                                 rectCtl.bottom = data.m_rect.bottom + (cyHeight 
      - m_sizeDialog.cy); | 
 |  3370  | 
 |  3371                                 if((data.m_dwResizeFlags & DLSZ_MOVE_Y) != 0) | 
 |  3372                                         rectCtl.top = rectCtl.bottom - (data.m_r
      ect.bottom - data.m_rect.top); | 
 |  3373                         } | 
 |  3374                 } | 
 |  3375  | 
 |  3376                 if((data.m_dwResizeFlags & DLSZ_REPAINT) != 0) | 
 |  3377                         ctl.Invalidate(); | 
 |  3378  | 
 |  3379                 if((data.m_dwResizeFlags & (DLSZ_SIZE_X | DLSZ_SIZE_Y | DLSZ_MOV
      E_X | DLSZ_MOVE_Y | DLSZ_REPAINT | DLSZ_CENTER_X | DLSZ_CENTER_Y)) != 0) | 
 |  3380                         ctl.SetWindowPos(NULL, &rectCtl, SWP_NOZORDER | SWP_NOAC
      TIVATE); | 
 |  3381  | 
 |  3382                 return true; | 
 |  3383         } | 
 |  3384 }; | 
 |  3385  | 
 |  3386  | 
 |  3387 /////////////////////////////////////////////////////////////////////////////// | 
 |  3388 // CDoubleBufferImpl - Provides double-buffer painting support to any window | 
 |  3389  | 
 |  3390 template <class T> | 
 |  3391 class CDoubleBufferImpl | 
 |  3392 { | 
 |  3393 public: | 
 |  3394 // Overrideables | 
 |  3395         void DoPaint(CDCHandle /*dc*/) | 
 |  3396         { | 
 |  3397                 // must be implemented in a derived class | 
 |  3398                 ATLASSERT(FALSE); | 
 |  3399         } | 
 |  3400  | 
 |  3401 // Message map and handlers | 
 |  3402         BEGIN_MSG_MAP(CDoubleBufferImpl) | 
 |  3403                 MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackground) | 
 |  3404                 MESSAGE_HANDLER(WM_PAINT, OnPaint) | 
 |  3405 #ifndef _WIN32_WCE | 
 |  3406                 MESSAGE_HANDLER(WM_PRINTCLIENT, OnPaint) | 
 |  3407 #endif // !_WIN32_WCE | 
 |  3408         END_MSG_MAP() | 
 |  3409  | 
 |  3410         LRESULT OnEraseBackground(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPa
      ram*/, BOOL& /*bHandled*/) | 
 |  3411         { | 
 |  3412                 return 1;   // no background painting needed | 
 |  3413         } | 
 |  3414  | 
 |  3415         LRESULT OnPaint(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /
      *bHandled*/) | 
 |  3416         { | 
 |  3417                 T* pT = static_cast<T*>(this); | 
 |  3418                 ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  3419  | 
 |  3420                 if(wParam != NULL) | 
 |  3421                 { | 
 |  3422                         RECT rect = { 0 }; | 
 |  3423                         pT->GetClientRect(&rect); | 
 |  3424                         CMemoryDC dcMem((HDC)wParam, rect); | 
 |  3425                         pT->DoPaint(dcMem.m_hDC); | 
 |  3426                 } | 
 |  3427                 else | 
 |  3428                 { | 
 |  3429                         CPaintDC dc(pT->m_hWnd); | 
 |  3430                         CMemoryDC dcMem(dc.m_hDC, dc.m_ps.rcPaint); | 
 |  3431                         pT->DoPaint(dcMem.m_hDC); | 
 |  3432                 } | 
 |  3433  | 
 |  3434                 return 0; | 
 |  3435         } | 
 |  3436 }; | 
 |  3437  | 
 |  3438  | 
 |  3439 /////////////////////////////////////////////////////////////////////////////// | 
 |  3440 // CDoubleBufferWindowImpl - Implements a double-buffer painting window | 
 |  3441  | 
 |  3442 template <class T, class TBase = ATL::CWindow, class TWinTraits = ATL::CControlW
      inTraits> | 
 |  3443 class ATL_NO_VTABLE CDoubleBufferWindowImpl : public ATL::CWindowImpl< T, TBase,
       TWinTraits >, public CDoubleBufferImpl< T > | 
 |  3444 { | 
 |  3445 public: | 
 |  3446         BEGIN_MSG_MAP(CDoubleBufferWindowImpl) | 
 |  3447                 CHAIN_MSG_MAP(CDoubleBufferImpl< T >) | 
 |  3448         END_MSG_MAP() | 
 |  3449 }; | 
 |  3450  | 
 |  3451  | 
 |  3452 // command bar support | 
 |  3453 #if !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) | 
 |  3454   #undef CBRM_GETMENU | 
 |  3455   #undef CBRM_TRACKPOPUPMENU | 
 |  3456   #undef CBRM_GETCMDBAR | 
 |  3457   #undef CBRPOPUPMENU | 
 |  3458 #endif // !defined(__ATLCTRLW_H__) && !defined(_WIN32_WCE) | 
 |  3459  | 
 |  3460 }; // namespace WTL | 
 |  3461  | 
 |  3462 #endif // __ATLFRAME_H__ | 
| OLD | NEW |