| 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 __ATLDLGS_H__ | 
 |    10 #define __ATLDLGS_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 atldlgs.h requires atlapp.h to be included first | 
 |    20 #endif | 
 |    21  | 
 |    22 #ifndef __ATLWIN_H__ | 
 |    23         #error atldlgs.h requires atlwin.h to be included first | 
 |    24 #endif | 
 |    25  | 
 |    26 #include <commdlg.h> | 
 |    27 #include <shlobj.h> | 
 |    28  | 
 |    29 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |    30   #include <shobjidl.h> | 
 |    31 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |    32  | 
 |    33  | 
 |    34 /////////////////////////////////////////////////////////////////////////////// | 
 |    35 // Classes in this file: | 
 |    36 // | 
 |    37 // CFileDialogImpl<T> | 
 |    38 // CFileDialog | 
 |    39 // CFileDialogEx | 
 |    40 // CMultiFileDialogImpl<T> | 
 |    41 // CMultiFileDialog | 
 |    42 // CShellFileDialogImpl<T> | 
 |    43 // CShellFileOpenDialogImpl<T> | 
 |    44 // CShellFileOpenDialog | 
 |    45 // CShellFileSaveDialogImpl<T> | 
 |    46 // CShellFileSaveDialog | 
 |    47 // CFolderDialogImpl<T> | 
 |    48 // CFolderDialog | 
 |    49 // CFontDialogImpl<T> | 
 |    50 // CFontDialog | 
 |    51 // CRichEditFontDialogImpl<T> | 
 |    52 // CRichEditFontDialog | 
 |    53 // CColorDialogImpl<T> | 
 |    54 // CColorDialog | 
 |    55 // CPrintDialogImpl<T> | 
 |    56 // CPrintDialog | 
 |    57 // CPrintDialogExImpl<T> | 
 |    58 // CPrintDialogEx | 
 |    59 // CPageSetupDialogImpl<T> | 
 |    60 // CPageSetupDialog | 
 |    61 // CFindReplaceDialogImpl<T> | 
 |    62 // CFindReplaceDialog | 
 |    63 // | 
 |    64 // CMemDlgTemplate | 
 |    65 // CIndirectDialogImpl<T, TDlgTemplate, TBase> | 
 |    66 // | 
 |    67 // CPropertySheetWindow | 
 |    68 // CPropertySheetImpl<T, TBase> | 
 |    69 // CPropertySheet | 
 |    70 // CPropertyPageWindow | 
 |    71 // CPropertyPageImpl<T, TBase> | 
 |    72 // CPropertyPage<t_wDlgTemplateID> | 
 |    73 // CAxPropertyPageImpl<T, TBase> | 
 |    74 // CAxPropertyPage<t_wDlgTemplateID> | 
 |    75 // | 
 |    76 // CWizard97SheetWindow | 
 |    77 // CWizard97SheetImpl<T, TBase> | 
 |    78 // CWizard97Sheet | 
 |    79 // CWizard97PageWindow | 
 |    80 // CWizard97PageImpl<T, TBase> | 
 |    81 // CWizard97ExteriorPageImpl<T, TBase> | 
 |    82 // CWizard97InteriorPageImpl<T, TBase> | 
 |    83 // | 
 |    84 // CAeroWizardFrameWindow | 
 |    85 // CAeroWizardFrameImpl<T, TBase> | 
 |    86 // CAeroWizardFrame | 
 |    87 // CAeroWizardPageWindow | 
 |    88 // CAeroWizardPageImpl<T, TBase> | 
 |    89 // CAeroWizardPage<t_wDlgTemplateID> | 
 |    90 // CAeroWizardAxPageImpl<T, TBase> | 
 |    91 // CAeroWizardAxPage<t_wDlgTemplateID> | 
 |    92 // | 
 |    93 // CTaskDialogConfig | 
 |    94 // CTaskDialogImpl<T> | 
 |    95 // CTaskDialog | 
 |    96 // | 
 |    97 // Global functions: | 
 |    98 //   AtlTaskDialog() | 
 |    99  | 
 |   100  | 
 |   101 namespace WTL | 
 |   102 { | 
 |   103  | 
 |   104 /////////////////////////////////////////////////////////////////////////////// | 
 |   105 // CFileDialogImpl - used for File Open or File Save As | 
 |   106  | 
 |   107 // compatibility with the old (vc6.0) headers | 
 |   108 #if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) | 
 |   109   #ifndef CDSIZEOF_STRUCT | 
 |   110     #define CDSIZEOF_STRUCT(structname, member)  (((int)((LPBYTE)(&((structname*
      )0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) | 
 |   111   #endif | 
 |   112   #define OPENFILENAME_SIZE_VERSION_400A  CDSIZEOF_STRUCT(OPENFILENAMEA,lpTempla
      teName) | 
 |   113   #define OPENFILENAME_SIZE_VERSION_400W  CDSIZEOF_STRUCT(OPENFILENAMEW,lpTempla
      teName) | 
 |   114   #ifdef UNICODE | 
 |   115     #define OPENFILENAME_SIZE_VERSION_400  OPENFILENAME_SIZE_VERSION_400W | 
 |   116   #else | 
 |   117     #define OPENFILENAME_SIZE_VERSION_400  OPENFILENAME_SIZE_VERSION_400A | 
 |   118   #endif // !UNICODE | 
 |   119 #endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400) | 
 |   120  | 
 |   121 #if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM) | 
 |   122   #define CDN_INCLUDEITEM         (CDN_FIRST - 0x0007) | 
 |   123 #endif | 
 |   124  | 
 |   125 template <class T> | 
 |   126 class ATL_NO_VTABLE CFileDialogImpl : public ATL::CDialogImplBase | 
 |   127 { | 
 |   128 public: | 
 |   129 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) | 
 |   130         OPENFILENAMEEX m_ofn; | 
 |   131 #else | 
 |   132         OPENFILENAME m_ofn; | 
 |   133 #endif | 
 |   134         BOOL m_bOpenFileDialog;            // TRUE for file open, FALSE for file
       save | 
 |   135         TCHAR m_szFileTitle[_MAX_FNAME];   // contains file title after return | 
 |   136         TCHAR m_szFileName[_MAX_PATH];     // contains full path name after retu
      rn | 
 |   137  | 
 |   138         CFileDialogImpl(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for Fi
      leSaveAs | 
 |   139                         LPCTSTR lpszDefExt = NULL, | 
 |   140                         LPCTSTR lpszFileName = NULL, | 
 |   141                         DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, | 
 |   142                         LPCTSTR lpszFilter = NULL, | 
 |   143                         HWND hWndParent = NULL) | 
 |   144         { | 
 |   145                 memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/N
      ULL | 
 |   146                 m_szFileName[0] = _T('\0'); | 
 |   147                 m_szFileTitle[0] = _T('\0'); | 
 |   148  | 
 |   149                 m_bOpenFileDialog = bOpenFileDialog; | 
 |   150  | 
 |   151                 m_ofn.lStructSize = sizeof(m_ofn); | 
 |   152 #if (_WIN32_WINNT >= 0x0500) | 
 |   153                 // adjust struct size if running on older version of Windows | 
 |   154                 if(AtlIsOldWindows()) | 
 |   155                 { | 
 |   156                         ATLASSERT(sizeof(m_ofn) > OPENFILENAME_SIZE_VERSION_400)
      ;   // must be | 
 |   157                         m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400; | 
 |   158                 } | 
 |   159 #endif // (_WIN32_WINNT >= 0x0500) | 
 |   160                 m_ofn.lpstrFile = m_szFileName; | 
 |   161                 m_ofn.nMaxFile = _MAX_PATH; | 
 |   162                 m_ofn.lpstrDefExt = lpszDefExt; | 
 |   163                 m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle; | 
 |   164                 m_ofn.nMaxFileTitle = _MAX_FNAME; | 
 |   165 #ifndef _WIN32_WCE | 
 |   166                 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENAB
      LESIZING; | 
 |   167 #else // CE specific | 
 |   168                 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK; | 
 |   169 #endif // !_WIN32_WCE | 
 |   170                 m_ofn.lpstrFilter = lpszFilter; | 
 |   171                 m_ofn.hInstance = ModuleHelper::GetResourceInstance(); | 
 |   172                 m_ofn.lpfnHook = (LPOFNHOOKPROC)T::StartDialogProc; | 
 |   173                 m_ofn.hwndOwner = hWndParent; | 
 |   174  | 
 |   175                 // setup initial file name | 
 |   176                 if(lpszFileName != NULL) | 
 |   177                 SecureHelper::strncpy_x(m_szFileName, _countof(m_szFileName), lp
      szFileName, _TRUNCATE); | 
 |   178         } | 
 |   179  | 
 |   180         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |   181         { | 
 |   182                 ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0); | 
 |   183                 ATLASSERT(m_ofn.lpfnHook != NULL);   // can still be a user hook | 
 |   184  | 
 |   185                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   186  | 
 |   187                 if(m_ofn.hwndOwner == NULL)   // set only if not specified befor
      e | 
 |   188                         m_ofn.hwndOwner = hWndParent; | 
 |   189  | 
 |   190                 ATLASSERT(m_hWnd == NULL); | 
 |   191                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBas
      e*)this); | 
 |   192  | 
 |   193                 BOOL bRet; | 
 |   194                 if(m_bOpenFileDialog) | 
 |   195 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) | 
 |   196                         bRet = ::GetOpenFileNameEx(&m_ofn); | 
 |   197                 else | 
 |   198                         bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn); | 
 |   199 #else | 
 |   200                         bRet = ::GetOpenFileName(&m_ofn); | 
 |   201                 else | 
 |   202                         bRet = ::GetSaveFileName(&m_ofn); | 
 |   203 #endif | 
 |   204  | 
 |   205                 m_hWnd = NULL; | 
 |   206  | 
 |   207                 return bRet ? IDOK : IDCANCEL; | 
 |   208         } | 
 |   209  | 
 |   210 // Attributes | 
 |   211         ATL::CWindow GetFileDialogWindow() const | 
 |   212         { | 
 |   213                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   214                 return ATL::CWindow(GetParent()); | 
 |   215         } | 
 |   216  | 
 |   217         int GetFilePath(LPTSTR lpstrFilePath, int nLength) const | 
 |   218         { | 
 |   219                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   220                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   221  | 
 |   222                 return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, n
      Length, (LPARAM)lpstrFilePath); | 
 |   223         } | 
 |   224  | 
 |   225         int GetFolderIDList(LPVOID lpBuff, int nLength) const | 
 |   226         { | 
 |   227                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   228                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   229  | 
 |   230                 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIS
      T, nLength, (LPARAM)lpBuff); | 
 |   231         } | 
 |   232  | 
 |   233         int GetFolderPath(LPTSTR lpstrFolderPath, int nLength) const | 
 |   234         { | 
 |   235                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   236                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   237  | 
 |   238                 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH,
       nLength, (LPARAM)lpstrFolderPath); | 
 |   239         } | 
 |   240  | 
 |   241         int GetSpec(LPTSTR lpstrSpec, int nLength) const | 
 |   242         { | 
 |   243                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   244                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   245  | 
 |   246                 return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC, nLeng
      th, (LPARAM)lpstrSpec); | 
 |   247         } | 
 |   248  | 
 |   249         void SetControlText(int nCtrlID, LPCTSTR lpstrText) | 
 |   250         { | 
 |   251                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   252                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   253  | 
 |   254                 GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT, nCtrlID, (
      LPARAM)lpstrText); | 
 |   255         } | 
 |   256  | 
 |   257         void SetDefExt(LPCTSTR lpstrExt) | 
 |   258         { | 
 |   259                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   260                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   261  | 
 |   262                 GetFileDialogWindow().SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpst
      rExt); | 
 |   263         } | 
 |   264  | 
 |   265         BOOL GetReadOnlyPref() const    // return TRUE if readonly checked | 
 |   266         { | 
 |   267                 return ((m_ofn.Flags & OFN_READONLY) != 0) ? TRUE : FALSE; | 
 |   268         } | 
 |   269  | 
 |   270 // Operations | 
 |   271         void HideControl(int nCtrlID) | 
 |   272         { | 
 |   273                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   274                 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0); | 
 |   275  | 
 |   276                 GetFileDialogWindow().SendMessage(CDM_HIDECONTROL, nCtrlID); | 
 |   277         } | 
 |   278  | 
 |   279 // Special override for common dialogs | 
 |   280         BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) | 
 |   281         { | 
 |   282                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   283                 GetFileDialogWindow().SendMessage(WM_COMMAND, MAKEWPARAM(IDCANCE
      L, 0)); | 
 |   284                 return TRUE; | 
 |   285         } | 
 |   286  | 
 |   287 // Message map and handlers | 
 |   288         BEGIN_MSG_MAP(CFileDialogImpl) | 
 |   289                 NOTIFY_CODE_HANDLER(CDN_FILEOK, _OnFileOK) | 
 |   290                 NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE, _OnFolderChange) | 
 |   291                 NOTIFY_CODE_HANDLER(CDN_HELP, _OnHelp) | 
 |   292                 NOTIFY_CODE_HANDLER(CDN_INITDONE, _OnInitDone) | 
 |   293                 NOTIFY_CODE_HANDLER(CDN_SELCHANGE, _OnSelChange) | 
 |   294                 NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION, _OnShareViolation) | 
 |   295                 NOTIFY_CODE_HANDLER(CDN_TYPECHANGE, _OnTypeChange) | 
 |   296 #ifndef _WIN32_WCE | 
 |   297                 NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM, _OnIncludeItem) | 
 |   298 #endif // !_WIN32_WCE | 
 |   299         END_MSG_MAP() | 
 |   300  | 
 |   301         LRESULT _OnFileOK(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   302         { | 
 |   303                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   304                 T* pT = static_cast<T*>(this); | 
 |   305                 return !pT->OnFileOK((LPOFNOTIFY)pnmh); | 
 |   306         } | 
 |   307  | 
 |   308         LRESULT _OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/
      ) | 
 |   309         { | 
 |   310                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   311                 T* pT = static_cast<T*>(this); | 
 |   312                 pT->OnFolderChange((LPOFNOTIFY)pnmh); | 
 |   313                 return 0; | 
 |   314         } | 
 |   315  | 
 |   316         LRESULT _OnHelp(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   317         { | 
 |   318                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   319                 T* pT = static_cast<T*>(this); | 
 |   320                 pT->OnHelp((LPOFNOTIFY)pnmh); | 
 |   321                 return 0; | 
 |   322         } | 
 |   323  | 
 |   324         LRESULT _OnInitDone(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   325         { | 
 |   326                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   327                 T* pT = static_cast<T*>(this); | 
 |   328                 pT->OnInitDone((LPOFNOTIFY)pnmh); | 
 |   329                 return 0; | 
 |   330         } | 
 |   331  | 
 |   332         LRESULT _OnSelChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   333         { | 
 |   334                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   335                 T* pT = static_cast<T*>(this); | 
 |   336                 pT->OnSelChange((LPOFNOTIFY)pnmh); | 
 |   337                 return 0; | 
 |   338         } | 
 |   339  | 
 |   340         LRESULT _OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled
      */) | 
 |   341         { | 
 |   342                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   343                 T* pT = static_cast<T*>(this); | 
 |   344                 return pT->OnShareViolation((LPOFNOTIFY)pnmh); | 
 |   345         } | 
 |   346  | 
 |   347         LRESULT _OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   348         { | 
 |   349                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   350                 T* pT = static_cast<T*>(this); | 
 |   351                 pT->OnTypeChange((LPOFNOTIFY)pnmh); | 
 |   352                 return 0; | 
 |   353         } | 
 |   354  | 
 |   355 #ifndef _WIN32_WCE | 
 |   356         LRESULT _OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/) | 
 |   357         { | 
 |   358                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |   359                 T* pT = static_cast<T*>(this); | 
 |   360                 return pT->OnIncludeItem((LPOFNOTIFYEX)pnmh); | 
 |   361         } | 
 |   362 #endif // !_WIN32_WCE | 
 |   363  | 
 |   364 // Overrideables | 
 |   365         BOOL OnFileOK(LPOFNOTIFY /*lpon*/) | 
 |   366         { | 
 |   367                 return TRUE; | 
 |   368         } | 
 |   369  | 
 |   370         void OnFolderChange(LPOFNOTIFY /*lpon*/) | 
 |   371         { | 
 |   372         } | 
 |   373  | 
 |   374         void OnHelp(LPOFNOTIFY /*lpon*/) | 
 |   375         { | 
 |   376         } | 
 |   377  | 
 |   378         void OnInitDone(LPOFNOTIFY /*lpon*/) | 
 |   379         { | 
 |   380         } | 
 |   381  | 
 |   382         void OnSelChange(LPOFNOTIFY /*lpon*/) | 
 |   383         { | 
 |   384         } | 
 |   385  | 
 |   386         int OnShareViolation(LPOFNOTIFY /*lpon*/) | 
 |   387         { | 
 |   388                 return 0; | 
 |   389         } | 
 |   390  | 
 |   391         void OnTypeChange(LPOFNOTIFY /*lpon*/) | 
 |   392         { | 
 |   393         } | 
 |   394  | 
 |   395 #ifndef _WIN32_WCE | 
 |   396         BOOL OnIncludeItem(LPOFNOTIFYEX /*lponex*/) | 
 |   397         { | 
 |   398                 return TRUE;   // include item | 
 |   399         } | 
 |   400 #endif // !_WIN32_WCE | 
 |   401 }; | 
 |   402  | 
 |   403 class CFileDialog : public CFileDialogImpl<CFileDialog> | 
 |   404 { | 
 |   405 public: | 
 |   406         CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSa
      veAs | 
 |   407                 LPCTSTR lpszDefExt = NULL, | 
 |   408                 LPCTSTR lpszFileName = NULL, | 
 |   409                 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, | 
 |   410                 LPCTSTR lpszFilter = NULL, | 
 |   411                 HWND hWndParent = NULL) | 
 |   412                 : CFileDialogImpl<CFileDialog>(bOpenFileDialog, lpszDefExt, lpsz
      FileName, dwFlags, lpszFilter, hWndParent) | 
 |   413         { } | 
 |   414  | 
 |   415         // override base class map and references to handlers | 
 |   416         DECLARE_EMPTY_MSG_MAP() | 
 |   417 }; | 
 |   418  | 
 |   419 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) | 
 |   420 class CFileDialogEx : public CFileDialogImpl<CFileDialogEx> | 
 |   421 { | 
 |   422 public: | 
 |   423         CFileDialogEx( // Supports only FileOpen | 
 |   424                 LPCTSTR lpszDefExt = NULL, | 
 |   425                 LPCTSTR lpszFileName = NULL, | 
 |   426                 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, | 
 |   427                 OFN_EXFLAG ExFlags = OFN_EXFLAG_THUMBNAILVIEW, | 
 |   428                 OFN_SORTORDER dwSortOrder = OFN_SORTORDER_AUTO,          | 
 |   429                 LPCTSTR lpszFilter = NULL, | 
 |   430                 HWND hWndParent = NULL) | 
 |   431                 : CFileDialogImpl<CFileDialogEx>(TRUE, lpszDefExt, lpszFileName,
       dwFlags, lpszFilter, hWndParent) | 
 |   432         { | 
 |   433                 m_ofn.ExFlags = ExFlags; | 
 |   434                 m_ofn.dwSortOrder = dwSortOrder; | 
 |   435         } | 
 |   436  | 
 |   437         // override base class map and references to handlers | 
 |   438         DECLARE_EMPTY_MSG_MAP() | 
 |   439 }; | 
 |   440 #endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501) | 
 |   441  | 
 |   442  | 
 |   443 /////////////////////////////////////////////////////////////////////////////// | 
 |   444 // Multi File Dialog - Multi-select File Open dialog | 
 |   445  | 
 |   446 #ifndef _WIN32_WCE | 
 |   447  | 
 |   448 // The class dynamically resizes the buffer as the file selection changes | 
 |   449 // (as described in Knowledge Base article 131462). It also expands selected | 
 |   450 // shortcut files to take into account the full path of the target file. | 
 |   451 // Note that this doesn't work on Win9x for the old style dialogs, as well as | 
 |   452 // on NT for non-Unicode builds.  | 
 |   453  | 
 |   454 #ifndef _WTL_FIXED_OFN_BUFFER_LENGTH | 
 |   455   #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000 | 
 |   456 #endif | 
 |   457  | 
 |   458 template <class T> | 
 |   459 class ATL_NO_VTABLE CMultiFileDialogImpl : public CFileDialogImpl< T > | 
 |   460 { | 
 |   461 public: | 
 |   462         mutable LPCTSTR m_pNextFile;  | 
 |   463 #ifndef _UNICODE | 
 |   464         bool m_bIsNT; | 
 |   465 #endif | 
 |   466  | 
 |   467         CMultiFileDialogImpl( | 
 |   468                 LPCTSTR lpszDefExt = NULL, | 
 |   469                 LPCTSTR lpszFileName = NULL, | 
 |   470                 DWORD dwFlags = OFN_HIDEREADONLY, | 
 |   471                 LPCTSTR lpszFilter = NULL, | 
 |   472                 HWND hWndParent = NULL) | 
 |   473                 : CFileDialogImpl<T>(TRUE, lpszDefExt, lpszFileName, dwFlags, lp
      szFilter, hWndParent),  | 
 |   474                   m_pNextFile(NULL) | 
 |   475         { | 
 |   476                 m_ofn.Flags |= OFN_ALLOWMULTISELECT;   // Force multiple selecti
      on mode | 
 |   477  | 
 |   478 #ifndef _UNICODE | 
 |   479                 OSVERSIONINFO ovi = { sizeof(ovi) }; | 
 |   480                 ::GetVersionEx(&ovi); | 
 |   481                 m_bIsNT = (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT); | 
 |   482                 if (m_bIsNT) | 
 |   483                 { | 
 |   484                         // On NT platforms, GetOpenFileNameA thunks to GetOpenFi
      leNameW and there  | 
 |   485                         // is absolutely nothing we can do except to start off w
      ith a large buffer. | 
 |   486                         ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LEN
      GTH)); | 
 |   487                 } | 
 |   488 #endif | 
 |   489         } | 
 |   490  | 
 |   491         ~CMultiFileDialogImpl() | 
 |   492         { | 
 |   493                 if (m_ofn.lpstrFile != m_szFileName)   // Free the buffer if we 
      allocated it | 
 |   494                         delete[] m_ofn.lpstrFile; | 
 |   495         } | 
 |   496  | 
 |   497 // Operations | 
 |   498         // Get the directory that the files were chosen from. | 
 |   499         // The function returns the number of characters copied, not including t
      he terminating zero.  | 
 |   500         // If the buffer is NULL, the function returns the required size, in cha
      racters, including the terminating zero. | 
 |   501         // If the function fails, the return value is zero. | 
 |   502         int GetDirectory(LPTSTR pBuffer, int nBufLen) const | 
 |   503         { | 
 |   504                 if (m_ofn.lpstrFile == NULL) | 
 |   505                         return 0; | 
 |   506  | 
 |   507                 LPCTSTR pStr = m_ofn.lpstrFile; | 
 |   508                 int nLength = lstrlen(pStr); | 
 |   509                 if (pStr[nLength + 1] == 0) | 
 |   510                 { | 
 |   511                         // The OFN buffer contains a single item so extract its 
      path. | 
 |   512                         LPCTSTR pSep = _strrchr(pStr, _T('\\')); | 
 |   513                         if (pSep != NULL) | 
 |   514                                 nLength = (int)(DWORD_PTR)(pSep - pStr); | 
 |   515                 } | 
 |   516  | 
 |   517                 int nRet = 0; | 
 |   518                 if (pBuffer == NULL)   // If the buffer is NULL, return the requ
      ired length | 
 |   519                 { | 
 |   520                         nRet = nLength + 1; | 
 |   521                 } | 
 |   522                 else if (nBufLen > nLength) | 
 |   523                 { | 
 |   524                         SecureHelper::strncpy_x(pBuffer, nBufLen, pStr, nLength)
      ; | 
 |   525                         nRet = nLength; | 
 |   526                 } | 
 |   527  | 
 |   528                 return nRet; | 
 |   529         } | 
 |   530  | 
 |   531 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   532         bool GetDirectory(_CSTRING_NS::CString& strDir) const | 
 |   533         { | 
 |   534                 bool bRet = false; | 
 |   535  | 
 |   536                 int nLength = GetDirectory(NULL, 0); | 
 |   537                 if (nLength > 0) | 
 |   538                 { | 
 |   539                         bRet = (GetDirectory(strDir.GetBuffer(nLength), nLength)
       > 0); | 
 |   540                         strDir.ReleaseBuffer(nLength - 1); | 
 |   541                 } | 
 |   542  | 
 |   543                 return bRet; | 
 |   544         } | 
 |   545 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   546  | 
 |   547         // Get the first filename as a pointer into the buffer. | 
 |   548         LPCTSTR GetFirstFileName() const | 
 |   549         { | 
 |   550                 if (m_ofn.lpstrFile == NULL) | 
 |   551                         return NULL; | 
 |   552  | 
 |   553                 m_pNextFile = NULL;   // Reset internal buffer pointer | 
 |   554  | 
 |   555                 LPCTSTR pStr = m_ofn.lpstrFile; | 
 |   556                 int nLength = lstrlen(pStr); | 
 |   557                 if (pStr[nLength + 1] != 0) | 
 |   558                 { | 
 |   559                         // Multiple items were selected. The first string is the
       directory, | 
 |   560                         // so skip forwards to the second string. | 
 |   561                         pStr += nLength + 1; | 
 |   562  | 
 |   563                         // Set up m_pNext so it points to the second item (or nu
      ll). | 
 |   564                         m_pNextFile = pStr; | 
 |   565                         GetNextFileName(); | 
 |   566                 } | 
 |   567                 else | 
 |   568                 { | 
 |   569                         // A single item was selected. Skip forward past the pat
      h. | 
 |   570                         LPCTSTR pSep = _strrchr(pStr, _T('\\')); | 
 |   571                         if (pSep != NULL) | 
 |   572                                 pStr = pSep + 1; | 
 |   573                 } | 
 |   574  | 
 |   575                 return pStr; | 
 |   576         } | 
 |   577  | 
 |   578         // Get the next filename as a pointer into the buffer. | 
 |   579         LPCTSTR GetNextFileName() const | 
 |   580         { | 
 |   581                 if (m_pNextFile == NULL) | 
 |   582                         return NULL; | 
 |   583  | 
 |   584                 LPCTSTR pStr = m_pNextFile; | 
 |   585                 // Set "m_pNextFile" to point to the next file name, or null if 
      we  | 
 |   586                 // have reached the last file in the list. | 
 |   587                 int nLength = lstrlen(pStr); | 
 |   588                 m_pNextFile = (pStr[nLength + 1] != 0) ? &pStr[nLength + 1] : NU
      LL; | 
 |   589  | 
 |   590                 return pStr; | 
 |   591         } | 
 |   592  | 
 |   593         // Get the first filename as a full path. | 
 |   594         // The function returns the number of characters copied, not including t
      he terminating zero.  | 
 |   595         // If the buffer is NULL, the function returns the required size, in cha
      racters, including the terminating zero. | 
 |   596         // If the function fails, the return value is zero. | 
 |   597         int GetFirstPathName(LPTSTR pBuffer, int nBufLen) const | 
 |   598         { | 
 |   599                 LPCTSTR pStr = GetFirstFileName(); | 
 |   600                 int nLengthDir = GetDirectory(NULL, 0); | 
 |   601                 if((pStr == NULL) || (nLengthDir == 0)) | 
 |   602                         return 0; | 
 |   603  | 
 |   604                 // Figure out the required length. | 
 |   605                 int nLengthTotal = nLengthDir + lstrlen(pStr); | 
 |   606  | 
 |   607                 int nRet = 0; | 
 |   608                 if(pBuffer == NULL) // If the buffer is NULL, return the require
      d length | 
 |   609                 { | 
 |   610                         nRet = nLengthTotal + 1; | 
 |   611                 } | 
 |   612                 else if (nBufLen > nLengthTotal) // If the buffer is big enough,
       go ahead and construct the path | 
 |   613                 {                | 
 |   614                         GetDirectory(pBuffer, nBufLen); | 
 |   615                         SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\")); | 
 |   616                         SecureHelper::strcat_x(pBuffer, nBufLen, pStr); | 
 |   617                         nRet = nLengthTotal; | 
 |   618                 } | 
 |   619  | 
 |   620                 return nRet; | 
 |   621         } | 
 |   622  | 
 |   623 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   624         bool GetFirstPathName(_CSTRING_NS::CString& strPath) const | 
 |   625         { | 
 |   626                 bool bRet = false; | 
 |   627  | 
 |   628                 int nLength = GetFirstPathName(NULL, 0); | 
 |   629                 if (nLength > 0) | 
 |   630                 { | 
 |   631                         bRet = (GetFirstPathName(strPath.GetBuffer(nLength), nLe
      ngth) > 0); | 
 |   632                         strPath.ReleaseBuffer(nLength - 1); | 
 |   633                 } | 
 |   634  | 
 |   635                 return bRet; | 
 |   636         } | 
 |   637 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   638  | 
 |   639         // Get the next filename as a full path. | 
 |   640         // The function returns the number of characters copied, not including t
      he terminating zero.  | 
 |   641         // If the buffer is NULL, the function returns the required size, in cha
      racters, including the terminating zero. | 
 |   642         // If the function fails, the return value is zero. | 
 |   643         // The internal position marker is moved forward only if the function su
      cceeds and the buffer was large enough. | 
 |   644         int GetNextPathName(LPTSTR pBuffer, int nBufLen) const | 
 |   645         { | 
 |   646                 if (m_pNextFile == NULL) | 
 |   647                         return 0; | 
 |   648  | 
 |   649                 int nRet = 0; | 
 |   650                 LPCTSTR pStr = m_pNextFile; | 
 |   651                 // Does the filename contain a backslash? | 
 |   652                 if (_strrchr(pStr, _T('\\')) != NULL) | 
 |   653                 { | 
 |   654                         // Yes, so we'll assume it's a full path. | 
 |   655                         int nLength = lstrlen(pStr); | 
 |   656  | 
 |   657                         if (pBuffer == NULL) // If the buffer is NULL, return th
      e required length | 
 |   658                         { | 
 |   659                                 nRet = nLength + 1; | 
 |   660                         } | 
 |   661                         else if (nBufLen > nLength) // The buffer is big enough,
       so go ahead and copy the filename | 
 |   662                         { | 
 |   663                                 SecureHelper::strcpy_x(pBuffer, nBufLen, GetNext
      FileName()); | 
 |   664                                 nRet = nBufLen; | 
 |   665                         } | 
 |   666                 } | 
 |   667                 else | 
 |   668                 { | 
 |   669                         // The filename is relative, so construct the full path. | 
 |   670                         int nLengthDir = GetDirectory(NULL, 0); | 
 |   671                         if (nLengthDir > 0) | 
 |   672                         { | 
 |   673                                 // Calculate the required space. | 
 |   674                                 int nLengthTotal = nLengthDir + lstrlen(pStr); | 
 |   675  | 
 |   676                                 if(pBuffer == NULL) // If the buffer is NULL, re
      turn the required length | 
 |   677                                 { | 
 |   678                                         nRet = nLengthTotal + 1; | 
 |   679                                 } | 
 |   680                                 else if (nBufLen > nLengthTotal) // If the buffe
      r is big enough, go ahead and construct the path | 
 |   681                                 { | 
 |   682                                         GetDirectory(pBuffer, nBufLen); | 
 |   683                                         SecureHelper::strcat_x(pBuffer, nBufLen,
       _T("\\")); | 
 |   684                                         SecureHelper::strcat_x(pBuffer, nBufLen,
       GetNextFileName()); | 
 |   685                                         nRet = nLengthTotal; | 
 |   686                                 } | 
 |   687                         } | 
 |   688                 } | 
 |   689  | 
 |   690                 return nRet; | 
 |   691         } | 
 |   692  | 
 |   693 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   694         bool GetNextPathName(_CSTRING_NS::CString& strPath) const | 
 |   695         { | 
 |   696                 bool bRet = false; | 
 |   697  | 
 |   698                 int nLength = GetNextPathName(NULL, 0); | 
 |   699                 if (nLength > 0) | 
 |   700                 { | 
 |   701                         bRet = (GetNextPathName(strPath.GetBuffer(nLength), nLen
      gth) > 0); | 
 |   702                         strPath.ReleaseBuffer(nLength - 1); | 
 |   703                 } | 
 |   704  | 
 |   705                 return bRet; | 
 |   706         } | 
 |   707 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   708  | 
 |   709 // Implementation | 
 |   710         bool ResizeFilenameBuffer(DWORD dwLength) | 
 |   711         { | 
 |   712                 if (dwLength > m_ofn.nMaxFile) | 
 |   713                 { | 
 |   714                         // Free the old buffer. | 
 |   715                         if (m_ofn.lpstrFile != m_szFileName) | 
 |   716                         { | 
 |   717                                 delete[] m_ofn.lpstrFile; | 
 |   718                                 m_ofn.lpstrFile = NULL; | 
 |   719                                 m_ofn.nMaxFile = 0; | 
 |   720                         } | 
 |   721  | 
 |   722                         // Allocate the new buffer. | 
 |   723                         LPTSTR lpstrBuff = NULL; | 
 |   724                         ATLTRY(lpstrBuff = new TCHAR[dwLength]); | 
 |   725                         if (lpstrBuff != NULL) | 
 |   726                         { | 
 |   727                                 m_ofn.lpstrFile = lpstrBuff; | 
 |   728                                 m_ofn.lpstrFile[0] = 0; | 
 |   729                                 m_ofn.nMaxFile = dwLength; | 
 |   730                         } | 
 |   731                 } | 
 |   732  | 
 |   733                 return (m_ofn.lpstrFile != NULL); | 
 |   734         } | 
 |   735  | 
 |   736         void OnSelChange(LPOFNOTIFY /*lpon*/) | 
 |   737         { | 
 |   738 #ifndef _UNICODE | 
 |   739                 // There is no point resizing the buffer in ANSI builds running 
      on NT. | 
 |   740                 if (m_bIsNT) | 
 |   741                         return; | 
 |   742 #endif | 
 |   743  | 
 |   744                 // Get the buffer length required to hold the spec. | 
 |   745                 int nLength = GetSpec(NULL, 0); | 
 |   746                 if (nLength <= 1) | 
 |   747                         return; // no files are selected, presumably | 
 |   748                  | 
 |   749                 // Add room for the directory, and an extra terminating zero. | 
 |   750                 nLength += GetFolderPath(NULL, 0) + 1; | 
 |   751  | 
 |   752                 if (!ResizeFilenameBuffer(nLength)) | 
 |   753                 { | 
 |   754                         ATLASSERT(FALSE); | 
 |   755                         return; | 
 |   756                 } | 
 |   757  | 
 |   758                 // If we are not following links then our work is done. | 
 |   759                 if ((m_ofn.Flags & OFN_NODEREFERENCELINKS) != 0) | 
 |   760                         return; | 
 |   761  | 
 |   762                 // Get the file spec, which is the text in the edit control. | 
 |   763                 if (GetSpec(m_ofn.lpstrFile, m_ofn.nMaxFile) <= 0) | 
 |   764                         return; | 
 |   765                  | 
 |   766                 // Get the ID-list of the current folder. | 
 |   767                 int nBytes = GetFolderIDList(NULL, 0); | 
 |   768                 CTempBuffer<ITEMIDLIST> idlist; | 
 |   769                 idlist.AllocateBytes(nBytes); | 
 |   770                 if ((nBytes <= 0) || (GetFolderIDList(idlist, nBytes) <= 0)) | 
 |   771                         return; | 
 |   772  | 
 |   773                 // First bind to the desktop folder, then to the current folder. | 
 |   774                 ATL::CComPtr<IShellFolder> pDesktop, pFolder; | 
 |   775                 if (FAILED(::SHGetDesktopFolder(&pDesktop))) | 
 |   776                         return; | 
 |   777                 if (FAILED(pDesktop->BindToObject(idlist, NULL, IID_IShellFolder
      , (void**)&pFolder))) | 
 |   778                         return; | 
 |   779  | 
 |   780                 // Work through the file spec, looking for quoted filenames. If 
      we find a shortcut file, then  | 
 |   781                 // we need to add enough extra buffer space to hold its target p
      ath. | 
 |   782                 DWORD nExtraChars = 0; | 
 |   783                 bool bInsideQuotes = false; | 
 |   784                 LPCTSTR pAnchor = m_ofn.lpstrFile; | 
 |   785                 LPCTSTR pChar = m_ofn.lpstrFile; | 
 |   786                 for ( ; *pChar; ++pChar) | 
 |   787                 { | 
 |   788                         // Look for quotation marks. | 
 |   789                         if (*pChar == _T('\"')) | 
 |   790                         { | 
 |   791                                 // We are either entering or leaving a passage o
      f quoted text. | 
 |   792                                 bInsideQuotes = !bInsideQuotes; | 
 |   793  | 
 |   794                                 // Is it an opening or closing quote? | 
 |   795                                 if (bInsideQuotes) | 
 |   796                                 { | 
 |   797                                         // We found an opening quote, so set "pA
      nchor" to the following character. | 
 |   798                                         pAnchor = pChar + 1; | 
 |   799                                 } | 
 |   800                                 else // closing quote | 
 |   801                                 { | 
 |   802                                         // Each quoted entity should be shorter 
      than MAX_PATH. | 
 |   803                                         if (pChar - pAnchor >= MAX_PATH) | 
 |   804                                                 return; | 
 |   805  | 
 |   806                                         // Get the ID-list and attributes of the
       file. | 
 |   807                                         USES_CONVERSION; | 
 |   808                                         int nFileNameLength = (int)(DWORD_PTR)(p
      Char - pAnchor); | 
 |   809                                         TCHAR szFileName[MAX_PATH]; | 
 |   810                                         SecureHelper::strncpy_x(szFileName, MAX_
      PATH, pAnchor, nFileNameLength); | 
 |   811                                         LPITEMIDLIST pidl = NULL; | 
 |   812                                         DWORD dwAttrib = SFGAO_LINK; | 
 |   813                                         if (SUCCEEDED(pFolder->ParseDisplayName(
      NULL, NULL, T2W(szFileName), NULL, &pidl, &dwAttrib))) | 
 |   814                                         { | 
 |   815                                                 // Is it a shortcut file? | 
 |   816                                                 if (dwAttrib & SFGAO_LINK) | 
 |   817                                                 { | 
 |   818                                                         // Bind to its IShellLin
      k interface. | 
 |   819                                                         ATL::CComPtr<IShellLink>
       pLink; | 
 |   820                                                         if (SUCCEEDED(pFolder->B
      indToObject(pidl, NULL, IID_IShellLink, (void**)&pLink))) | 
 |   821                                                         { | 
 |   822                                                                 // Get the short
      cut's target path. | 
 |   823                                                                 TCHAR szPath[MAX
      _PATH]; | 
 |   824                                                                 if (SUCCEEDED(pL
      ink->GetPath(szPath, MAX_PATH, NULL, 0))) | 
 |   825                                                                 { | 
 |   826                                                                         // If th
      e target path is longer than the shortcut name, then add on the number  | 
 |   827                                                                         // of ex
      tra characters that are required. | 
 |   828                                                                         int nNew
      Length = lstrlen(szPath); | 
 |   829                                                                         if (nNew
      Length > nFileNameLength) | 
 |   830                                                                                 
      nExtraChars += nNewLength - nFileNameLength; | 
 |   831                                                                 } | 
 |   832                                                         } | 
 |   833                                                 } | 
 |   834  | 
 |   835                                                 // Free the ID-list returned by 
      ParseDisplayName. | 
 |   836                                                 ::CoTaskMemFree(pidl); | 
 |   837                                         } | 
 |   838                                 } | 
 |   839                         } | 
 |   840                 } | 
 |   841  | 
 |   842                 // If we need more space for shortcut targets, then reallocate. | 
 |   843                 if (nExtraChars > 0) | 
 |   844                         ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraCh
      ars)); | 
 |   845         } | 
 |   846  | 
 |   847         // Helper for _ATM_MIN_CRT | 
 |   848         static const TCHAR* _strrchr(const TCHAR* p, TCHAR ch) | 
 |   849         { | 
 |   850 #ifndef _ATL_MIN_CRT | 
 |   851                 return _tcsrchr(p, ch); | 
 |   852 #else // _ATL_MIN_CRT | 
 |   853                 const TCHAR* lpsz = NULL; | 
 |   854                 while (*p != 0) | 
 |   855                 { | 
 |   856                         if (*p == ch) | 
 |   857                                 lpsz = p; | 
 |   858                         p = ::CharNext(p); | 
 |   859                 } | 
 |   860                 return lpsz; | 
 |   861 #endif // _ATL_MIN_CRT | 
 |   862         } | 
 |   863 }; | 
 |   864  | 
 |   865 class CMultiFileDialog : public CMultiFileDialogImpl<CMultiFileDialog> | 
 |   866 { | 
 |   867 public: | 
 |   868         CMultiFileDialog( | 
 |   869                 LPCTSTR lpszDefExt = NULL, | 
 |   870                 LPCTSTR lpszFileName = NULL, | 
 |   871                 DWORD dwFlags = OFN_HIDEREADONLY, | 
 |   872                 LPCTSTR lpszFilter = NULL, | 
 |   873                 HWND hWndParent = NULL) | 
 |   874                 : CMultiFileDialogImpl<CMultiFileDialog>(lpszDefExt, lpszFileNam
      e, dwFlags, lpszFilter, hWndParent) | 
 |   875         { } | 
 |   876  | 
 |   877         BEGIN_MSG_MAP(CMultiFileDialog) | 
 |   878                 CHAIN_MSG_MAP(CMultiFileDialogImpl<CMultiFileDialog>) | 
 |   879         END_MSG_MAP() | 
 |   880 }; | 
 |   881  | 
 |   882 #endif // !_WIN32_WCE | 
 |   883  | 
 |   884  | 
 |   885 /////////////////////////////////////////////////////////////////////////////// | 
 |   886 // Shell File Dialog - new Shell File Open and Save dialogs in Vista | 
 |   887  | 
 |   888 // Note: Use GetPtr() to access dialog interface methods. | 
 |   889 // Example: | 
 |   890 //      CShellFileOpenDialog dlg; | 
 |   891 //      dlg.GetPtr()->SetTitle(L"MyFileOpenDialog"); | 
 |   892  | 
 |   893 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |   894  | 
 |   895 /////////////////////////////////////////////////////////////////////////////// | 
 |   896 // CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFile
      SaveDialogImpl | 
 |   897  | 
 |   898 template <class T> | 
 |   899 class ATL_NO_VTABLE CShellFileDialogImpl : public IFileDialogEvents | 
 |   900 { | 
 |   901 public: | 
 |   902 // Operations | 
 |   903         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |   904         { | 
 |   905                 INT_PTR nRet = -1; | 
 |   906  | 
 |   907                 T* pT = static_cast<T*>(this); | 
 |   908                 if(pT->m_spFileDlg == NULL) | 
 |   909                 { | 
 |   910                         ATLASSERT(FALSE); | 
 |   911                         return nRet; | 
 |   912                 } | 
 |   913  | 
 |   914                 DWORD dwCookie = 0; | 
 |   915                 pT->_Advise(dwCookie); | 
 |   916  | 
 |   917                 HRESULT hRet = pT->m_spFileDlg->Show(hWndParent); | 
 |   918                 if(SUCCEEDED(hRet)) | 
 |   919                         nRet = IDOK; | 
 |   920                 else if(hRet == HRESULT_FROM_WIN32(ERROR_CANCELLED)) | 
 |   921                         nRet = IDCANCEL; | 
 |   922                 else | 
 |   923                         ATLASSERT(FALSE);   // error | 
 |   924  | 
 |   925                 pT->_Unadvise(dwCookie); | 
 |   926  | 
 |   927                 return nRet; | 
 |   928         } | 
 |   929  | 
 |   930         bool IsNull() const | 
 |   931         { | 
 |   932                 const T* pT = static_cast<const T*>(this); | 
 |   933                 return (pT->m_spFileDlg == NULL); | 
 |   934         } | 
 |   935  | 
 |   936 // Operations - get file path after dialog returns | 
 |   937         HRESULT GetFilePath(LPWSTR lpstrFilePath, int cchLength) | 
 |   938         { | 
 |   939                 T* pT = static_cast<T*>(this); | 
 |   940                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |   941  | 
 |   942                 ATL::CComPtr<IShellItem> spItem; | 
 |   943                 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); | 
 |   944  | 
 |   945                 if(SUCCEEDED(hRet)) | 
 |   946                         hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPAT
      H, lpstrFilePath, cchLength); | 
 |   947  | 
 |   948                 return hRet; | 
 |   949         } | 
 |   950  | 
 |   951         HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength) | 
 |   952         { | 
 |   953                 T* pT = static_cast<T*>(this); | 
 |   954                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |   955  | 
 |   956                 ATL::CComPtr<IShellItem> spItem; | 
 |   957                 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); | 
 |   958  | 
 |   959                 if(SUCCEEDED(hRet)) | 
 |   960                         hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISP
      LAY, lpstrFileTitle, cchLength); | 
 |   961  | 
 |   962                 return hRet; | 
 |   963         } | 
 |   964  | 
 |   965 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   966         HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath) | 
 |   967         { | 
 |   968                 T* pT = static_cast<T*>(this); | 
 |   969                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |   970  | 
 |   971                 ATL::CComPtr<IShellItem> spItem; | 
 |   972                 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); | 
 |   973  | 
 |   974                 if(SUCCEEDED(hRet)) | 
 |   975                         hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPAT
      H, strFilePath); | 
 |   976  | 
 |   977                 return hRet; | 
 |   978         } | 
 |   979  | 
 |   980         HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle) | 
 |   981         { | 
 |   982                 T* pT = static_cast<T*>(this); | 
 |   983                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |   984  | 
 |   985                 ATL::CComPtr<IShellItem> spItem; | 
 |   986                 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem); | 
 |   987  | 
 |   988                 if(SUCCEEDED(hRet)) | 
 |   989                         hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISP
      LAY, strFileTitle); | 
 |   990  | 
 |   991                 return hRet; | 
 |   992         } | 
 |   993 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |   994  | 
 |   995 // Helpers for IShellItem | 
 |   996         static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN ty
      pe, LPWSTR lpstr, int cchLength) | 
 |   997         { | 
 |   998                 ATLASSERT(pShellItem != NULL); | 
 |   999  | 
 |  1000                 LPWSTR lpstrName = NULL; | 
 |  1001                 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); | 
 |  1002  | 
 |  1003                 if(SUCCEEDED(hRet)) | 
 |  1004                 { | 
 |  1005                         if(lstrlenW(lpstrName) < cchLength) | 
 |  1006                         { | 
 |  1007                                 SecureHelper::strcpyW_x(lpstr, cchLength, lpstrN
      ame); | 
 |  1008                         } | 
 |  1009                         else | 
 |  1010                         { | 
 |  1011                                 ATLASSERT(FALSE); | 
 |  1012                                 hRet = DISP_E_BUFFERTOOSMALL; | 
 |  1013                         } | 
 |  1014  | 
 |  1015                         ::CoTaskMemFree(lpstrName); | 
 |  1016                 } | 
 |  1017  | 
 |  1018                 return hRet; | 
 |  1019         } | 
 |  1020  | 
 |  1021 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |  1022         static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN ty
      pe, _CSTRING_NS::CString& str) | 
 |  1023         { | 
 |  1024                 ATLASSERT(pShellItem != NULL); | 
 |  1025  | 
 |  1026                 LPWSTR lpstrName = NULL; | 
 |  1027                 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName); | 
 |  1028  | 
 |  1029                 if(SUCCEEDED(hRet)) | 
 |  1030                 { | 
 |  1031                         str = lpstrName; | 
 |  1032                         ::CoTaskMemFree(lpstrName); | 
 |  1033                 } | 
 |  1034  | 
 |  1035                 return hRet; | 
 |  1036         } | 
 |  1037 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__) | 
 |  1038  | 
 |  1039 // Implementation | 
 |  1040         void _Advise(DWORD& dwCookie) | 
 |  1041         { | 
 |  1042                 T* pT = static_cast<T*>(this); | 
 |  1043                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |  1044                 HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this,
       &dwCookie); | 
 |  1045                 ATLVERIFY(SUCCEEDED(hRet)); | 
 |  1046         } | 
 |  1047  | 
 |  1048         void _Unadvise(DWORD dwCookie) | 
 |  1049         { | 
 |  1050                 T* pT = static_cast<T*>(this); | 
 |  1051                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |  1052                 HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie); | 
 |  1053                 ATLVERIFY(SUCCEEDED(hRet)); | 
 |  1054         } | 
 |  1055  | 
 |  1056         void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, co
      nst COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount) | 
 |  1057         { | 
 |  1058                 T* pT = static_cast<T*>(this); | 
 |  1059                 ATLASSERT(pT->m_spFileDlg != NULL); | 
 |  1060  | 
 |  1061                 HRESULT hRet = E_FAIL; | 
 |  1062  | 
 |  1063                 if(lpszFileName != NULL) | 
 |  1064                 { | 
 |  1065                         hRet = pT->m_spFileDlg->SetFileName(lpszFileName); | 
 |  1066                         ATLASSERT(SUCCEEDED(hRet)); | 
 |  1067                 } | 
 |  1068  | 
 |  1069                 hRet = pT->m_spFileDlg->SetOptions(dwOptions); | 
 |  1070                 ATLASSERT(SUCCEEDED(hRet)); | 
 |  1071  | 
 |  1072                 if(lpszDefExt != NULL) | 
 |  1073                 { | 
 |  1074                         hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt); | 
 |  1075                         ATLASSERT(SUCCEEDED(hRet)); | 
 |  1076                 } | 
 |  1077  | 
 |  1078                 if(arrFilterSpec != NULL && uFilterSpecCount != 0U) | 
 |  1079                 { | 
 |  1080                         hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, a
      rrFilterSpec); | 
 |  1081                         ATLASSERT(SUCCEEDED(hRet)); | 
 |  1082                 } | 
 |  1083         } | 
 |  1084  | 
 |  1085 // Implementation - IUnknown interface | 
 |  1086         STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) | 
 |  1087         { | 
 |  1088                 if(ppvObject == NULL) | 
 |  1089                         return E_POINTER; | 
 |  1090  | 
 |  1091                 T* pT = static_cast<T*>(this); | 
 |  1092                 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFil
      eDialogEvents)) | 
 |  1093                 { | 
 |  1094                         *ppvObject = (IFileDialogEvents*)pT; | 
 |  1095                         // AddRef() not needed | 
 |  1096                         return S_OK; | 
 |  1097                 } | 
 |  1098  | 
 |  1099                 return E_NOINTERFACE; | 
 |  1100         } | 
 |  1101  | 
 |  1102         virtual ULONG STDMETHODCALLTYPE AddRef() | 
 |  1103         { | 
 |  1104                 return 1; | 
 |  1105         } | 
 |  1106  | 
 |  1107         virtual ULONG STDMETHODCALLTYPE Release() | 
 |  1108         { | 
 |  1109                 return 1; | 
 |  1110         } | 
 |  1111  | 
 |  1112 // Implementation - IFileDialogEvents interface | 
 |  1113         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialo
      g* pfd) | 
 |  1114         { | 
 |  1115                 T* pT = static_cast<T*>(this); | 
 |  1116                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1117                 pfd;   // avoid level 4 warning | 
 |  1118                 return pT->OnFileOk(); | 
 |  1119         } | 
 |  1120  | 
 |  1121         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IF
      ileDialog* pfd, IShellItem* psiFolder) | 
 |  1122         { | 
 |  1123                 T* pT = static_cast<T*>(this); | 
 |  1124                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1125                 pfd;   // avoid level 4 warning | 
 |  1126                 return pT->OnFolderChanging(psiFolder); | 
 |  1127         } | 
 |  1128  | 
 |  1129         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFil
      eDialog* pfd) | 
 |  1130         { | 
 |  1131                 T* pT = static_cast<T*>(this); | 
 |  1132                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1133                 pfd;   // avoid level 4 warning | 
 |  1134                 return pT->OnFolderChange(); | 
 |  1135         } | 
 |  1136  | 
 |  1137         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(I
      FileDialog* pfd) | 
 |  1138         { | 
 |  1139                 T* pT = static_cast<T*>(this); | 
 |  1140                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1141                 pfd;   // avoid level 4 warning | 
 |  1142                 return pT->OnSelectionChange(); | 
 |  1143         } | 
 |  1144  | 
 |  1145         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IF
      ileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse) | 
 |  1146         { | 
 |  1147                 T* pT = static_cast<T*>(this); | 
 |  1148                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1149                 pfd;   // avoid level 4 warning | 
 |  1150                 return pT->OnShareViolation(psi, pResponse); | 
 |  1151         } | 
 |  1152  | 
 |  1153         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileD
      ialog* pfd) | 
 |  1154         { | 
 |  1155                 T* pT = static_cast<T*>(this); | 
 |  1156                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1157                 pfd;   // avoid level 4 warning | 
 |  1158                 return pT->OnTypeChange(); | 
 |  1159         } | 
 |  1160  | 
 |  1161         virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDi
      alog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse) | 
 |  1162         { | 
 |  1163                 T* pT = static_cast<T*>(this); | 
 |  1164                 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd)); | 
 |  1165                 pfd;   // avoid level 4 warning | 
 |  1166                 return pT->OnOverwrite(psi, pResponse); | 
 |  1167         } | 
 |  1168  | 
 |  1169 // Overrideables - Event handlers | 
 |  1170         HRESULT OnFileOk() | 
 |  1171         { | 
 |  1172                 return E_NOTIMPL; | 
 |  1173         } | 
 |  1174  | 
 |  1175         HRESULT OnFolderChanging(IShellItem* /*psiFolder*/) | 
 |  1176         { | 
 |  1177                 return E_NOTIMPL; | 
 |  1178         } | 
 |  1179  | 
 |  1180         HRESULT OnFolderChange() | 
 |  1181         { | 
 |  1182                 return E_NOTIMPL; | 
 |  1183         } | 
 |  1184  | 
 |  1185         HRESULT OnSelectionChange() | 
 |  1186         { | 
 |  1187                 return E_NOTIMPL; | 
 |  1188         } | 
 |  1189  | 
 |  1190         HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONS
      E* /*pResponse*/) | 
 |  1191         { | 
 |  1192                 return E_NOTIMPL; | 
 |  1193         } | 
 |  1194  | 
 |  1195         HRESULT OnTypeChange() | 
 |  1196         { | 
 |  1197                 return E_NOTIMPL; | 
 |  1198         } | 
 |  1199  | 
 |  1200         HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResp
      onse*/) | 
 |  1201         { | 
 |  1202                 return E_NOTIMPL; | 
 |  1203         } | 
 |  1204 }; | 
 |  1205  | 
 |  1206  | 
 |  1207 /////////////////////////////////////////////////////////////////////////////// | 
 |  1208 // CShellFileOpenDialogImpl - implements new Shell File Open dialog | 
 |  1209  | 
 |  1210 template <class T> | 
 |  1211 class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T > | 
 |  1212 { | 
 |  1213 public: | 
 |  1214         ATL::CComPtr<IFileOpenDialog> m_spFileDlg; | 
 |  1215  | 
 |  1216         CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL,  | 
 |  1217                                  DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PAT
      HMUSTEXIST | FOS_FILEMUSTEXIST,  | 
 |  1218                                  LPCWSTR lpszDefExt = NULL,  | 
 |  1219                                  const COMDLG_FILTERSPEC* arrFilterSpec = NULL,  | 
 |  1220                                  UINT uFilterSpecCount = 0U) | 
 |  1221         { | 
 |  1222                 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog
      ); | 
 |  1223  | 
 |  1224                 if(SUCCEEDED(hRet)) | 
 |  1225                         _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec
      , uFilterSpecCount); | 
 |  1226         } | 
 |  1227  | 
 |  1228         IFileOpenDialog* GetPtr() | 
 |  1229         { | 
 |  1230                 return m_spFileDlg; | 
 |  1231         } | 
 |  1232 }; | 
 |  1233  | 
 |  1234  | 
 |  1235 /////////////////////////////////////////////////////////////////////////////// | 
 |  1236 // CShellFileOpenDialog - new Shell File Open dialog without events | 
 |  1237  | 
 |  1238 class CShellFileOpenDialog : public CShellFileOpenDialogImpl<CShellFileOpenDialo
      g> | 
 |  1239 { | 
 |  1240 public: | 
 |  1241         CShellFileOpenDialog(LPCWSTR lpszFileName = NULL,  | 
 |  1242                              DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUS
      TEXIST | FOS_FILEMUSTEXIST,  | 
 |  1243                              LPCWSTR lpszDefExt = NULL,  | 
 |  1244                              const COMDLG_FILTERSPEC* arrFilterSpec = NULL,  | 
 |  1245                              UINT uFilterSpecCount = 0U) : CShellFileOpenDialogI
      mpl<CShellFileOpenDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uF
      ilterSpecCount) | 
 |  1246         { } | 
 |  1247  | 
 |  1248 // Implementation (remove _Advise/_Unadvise code using template magic) | 
 |  1249         void _Advise(DWORD& /*dwCookie*/) | 
 |  1250         { } | 
 |  1251  | 
 |  1252         void _Unadvise(DWORD /*dwCookie*/) | 
 |  1253         { } | 
 |  1254 }; | 
 |  1255  | 
 |  1256  | 
 |  1257 /////////////////////////////////////////////////////////////////////////////// | 
 |  1258 // CShellFileSaveDialogImpl - implements new Shell File Save dialog | 
 |  1259  | 
 |  1260 template <class T> | 
 |  1261 class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T > | 
 |  1262 { | 
 |  1263 public: | 
 |  1264         ATL::CComPtr<IFileSaveDialog> m_spFileDlg; | 
 |  1265  | 
 |  1266         CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL,  | 
 |  1267                                  DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PAT
      HMUSTEXIST | FOS_OVERWRITEPROMPT,  | 
 |  1268                                  LPCWSTR lpszDefExt = NULL,  | 
 |  1269                                  const COMDLG_FILTERSPEC* arrFilterSpec = NULL,  | 
 |  1270                                  UINT uFilterSpecCount = 0U) | 
 |  1271         { | 
 |  1272                 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog
      ); | 
 |  1273  | 
 |  1274                 if(SUCCEEDED(hRet)) | 
 |  1275                         _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec
      , uFilterSpecCount); | 
 |  1276         } | 
 |  1277  | 
 |  1278         IFileSaveDialog* GetPtr() | 
 |  1279         { | 
 |  1280                 return m_spFileDlg; | 
 |  1281         } | 
 |  1282 }; | 
 |  1283  | 
 |  1284  | 
 |  1285 /////////////////////////////////////////////////////////////////////////////// | 
 |  1286 // CShellFileSaveDialog - new Shell File Save dialog without events | 
 |  1287  | 
 |  1288 class CShellFileSaveDialog : public CShellFileSaveDialogImpl<CShellFileSaveDialo
      g> | 
 |  1289 { | 
 |  1290 public: | 
 |  1291         CShellFileSaveDialog(LPCWSTR lpszFileName = NULL,  | 
 |  1292                              DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUS
      TEXIST | FOS_OVERWRITEPROMPT,  | 
 |  1293                              LPCWSTR lpszDefExt = NULL,  | 
 |  1294                              const COMDLG_FILTERSPEC* arrFilterSpec = NULL,  | 
 |  1295                              UINT uFilterSpecCount = 0U) : CShellFileSaveDialogI
      mpl<CShellFileSaveDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uF
      ilterSpecCount) | 
 |  1296         { } | 
 |  1297  | 
 |  1298 // Implementation (remove _Advise/_Unadvise code using template magic) | 
 |  1299         void _Advise(DWORD& /*dwCookie*/) | 
 |  1300         { } | 
 |  1301  | 
 |  1302         void _Unadvise(DWORD /*dwCookie*/) | 
 |  1303         { } | 
 |  1304 }; | 
 |  1305  | 
 |  1306 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |  1307  | 
 |  1308  | 
 |  1309 /////////////////////////////////////////////////////////////////////////////// | 
 |  1310 // CFolderDialogImpl - used for browsing for a folder | 
 |  1311  | 
 |  1312 #ifndef _WIN32_WCE | 
 |  1313  | 
 |  1314 template <class T> | 
 |  1315 class ATL_NO_VTABLE CFolderDialogImpl | 
 |  1316 { | 
 |  1317 public: | 
 |  1318         BROWSEINFO m_bi; | 
 |  1319         LPCTSTR m_lpstrInitialFolder; | 
 |  1320         LPCITEMIDLIST m_pidlInitialSelection; | 
 |  1321         bool m_bExpandInitialSelection; | 
 |  1322         TCHAR m_szFolderDisplayName[MAX_PATH]; | 
 |  1323         TCHAR m_szFolderPath[MAX_PATH]; | 
 |  1324         LPITEMIDLIST m_pidlSelected; | 
 |  1325         HWND m_hWnd;   // used only in the callback function | 
 |  1326  | 
 |  1327 // Constructor | 
 |  1328         CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UIN
      T uFlags = BIF_RETURNONLYFSDIRS) :  | 
 |  1329                         m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL)
      , m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL) | 
 |  1330         { | 
 |  1331                 memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NUL
      L | 
 |  1332  | 
 |  1333                 m_bi.hwndOwner = hWndParent; | 
 |  1334                 m_bi.pidlRoot = NULL; | 
 |  1335                 m_bi.pszDisplayName = m_szFolderDisplayName; | 
 |  1336                 m_bi.lpszTitle = lpstrTitle; | 
 |  1337                 m_bi.ulFlags = uFlags; | 
 |  1338                 m_bi.lpfn = BrowseCallbackProc; | 
 |  1339                 m_bi.lParam = (LPARAM)static_cast<T*>(this); | 
 |  1340  | 
 |  1341                 m_szFolderPath[0] = 0; | 
 |  1342                 m_szFolderDisplayName[0] = 0; | 
 |  1343         } | 
 |  1344  | 
 |  1345         ~CFolderDialogImpl() | 
 |  1346         { | 
 |  1347                 ::CoTaskMemFree(m_pidlSelected); | 
 |  1348         } | 
 |  1349  | 
 |  1350 // Operations | 
 |  1351         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  1352         { | 
 |  1353                 if(m_bi.hwndOwner == NULL)   // set only if not specified before | 
 |  1354                         m_bi.hwndOwner = hWndParent; | 
 |  1355  | 
 |  1356                 // Clear out any previous results | 
 |  1357                 m_szFolderPath[0] = 0; | 
 |  1358                 m_szFolderDisplayName[0] = 0; | 
 |  1359                 ::CoTaskMemFree(m_pidlSelected); | 
 |  1360  | 
 |  1361                 INT_PTR nRet = IDCANCEL; | 
 |  1362                 m_pidlSelected = ::SHBrowseForFolder(&m_bi); | 
 |  1363  | 
 |  1364                 if(m_pidlSelected != NULL) | 
 |  1365                 { | 
 |  1366                         nRet = IDOK; | 
 |  1367  | 
 |  1368                         // If BIF_RETURNONLYFSDIRS is set, we try to get the fil
      esystem path. | 
 |  1369                         // Otherwise, the caller must handle the ID-list directl
      y. | 
 |  1370                         if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0) | 
 |  1371                         { | 
 |  1372                                 if(::SHGetPathFromIDList(m_pidlSelected, m_szFol
      derPath) == FALSE) | 
 |  1373                                         nRet = IDCANCEL; | 
 |  1374                         } | 
 |  1375                 } | 
 |  1376  | 
 |  1377                 return nRet; | 
 |  1378         } | 
 |  1379  | 
 |  1380         // Methods to call before DoModal | 
 |  1381         void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true) | 
 |  1382         { | 
 |  1383                 // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is
       specified | 
 |  1384                 m_lpstrInitialFolder = lpstrInitialFolder; | 
 |  1385                 m_bExpandInitialSelection = bExpand; | 
 |  1386         } | 
 |  1387  | 
 |  1388         void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true) | 
 |  1389         { | 
 |  1390                 m_pidlInitialSelection = pidl; | 
 |  1391                 m_bExpandInitialSelection = bExpand; | 
 |  1392         } | 
 |  1393  | 
 |  1394         // Methods to call after DoModal | 
 |  1395         LPITEMIDLIST GetSelectedItem(bool bDetach = false) | 
 |  1396         { | 
 |  1397                 LPITEMIDLIST pidl = m_pidlSelected; | 
 |  1398                 if(bDetach) | 
 |  1399                         m_pidlSelected = NULL; | 
 |  1400  | 
 |  1401                 return pidl; | 
 |  1402         } | 
 |  1403  | 
 |  1404         LPCTSTR GetFolderPath() const | 
 |  1405         { | 
 |  1406                 return m_szFolderPath; | 
 |  1407         } | 
 |  1408  | 
 |  1409         LPCTSTR GetFolderDisplayName() const | 
 |  1410         { | 
 |  1411                 return m_szFolderDisplayName; | 
 |  1412         } | 
 |  1413  | 
 |  1414         int GetFolderImageIndex() const | 
 |  1415         { | 
 |  1416                 return m_bi.iImage; | 
 |  1417         } | 
 |  1418  | 
 |  1419 // Callback function and overrideables | 
 |  1420         static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lPar
      am, LPARAM lpData) | 
 |  1421         { | 
 |  1422 #ifndef BFFM_VALIDATEFAILED | 
 |  1423   #ifdef UNICODE | 
 |  1424                 const int BFFM_VALIDATEFAILED = 4; | 
 |  1425   #else | 
 |  1426                 const int BFFM_VALIDATEFAILED = 3; | 
 |  1427   #endif | 
 |  1428 #endif // !BFFM_VALIDATEFAILED | 
 |  1429 #ifndef BFFM_IUNKNOWN | 
 |  1430                 const int BFFM_IUNKNOWN = 5; | 
 |  1431 #endif // !BFFM_IUNKNOWN | 
 |  1432 #ifndef BIF_NEWDIALOGSTYLE | 
 |  1433                 const UINT BIF_NEWDIALOGSTYLE = 0x0040; | 
 |  1434 #endif // !BIF_NEWDIALOGSTYLE | 
 |  1435  | 
 |  1436                 int nRet = 0; | 
 |  1437                 T* pT = (T*)lpData; | 
 |  1438                 bool bClear = false; | 
 |  1439                 if(pT->m_hWnd == NULL) | 
 |  1440                 { | 
 |  1441                         pT->m_hWnd = hWnd; | 
 |  1442                         bClear = true; | 
 |  1443                 } | 
 |  1444                 else | 
 |  1445                 { | 
 |  1446                         ATLASSERT(pT->m_hWnd == hWnd); | 
 |  1447                 } | 
 |  1448  | 
 |  1449                 switch(uMsg) | 
 |  1450                 { | 
 |  1451                 case BFFM_INITIALIZED: | 
 |  1452                         // Set initial selection | 
 |  1453                         // Note that m_pidlInitialSelection, if set, takes prece
      dence over m_lpstrInitialFolder | 
 |  1454                         if(pT->m_pidlInitialSelection != NULL) | 
 |  1455                                 pT->SetSelection(pT->m_pidlInitialSelection); | 
 |  1456                         else if(pT->m_lpstrInitialFolder != NULL) | 
 |  1457                                 pT->SetSelection(pT->m_lpstrInitialFolder); | 
 |  1458  | 
 |  1459                         // Expand initial selection if appropriate | 
 |  1460                         if(pT->m_bExpandInitialSelection && ((pT->m_bi.ulFlags &
       BIF_NEWDIALOGSTYLE) != 0)) | 
 |  1461                         { | 
 |  1462                                 if(pT->m_pidlInitialSelection != NULL) | 
 |  1463                                         pT->SetExpanded(pT->m_pidlInitialSelecti
      on); | 
 |  1464                                 else if(pT->m_lpstrInitialFolder != NULL) | 
 |  1465                                         pT->SetExpanded(pT->m_lpstrInitialFolder
      ); | 
 |  1466                         } | 
 |  1467                         pT->OnInitialized(); | 
 |  1468                         break; | 
 |  1469                 case BFFM_SELCHANGED: | 
 |  1470                         pT->OnSelChanged((LPITEMIDLIST)lParam); | 
 |  1471                         break; | 
 |  1472                 case BFFM_VALIDATEFAILED: | 
 |  1473                         nRet = pT->OnValidateFailed((LPCTSTR)lParam); | 
 |  1474                         break; | 
 |  1475                 case BFFM_IUNKNOWN: | 
 |  1476                         pT->OnIUnknown((IUnknown*)lParam); | 
 |  1477                         break; | 
 |  1478                 default: | 
 |  1479                         ATLTRACE2(atlTraceUI, 0, _T("Unknown message received in
       CFolderDialogImpl::BrowseCallbackProc\n")); | 
 |  1480                         break; | 
 |  1481                 } | 
 |  1482  | 
 |  1483                 if(bClear) | 
 |  1484                         pT->m_hWnd = NULL; | 
 |  1485                 return nRet; | 
 |  1486         } | 
 |  1487  | 
 |  1488         void OnInitialized() | 
 |  1489         { | 
 |  1490         } | 
 |  1491  | 
 |  1492         void OnSelChanged(LPITEMIDLIST /*pItemIDList*/) | 
 |  1493         { | 
 |  1494         } | 
 |  1495  | 
 |  1496         int OnValidateFailed(LPCTSTR /*lpstrFolderPath*/) | 
 |  1497         { | 
 |  1498                 return 1;   // 1=continue, 0=EndDialog | 
 |  1499         } | 
 |  1500  | 
 |  1501         void OnIUnknown(IUnknown* /*pUnknown*/) | 
 |  1502         { | 
 |  1503         } | 
 |  1504  | 
 |  1505         // Commands - valid to call only from handlers | 
 |  1506         void EnableOK(BOOL bEnable) | 
 |  1507         { | 
 |  1508                 ATLASSERT(m_hWnd != NULL); | 
 |  1509                 ::SendMessage(m_hWnd, BFFM_ENABLEOK, 0, bEnable); | 
 |  1510         } | 
 |  1511  | 
 |  1512         void SetSelection(LPCITEMIDLIST pItemIDList) | 
 |  1513         { | 
 |  1514                 ATLASSERT(m_hWnd != NULL); | 
 |  1515                 ::SendMessage(m_hWnd, BFFM_SETSELECTION, FALSE, (LPARAM)pItemIDL
      ist); | 
 |  1516         } | 
 |  1517  | 
 |  1518         void SetSelection(LPCTSTR lpstrFolderPath) | 
 |  1519         { | 
 |  1520                 ATLASSERT(m_hWnd != NULL); | 
 |  1521                 ::SendMessage(m_hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrFold
      erPath); | 
 |  1522         } | 
 |  1523  | 
 |  1524         void SetStatusText(LPCTSTR lpstrText) | 
 |  1525         { | 
 |  1526                 ATLASSERT(m_hWnd != NULL); | 
 |  1527                 ::SendMessage(m_hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)lpstrText); | 
 |  1528         } | 
 |  1529  | 
 |  1530         void SetOKText(LPCTSTR lpstrOKText) | 
 |  1531         { | 
 |  1532 #ifndef BFFM_SETOKTEXT | 
 |  1533                 const UINT BFFM_SETOKTEXT = WM_USER + 105; | 
 |  1534 #endif | 
 |  1535                 ATLASSERT(m_hWnd != NULL); | 
 |  1536                 USES_CONVERSION; | 
 |  1537                 LPCWSTR lpstr = T2CW(lpstrOKText); | 
 |  1538                 ::SendMessage(m_hWnd, BFFM_SETOKTEXT, (WPARAM)lpstr, 0L); | 
 |  1539         } | 
 |  1540  | 
 |  1541         void SetExpanded(LPCITEMIDLIST pItemIDList) | 
 |  1542         { | 
 |  1543 #ifndef BFFM_SETEXPANDED | 
 |  1544                 const UINT BFFM_SETEXPANDED = WM_USER + 106; | 
 |  1545 #endif | 
 |  1546                 ATLASSERT(m_hWnd != NULL); | 
 |  1547                 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, FALSE, (LPARAM)pItemIDLi
      st); | 
 |  1548         } | 
 |  1549  | 
 |  1550         void SetExpanded(LPCTSTR lpstrFolderPath) | 
 |  1551         { | 
 |  1552 #ifndef BFFM_SETEXPANDED | 
 |  1553                 const UINT BFFM_SETEXPANDED = WM_USER + 106; | 
 |  1554 #endif | 
 |  1555                 ATLASSERT(m_hWnd != NULL); | 
 |  1556                 USES_CONVERSION; | 
 |  1557                 LPCWSTR lpstr = T2CW(lpstrFolderPath); | 
 |  1558                 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)lpstr); | 
 |  1559         } | 
 |  1560 }; | 
 |  1561  | 
 |  1562 class CFolderDialog : public CFolderDialogImpl<CFolderDialog> | 
 |  1563 { | 
 |  1564 public: | 
 |  1565         CFolderDialog(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uF
      lags = BIF_RETURNONLYFSDIRS) | 
 |  1566                 : CFolderDialogImpl<CFolderDialog>(hWndParent, lpstrTitle, uFlag
      s) | 
 |  1567         { } | 
 |  1568 }; | 
 |  1569  | 
 |  1570 #endif // !_WIN32_WCE | 
 |  1571  | 
 |  1572  | 
 |  1573 /////////////////////////////////////////////////////////////////////////////// | 
 |  1574 // CCommonDialogImplBase - base class for common dialog classes | 
 |  1575  | 
 |  1576 class ATL_NO_VTABLE CCommonDialogImplBase : public ATL::CWindowImplBase | 
 |  1577 { | 
 |  1578 public: | 
 |  1579         static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
      PARAM lParam) | 
 |  1580         { | 
 |  1581                 if(uMsg != WM_INITDIALOG) | 
 |  1582                         return 0; | 
 |  1583                 CCommonDialogImplBase* pT = (CCommonDialogImplBase*)ModuleHelper
      ::ExtractCreateWndData(); | 
 |  1584                 ATLASSERT(pT != NULL); | 
 |  1585                 ATLASSERT(pT->m_hWnd == NULL); | 
 |  1586                 ATLASSERT(::IsWindow(hWnd)); | 
 |  1587                 // subclass dialog's window | 
 |  1588                 if(!pT->SubclassWindow(hWnd)) | 
 |  1589                 { | 
 |  1590                         ATLTRACE2(atlTraceUI, 0, _T("Subclassing a common dialog
       failed\n")); | 
 |  1591                         return 0; | 
 |  1592                 } | 
 |  1593                 // check message map for WM_INITDIALOG handler | 
 |  1594                 LRESULT lRes = 0; | 
 |  1595                 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lR
      es, 0) == FALSE) | 
 |  1596                         return 0; | 
 |  1597                 return lRes; | 
 |  1598         } | 
 |  1599  | 
 |  1600 // Special override for common dialogs | 
 |  1601         BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) | 
 |  1602         { | 
 |  1603                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  1604                 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); | 
 |  1605                 return TRUE; | 
 |  1606         } | 
 |  1607  | 
 |  1608 // Implementation - try to override these, to prevent errors | 
 |  1609         HWND Create(HWND, ATL::_U_RECT, LPCTSTR, DWORD, DWORD, ATL::_U_MENUorID,
       ATOM, LPVOID) | 
 |  1610         { | 
 |  1611                 ATLASSERT(FALSE);   // should not be called | 
 |  1612                 return NULL; | 
 |  1613         } | 
 |  1614  | 
 |  1615         static LRESULT CALLBACK StartWindowProc(HWND /*hWnd*/, UINT /*uMsg*/, WP
      ARAM /*wParam*/, LPARAM /*lParam*/) | 
 |  1616         { | 
 |  1617                 ATLASSERT(FALSE);   // should not be called | 
 |  1618                 return 0; | 
 |  1619         } | 
 |  1620 }; | 
 |  1621  | 
 |  1622  | 
 |  1623 /////////////////////////////////////////////////////////////////////////////// | 
 |  1624 // CFontDialogImpl - font selection dialog | 
 |  1625  | 
 |  1626 #ifndef _WIN32_WCE | 
 |  1627  | 
 |  1628 template <class T> | 
 |  1629 class ATL_NO_VTABLE CFontDialogImpl : public CCommonDialogImplBase | 
 |  1630 { | 
 |  1631 public: | 
 |  1632         enum { _cchStyleName = 64 }; | 
 |  1633  | 
 |  1634         CHOOSEFONT m_cf; | 
 |  1635         TCHAR m_szStyleName[_cchStyleName];  // contains style name after return | 
 |  1636         LOGFONT m_lf;                        // default LOGFONT to store the inf
      o | 
 |  1637  | 
 |  1638 // Constructors | 
 |  1639         CFontDialogImpl(LPLOGFONT lplfInitial = NULL, | 
 |  1640                         DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, | 
 |  1641                         HDC hDCPrinter = NULL, | 
 |  1642                         HWND hWndParent = NULL) | 
 |  1643         { | 
 |  1644                 memset(&m_cf, 0, sizeof(m_cf)); | 
 |  1645                 memset(&m_lf, 0, sizeof(m_lf)); | 
 |  1646                 memset(&m_szStyleName, 0, sizeof(m_szStyleName)); | 
 |  1647  | 
 |  1648                 m_cf.lStructSize = sizeof(m_cf); | 
 |  1649                 m_cf.hwndOwner = hWndParent; | 
 |  1650                 m_cf.rgbColors = RGB(0, 0, 0); | 
 |  1651                 m_cf.lpszStyle = (LPTSTR)&m_szStyleName; | 
 |  1652                 m_cf.Flags = dwFlags | CF_ENABLEHOOK; | 
 |  1653                 m_cf.lpfnHook = (LPCFHOOKPROC)T::HookProc; | 
 |  1654  | 
 |  1655                 if(lplfInitial != NULL) | 
 |  1656                 { | 
 |  1657                         m_cf.lpLogFont = lplfInitial; | 
 |  1658                         m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; | 
 |  1659                         m_lf = *lplfInitial; | 
 |  1660                 } | 
 |  1661                 else | 
 |  1662                 { | 
 |  1663                         m_cf.lpLogFont = &m_lf; | 
 |  1664                 } | 
 |  1665  | 
 |  1666                 if(hDCPrinter != NULL) | 
 |  1667                 { | 
 |  1668                         m_cf.hDC = hDCPrinter; | 
 |  1669                         m_cf.Flags |= CF_PRINTERFONTS; | 
 |  1670                 } | 
 |  1671         } | 
 |  1672  | 
 |  1673 // Operations | 
 |  1674         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  1675         { | 
 |  1676                 ATLASSERT((m_cf.Flags & CF_ENABLEHOOK) != 0); | 
 |  1677                 ATLASSERT(m_cf.lpfnHook != NULL);   // can still be a user hook | 
 |  1678  | 
 |  1679                 if(m_cf.hwndOwner == NULL)          // set only if not specified
       before | 
 |  1680                         m_cf.hwndOwner = hWndParent; | 
 |  1681  | 
 |  1682                 ATLASSERT(m_hWnd == NULL); | 
 |  1683                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBa
      se*)this); | 
 |  1684  | 
 |  1685                 BOOL bRet = ::ChooseFont(&m_cf); | 
 |  1686  | 
 |  1687                 m_hWnd = NULL; | 
 |  1688  | 
 |  1689                 if(bRet)   // copy logical font from user's initialization buffe
      r (if needed) | 
 |  1690                         SecureHelper::memcpy_x(&m_lf, sizeof(m_lf), m_cf.lpLogFo
      nt, sizeof(m_lf)); | 
 |  1691  | 
 |  1692                 return bRet ? IDOK : IDCANCEL; | 
 |  1693         } | 
 |  1694  | 
 |  1695         // works only when the dialog is dislayed or after | 
 |  1696         void GetCurrentFont(LPLOGFONT lplf) const | 
 |  1697         { | 
 |  1698                 ATLASSERT(lplf != NULL); | 
 |  1699  | 
 |  1700                 if(m_hWnd != NULL) | 
 |  1701                         ::SendMessage(m_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (LPAR
      AM)lplf); | 
 |  1702                 else | 
 |  1703                         *lplf = m_lf; | 
 |  1704         } | 
 |  1705  | 
 |  1706         // works only when the dialog is dislayed or before | 
 |  1707 #ifndef _WIN32_WCE | 
 |  1708         void SetLogFont(LPLOGFONT lplf) | 
 |  1709         { | 
 |  1710                 ATLASSERT(lplf != NULL); | 
 |  1711 #ifndef WM_CHOOSEFONT_SETLOGFONT | 
 |  1712                 const UINT WM_CHOOSEFONT_SETLOGFONT = (WM_USER + 101); | 
 |  1713 #endif | 
 |  1714                 if(m_hWnd != NULL) | 
 |  1715                 { | 
 |  1716                         ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETLOGFONT, 0, (LPAR
      AM)lplf); | 
 |  1717                 } | 
 |  1718                 else | 
 |  1719                 { | 
 |  1720                         m_lf = *lplf; | 
 |  1721                         m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; | 
 |  1722                 } | 
 |  1723         } | 
 |  1724  | 
 |  1725         void SetFlags(DWORD dwFlags) | 
 |  1726         { | 
 |  1727 #ifndef WM_CHOOSEFONT_SETFLAGS | 
 |  1728                 const UINT WM_CHOOSEFONT_SETFLAGS = (WM_USER + 102); | 
 |  1729 #endif | 
 |  1730                 if(m_hWnd != NULL) | 
 |  1731                 { | 
 |  1732                         CHOOSEFONT cf = { sizeof(CHOOSEFONT) }; | 
 |  1733                         cf.Flags = dwFlags; | 
 |  1734                         ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETFLAGS, 0, (LPARAM
      )&cf); | 
 |  1735                 } | 
 |  1736                 else | 
 |  1737                 { | 
 |  1738                         m_cf.Flags = dwFlags; | 
 |  1739                 } | 
 |  1740         } | 
 |  1741 #endif // !_WIN32_WCE | 
 |  1742  | 
 |  1743         // Helpers for parsing information after successful return | 
 |  1744         LPCTSTR GetFaceName() const   // return the face name of the font | 
 |  1745         { | 
 |  1746                 return (LPCTSTR)m_cf.lpLogFont->lfFaceName; | 
 |  1747         } | 
 |  1748  | 
 |  1749         LPCTSTR GetStyleName() const  // return the style name of the font | 
 |  1750         { | 
 |  1751                 return m_cf.lpszStyle; | 
 |  1752         } | 
 |  1753  | 
 |  1754         int GetSize() const           // return the pt size of the font | 
 |  1755         { | 
 |  1756                 return m_cf.iPointSize; | 
 |  1757         } | 
 |  1758  | 
 |  1759         COLORREF GetColor() const     // return the color of the font | 
 |  1760         { | 
 |  1761                 return m_cf.rgbColors; | 
 |  1762         } | 
 |  1763  | 
 |  1764         int GetWeight() const         // return the chosen font weight | 
 |  1765         { | 
 |  1766                 return (int)m_cf.lpLogFont->lfWeight; | 
 |  1767         } | 
 |  1768  | 
 |  1769         BOOL IsStrikeOut() const      // return TRUE if strikeout | 
 |  1770         { | 
 |  1771                 return (m_cf.lpLogFont->lfStrikeOut) ? TRUE : FALSE; | 
 |  1772         } | 
 |  1773  | 
 |  1774         BOOL IsUnderline() const      // return TRUE if underline | 
 |  1775         { | 
 |  1776                 return (m_cf.lpLogFont->lfUnderline) ? TRUE : FALSE; | 
 |  1777         } | 
 |  1778  | 
 |  1779         BOOL IsBold() const           // return TRUE if bold font | 
 |  1780         { | 
 |  1781                 return (m_cf.lpLogFont->lfWeight == FW_BOLD) ? TRUE : FALSE; | 
 |  1782         } | 
 |  1783  | 
 |  1784         BOOL IsItalic() const         // return TRUE if italic font | 
 |  1785         { | 
 |  1786                 return m_cf.lpLogFont->lfItalic ? TRUE : FALSE; | 
 |  1787         } | 
 |  1788 }; | 
 |  1789  | 
 |  1790 class CFontDialog : public CFontDialogImpl<CFontDialog> | 
 |  1791 { | 
 |  1792 public: | 
 |  1793         CFontDialog(LPLOGFONT lplfInitial = NULL, | 
 |  1794                 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS, | 
 |  1795                 HDC hDCPrinter = NULL, | 
 |  1796                 HWND hWndParent = NULL) | 
 |  1797                 : CFontDialogImpl<CFontDialog>(lplfInitial, dwFlags, hDCPrinter,
       hWndParent) | 
 |  1798         { } | 
 |  1799  | 
 |  1800         DECLARE_EMPTY_MSG_MAP() | 
 |  1801 }; | 
 |  1802  | 
 |  1803 #endif // _WIN32_WCE | 
 |  1804  | 
 |  1805  | 
 |  1806 /////////////////////////////////////////////////////////////////////////////// | 
 |  1807 // CRichEditFontDialogImpl - font selection for the Rich Edit ctrl | 
 |  1808  | 
 |  1809 #if defined(_RICHEDIT_) && !defined(_WIN32_WCE) | 
 |  1810  | 
 |  1811 template <class T> | 
 |  1812 class ATL_NO_VTABLE CRichEditFontDialogImpl : public CFontDialogImpl< T > | 
 |  1813 { | 
 |  1814 public: | 
 |  1815         CRichEditFontDialogImpl(const CHARFORMAT& charformat, | 
 |  1816                         DWORD dwFlags = CF_SCREENFONTS, | 
 |  1817                         HDC hDCPrinter = NULL, | 
 |  1818                         HWND hWndParent = NULL) | 
 |  1819                         : CFontDialogImpl< T >(NULL, dwFlags, hDCPrinter, hWndPa
      rent) | 
 |  1820         { | 
 |  1821                 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT; | 
 |  1822                 m_cf.Flags |= FillInLogFont(charformat); | 
 |  1823                 m_cf.lpLogFont = &m_lf; | 
 |  1824  | 
 |  1825                 if((charformat.dwMask & CFM_COLOR) != 0) | 
 |  1826                         m_cf.rgbColors = charformat.crTextColor; | 
 |  1827         } | 
 |  1828  | 
 |  1829         void GetCharFormat(CHARFORMAT& cf) const | 
 |  1830         { | 
 |  1831                 USES_CONVERSION; | 
 |  1832                 cf.dwEffects = 0; | 
 |  1833                 cf.dwMask = 0; | 
 |  1834                 if((m_cf.Flags & CF_NOSTYLESEL) == 0) | 
 |  1835                 { | 
 |  1836                         cf.dwMask |= CFM_BOLD | CFM_ITALIC; | 
 |  1837                         cf.dwEffects |= IsBold() ? CFE_BOLD : 0; | 
 |  1838                         cf.dwEffects |= IsItalic() ? CFE_ITALIC : 0; | 
 |  1839                 } | 
 |  1840                 if((m_cf.Flags & CF_NOSIZESEL) == 0) | 
 |  1841                 { | 
 |  1842                         cf.dwMask |= CFM_SIZE; | 
 |  1843                         // GetSize() returns in tenths of points so mulitply by 
      2 to get twips | 
 |  1844                         cf.yHeight = GetSize() * 2; | 
 |  1845                 } | 
 |  1846  | 
 |  1847                 if((m_cf.Flags & CF_NOFACESEL) == 0) | 
 |  1848                 { | 
 |  1849                         cf.dwMask |= CFM_FACE; | 
 |  1850                         cf.bPitchAndFamily = m_cf.lpLogFont->lfPitchAndFamily; | 
 |  1851 #if (_RICHEDIT_VER >= 0x0200) | 
 |  1852                         SecureHelper::strcpy_x(cf.szFaceName, _countof(cf.szFace
      Name), GetFaceName()); | 
 |  1853 #else // !(_RICHEDIT_VER >= 0x0200) | 
 |  1854                         SecureHelper::strcpyA_x(cf.szFaceName, _countof(cf.szFac
      eName), T2A((LPTSTR)(LPCTSTR)GetFaceName())); | 
 |  1855 #endif // !(_RICHEDIT_VER >= 0x0200) | 
 |  1856                 } | 
 |  1857  | 
 |  1858                 if((m_cf.Flags & CF_EFFECTS) != 0) | 
 |  1859                 { | 
 |  1860                         cf.dwMask |= CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR; | 
 |  1861                         cf.dwEffects |= IsUnderline() ? CFE_UNDERLINE : 0; | 
 |  1862                         cf.dwEffects |= IsStrikeOut() ? CFE_STRIKEOUT : 0; | 
 |  1863                         cf.crTextColor = GetColor(); | 
 |  1864                 } | 
 |  1865                 if((m_cf.Flags & CF_NOSCRIPTSEL) == 0) | 
 |  1866                 { | 
 |  1867                         cf.bCharSet = m_cf.lpLogFont->lfCharSet; | 
 |  1868                         cf.dwMask |= CFM_CHARSET; | 
 |  1869                 } | 
 |  1870                 cf.yOffset = 0; | 
 |  1871         } | 
 |  1872  | 
 |  1873         DWORD FillInLogFont(const CHARFORMAT& cf) | 
 |  1874         { | 
 |  1875                 USES_CONVERSION; | 
 |  1876                 DWORD dwFlags = 0; | 
 |  1877                 if((cf.dwMask & CFM_SIZE) != 0) | 
 |  1878                 { | 
 |  1879                         HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL); | 
 |  1880                         LONG yPerInch = ::GetDeviceCaps(hDC, LOGPIXELSY); | 
 |  1881                         m_lf.lfHeight = -(int)((cf.yHeight * yPerInch) / 1440); | 
 |  1882                 } | 
 |  1883                 else | 
 |  1884                         m_lf.lfHeight = 0; | 
 |  1885  | 
 |  1886                 m_lf.lfWidth = 0; | 
 |  1887                 m_lf.lfEscapement = 0; | 
 |  1888                 m_lf.lfOrientation = 0; | 
 |  1889  | 
 |  1890                 if((cf.dwMask & (CFM_ITALIC | CFM_BOLD)) == (CFM_ITALIC | CFM_BO
      LD)) | 
 |  1891                 { | 
 |  1892                         m_lf.lfWeight = ((cf.dwEffects & CFE_BOLD) != 0) ? FW_BO
      LD : FW_NORMAL; | 
 |  1893                         m_lf.lfItalic = (BYTE)(((cf.dwEffects & CFE_ITALIC) != 0
      ) ? TRUE : FALSE); | 
 |  1894                 } | 
 |  1895                 else | 
 |  1896                 { | 
 |  1897                         dwFlags |= CF_NOSTYLESEL; | 
 |  1898                         m_lf.lfWeight = FW_DONTCARE; | 
 |  1899                         m_lf.lfItalic = FALSE; | 
 |  1900                 } | 
 |  1901  | 
 |  1902                 if((cf.dwMask & (CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR)) == 
      (CFM_UNDERLINE|CFM_STRIKEOUT|CFM_COLOR)) | 
 |  1903                 { | 
 |  1904                         dwFlags |= CF_EFFECTS; | 
 |  1905                         m_lf.lfUnderline = (BYTE)(((cf.dwEffects & CFE_UNDERLINE
      ) != 0) ? TRUE : FALSE); | 
 |  1906                         m_lf.lfStrikeOut = (BYTE)(((cf.dwEffects & CFE_STRIKEOUT
      ) != 0) ? TRUE : FALSE); | 
 |  1907                 } | 
 |  1908                 else | 
 |  1909                 { | 
 |  1910                         m_lf.lfUnderline = (BYTE)FALSE; | 
 |  1911                         m_lf.lfStrikeOut = (BYTE)FALSE; | 
 |  1912                 } | 
 |  1913  | 
 |  1914                 if((cf.dwMask & CFM_CHARSET) != 0) | 
 |  1915                         m_lf.lfCharSet = cf.bCharSet; | 
 |  1916                 else | 
 |  1917                         dwFlags |= CF_NOSCRIPTSEL; | 
 |  1918                 m_lf.lfOutPrecision = OUT_DEFAULT_PRECIS; | 
 |  1919                 m_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; | 
 |  1920                 m_lf.lfQuality = DEFAULT_QUALITY; | 
 |  1921                 if((cf.dwMask & CFM_FACE) != 0) | 
 |  1922                 { | 
 |  1923                         m_lf.lfPitchAndFamily = cf.bPitchAndFamily; | 
 |  1924 #if (_RICHEDIT_VER >= 0x0200) | 
 |  1925                         SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lf
      FaceName), cf.szFaceName); | 
 |  1926 #else // !(_RICHEDIT_VER >= 0x0200) | 
 |  1927                         SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lf
      FaceName), A2T((LPSTR)cf.szFaceName)); | 
 |  1928 #endif // !(_RICHEDIT_VER >= 0x0200) | 
 |  1929                 } | 
 |  1930                 else | 
 |  1931                 { | 
 |  1932                         m_lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE; | 
 |  1933                         m_lf.lfFaceName[0] = (TCHAR)0; | 
 |  1934                 } | 
 |  1935                 return dwFlags; | 
 |  1936         } | 
 |  1937 }; | 
 |  1938  | 
 |  1939 class CRichEditFontDialog : public CRichEditFontDialogImpl<CRichEditFontDialog> | 
 |  1940 { | 
 |  1941 public: | 
 |  1942         CRichEditFontDialog(const CHARFORMAT& charformat, | 
 |  1943                 DWORD dwFlags = CF_SCREENFONTS, | 
 |  1944                 HDC hDCPrinter = NULL, | 
 |  1945                 HWND hWndParent = NULL) | 
 |  1946                 : CRichEditFontDialogImpl<CRichEditFontDialog>(charformat, dwFla
      gs, hDCPrinter, hWndParent) | 
 |  1947         { } | 
 |  1948  | 
 |  1949         DECLARE_EMPTY_MSG_MAP() | 
 |  1950 }; | 
 |  1951  | 
 |  1952 #endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE) | 
 |  1953  | 
 |  1954  | 
 |  1955 /////////////////////////////////////////////////////////////////////////////// | 
 |  1956 // CColorDialogImpl - color selection | 
 |  1957  | 
 |  1958 #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP
      ) && (_WIN32_WCE > 0x0500))) | 
 |  1959  | 
 |  1960 #ifdef _WIN32_WCE | 
 |  1961   #pragma comment(lib, "commdlg.lib") | 
 |  1962  | 
 |  1963   #ifndef SETRGBSTRING | 
 |  1964     #define SETRGBSTRING _T("commdlg_SetRGBColor") | 
 |  1965   #endif | 
 |  1966  | 
 |  1967   #ifndef COLOROKSTRING | 
 |  1968     #define COLOROKSTRING _T("commdlg_ColorOK") | 
 |  1969   #endif | 
 |  1970 #endif | 
 |  1971  | 
 |  1972 template <class T> | 
 |  1973 class ATL_NO_VTABLE CColorDialogImpl : public CCommonDialogImplBase | 
 |  1974 { | 
 |  1975 public: | 
 |  1976         CHOOSECOLOR m_cc; | 
 |  1977  | 
 |  1978 // Constructor | 
 |  1979         CColorDialogImpl(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParen
      t = NULL) | 
 |  1980         { | 
 |  1981                 memset(&m_cc, 0, sizeof(m_cc)); | 
 |  1982  | 
 |  1983                 m_cc.lStructSize = sizeof(m_cc); | 
 |  1984                 m_cc.lpCustColors = GetCustomColors(); | 
 |  1985                 m_cc.hwndOwner = hWndParent; | 
 |  1986                 m_cc.Flags = dwFlags | CC_ENABLEHOOK; | 
 |  1987                 m_cc.lpfnHook = (LPCCHOOKPROC)T::HookProc; | 
 |  1988  | 
 |  1989                 if(clrInit != 0) | 
 |  1990                 { | 
 |  1991                         m_cc.rgbResult = clrInit; | 
 |  1992                         m_cc.Flags |= CC_RGBINIT; | 
 |  1993                 } | 
 |  1994         } | 
 |  1995  | 
 |  1996 // Operations | 
 |  1997         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  1998         { | 
 |  1999                 ATLASSERT((m_cc.Flags & CC_ENABLEHOOK) != 0); | 
 |  2000                 ATLASSERT(m_cc.lpfnHook != NULL);   // can still be a user hook | 
 |  2001  | 
 |  2002                 if(m_cc.hwndOwner == NULL)          // set only if not specified
       before | 
 |  2003                         m_cc.hwndOwner = hWndParent; | 
 |  2004  | 
 |  2005                 ATLASSERT(m_hWnd == NULL); | 
 |  2006                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBa
      se*)this); | 
 |  2007  | 
 |  2008                 BOOL bRet = ::ChooseColor(&m_cc); | 
 |  2009  | 
 |  2010                 m_hWnd = NULL; | 
 |  2011  | 
 |  2012                 return bRet ? IDOK : IDCANCEL; | 
 |  2013         } | 
 |  2014  | 
 |  2015         // Set the current color while dialog is displayed | 
 |  2016         void SetCurrentColor(COLORREF clr) | 
 |  2017         { | 
 |  2018                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  2019                 SendMessage(_GetSetRGBMessage(), 0, (LPARAM)clr); | 
 |  2020         } | 
 |  2021  | 
 |  2022         // Get the selected color after DoModal returns, or in OnColorOK | 
 |  2023         COLORREF GetColor() const | 
 |  2024         { | 
 |  2025                 return m_cc.rgbResult; | 
 |  2026         } | 
 |  2027  | 
 |  2028 // Special override for the color dialog | 
 |  2029         static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, L
      PARAM lParam) | 
 |  2030         { | 
 |  2031                 if(uMsg != WM_INITDIALOG && uMsg != _GetColorOKMessage()) | 
 |  2032                         return 0; | 
 |  2033  | 
 |  2034                 LPCHOOSECOLOR lpCC = (LPCHOOSECOLOR)lParam; | 
 |  2035                 CCommonDialogImplBase* pT = NULL; | 
 |  2036  | 
 |  2037                 if(uMsg == WM_INITDIALOG) | 
 |  2038                 { | 
 |  2039                         pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreate
      WndData(); | 
 |  2040                         lpCC->lCustData = (LPARAM)pT; | 
 |  2041                         ATLASSERT(pT != NULL); | 
 |  2042                         ATLASSERT(pT->m_hWnd == NULL); | 
 |  2043                         ATLASSERT(::IsWindow(hWnd)); | 
 |  2044                         // subclass dialog's window | 
 |  2045                         if(!pT->SubclassWindow(hWnd)) | 
 |  2046                         { | 
 |  2047                                 ATLTRACE2(atlTraceUI, 0, _T("Subclassing a Color
       common dialog failed\n")); | 
 |  2048                                 return 0; | 
 |  2049                         } | 
 |  2050                 } | 
 |  2051                 else if(uMsg == _GetColorOKMessage()) | 
 |  2052                 { | 
 |  2053                         pT = (CCommonDialogImplBase*)lpCC->lCustData; | 
 |  2054                         ATLASSERT(pT != NULL); | 
 |  2055                         ATLASSERT(::IsWindow(pT->m_hWnd)); | 
 |  2056                 } | 
 |  2057  | 
 |  2058                 // pass to the message map | 
 |  2059                 LRESULT lRes; | 
 |  2060                 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lR
      es, 0) == FALSE) | 
 |  2061                         return 0; | 
 |  2062                 return lRes; | 
 |  2063         } | 
 |  2064  | 
 |  2065 // Helpers | 
 |  2066         static COLORREF* GetCustomColors() | 
 |  2067         { | 
 |  2068                 static COLORREF rgbCustomColors[16] = | 
 |  2069                 { | 
 |  2070                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2071                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2072                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2073                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2074                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2075                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2076                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2077                         RGB(255, 255, 255), RGB(255, 255, 255),  | 
 |  2078                 }; | 
 |  2079  | 
 |  2080                 return rgbCustomColors; | 
 |  2081         } | 
 |  2082  | 
 |  2083         static UINT _GetSetRGBMessage() | 
 |  2084         { | 
 |  2085                 static UINT uSetRGBMessage = 0; | 
 |  2086                 if(uSetRGBMessage == 0) | 
 |  2087                 { | 
 |  2088                         CStaticDataInitCriticalSectionLock lock; | 
 |  2089                         if(FAILED(lock.Lock())) | 
 |  2090                         { | 
 |  2091                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CColorDialogImpl::_GetSetRGBMessage.\n")); | 
 |  2092                                 ATLASSERT(FALSE); | 
 |  2093                                 return 0; | 
 |  2094                         } | 
 |  2095  | 
 |  2096                         if(uSetRGBMessage == 0) | 
 |  2097                                 uSetRGBMessage = ::RegisterWindowMessage(SETRGBS
      TRING); | 
 |  2098  | 
 |  2099                         lock.Unlock(); | 
 |  2100                 } | 
 |  2101                 ATLASSERT(uSetRGBMessage != 0); | 
 |  2102                 return uSetRGBMessage; | 
 |  2103         } | 
 |  2104  | 
 |  2105         static UINT _GetColorOKMessage() | 
 |  2106         { | 
 |  2107                 static UINT uColorOKMessage = 0; | 
 |  2108                 if(uColorOKMessage == 0) | 
 |  2109                 { | 
 |  2110                         CStaticDataInitCriticalSectionLock lock; | 
 |  2111                         if(FAILED(lock.Lock())) | 
 |  2112                         { | 
 |  2113                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CColorDialogImpl::_GetColorOKMessage.\n")); | 
 |  2114                                 ATLASSERT(FALSE); | 
 |  2115                                 return 0; | 
 |  2116                         } | 
 |  2117  | 
 |  2118                         if(uColorOKMessage == 0) | 
 |  2119                                 uColorOKMessage = ::RegisterWindowMessage(COLORO
      KSTRING); | 
 |  2120  | 
 |  2121                         lock.Unlock(); | 
 |  2122                 } | 
 |  2123                 ATLASSERT(uColorOKMessage != 0); | 
 |  2124                 return uColorOKMessage; | 
 |  2125         } | 
 |  2126  | 
 |  2127 // Message map and handlers | 
 |  2128         BEGIN_MSG_MAP(CColorDialogImpl) | 
 |  2129                 MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK) | 
 |  2130         END_MSG_MAP() | 
 |  2131  | 
 |  2132         LRESULT _OnColorOK(UINT, WPARAM, LPARAM, BOOL&) | 
 |  2133         { | 
 |  2134                 T* pT = static_cast<T*>(this); | 
 |  2135                 return pT->OnColorOK(); | 
 |  2136         } | 
 |  2137  | 
 |  2138 // Overrideable | 
 |  2139         BOOL OnColorOK()        // validate color | 
 |  2140         { | 
 |  2141                 return FALSE; | 
 |  2142         } | 
 |  2143 }; | 
 |  2144  | 
 |  2145 class CColorDialog : public CColorDialogImpl<CColorDialog> | 
 |  2146 { | 
 |  2147 public: | 
 |  2148         CColorDialog(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = 
      NULL) | 
 |  2149                 : CColorDialogImpl<CColorDialog>(clrInit, dwFlags, hWndParent) | 
 |  2150         { } | 
 |  2151  | 
 |  2152         // override base class map and references to handlers | 
 |  2153         DECLARE_EMPTY_MSG_MAP() | 
 |  2154 }; | 
 |  2155  | 
 |  2156 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFOR
      M_WFSP) && (_WIN32_WCE > 0x0500))) | 
 |  2157  | 
 |  2158  | 
 |  2159 /////////////////////////////////////////////////////////////////////////////// | 
 |  2160 // CPrintDialogImpl - used for Print... and PrintSetup... | 
 |  2161  | 
 |  2162 #ifndef _WIN32_WCE | 
 |  2163  | 
 |  2164 // global helper | 
 |  2165 static HDC _AtlCreateDC(HGLOBAL hDevNames, HGLOBAL hDevMode) | 
 |  2166 { | 
 |  2167         if(hDevNames == NULL) | 
 |  2168                 return NULL; | 
 |  2169  | 
 |  2170         LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(hDevNames); | 
 |  2171         LPDEVMODE  lpDevMode = (hDevMode != NULL) ? (LPDEVMODE)::GlobalLock(hDev
      Mode) : NULL; | 
 |  2172  | 
 |  2173         if(lpDevNames == NULL) | 
 |  2174                 return NULL; | 
 |  2175  | 
 |  2176         HDC hDC = ::CreateDC((LPCTSTR)lpDevNames + lpDevNames->wDriverOffset, | 
 |  2177                                           (LPCTSTR)lpDevNames + lpDevNames->wDev
      iceOffset, | 
 |  2178                                           (LPCTSTR)lpDevNames + lpDevNames->wOut
      putOffset, | 
 |  2179                                           lpDevMode); | 
 |  2180  | 
 |  2181         ::GlobalUnlock(hDevNames); | 
 |  2182         if(hDevMode != NULL) | 
 |  2183                 ::GlobalUnlock(hDevMode); | 
 |  2184         return hDC; | 
 |  2185 } | 
 |  2186  | 
 |  2187 template <class T> | 
 |  2188 class ATL_NO_VTABLE CPrintDialogImpl : public CCommonDialogImplBase | 
 |  2189 { | 
 |  2190 public: | 
 |  2191         // print dialog parameter block (note this is a reference) | 
 |  2192         PRINTDLG& m_pd; | 
 |  2193  | 
 |  2194 // Constructors | 
 |  2195         CPrintDialogImpl(BOOL bPrintSetupOnly = FALSE,  // TRUE for Print Setup,
       FALSE for Print Dialog | 
 |  2196                         DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_N
      OPAGENUMS | PD_NOSELECTION, | 
 |  2197                         HWND hWndParent = NULL) | 
 |  2198                         : m_pd(m_pdActual) | 
 |  2199         { | 
 |  2200                 memset(&m_pdActual, 0, sizeof(m_pdActual)); | 
 |  2201  | 
 |  2202                 m_pd.lStructSize = sizeof(m_pdActual); | 
 |  2203                 m_pd.hwndOwner = hWndParent; | 
 |  2204                 m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK)
      ; | 
 |  2205                 m_pd.lpfnPrintHook = (LPPRINTHOOKPROC)T::HookProc; | 
 |  2206                 m_pd.lpfnSetupHook = (LPSETUPHOOKPROC)T::HookProc; | 
 |  2207  | 
 |  2208                 if(bPrintSetupOnly) | 
 |  2209                         m_pd.Flags |= PD_PRINTSETUP; | 
 |  2210                 else | 
 |  2211                         m_pd.Flags |= PD_RETURNDC; | 
 |  2212  | 
 |  2213                 m_pd.Flags &= ~PD_RETURNIC; // do not support information contex
      t | 
 |  2214         } | 
 |  2215  | 
 |  2216 // Operations | 
 |  2217         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  2218         { | 
 |  2219                 ATLASSERT((m_pd.Flags & PD_ENABLEPRINTHOOK) != 0); | 
 |  2220                 ATLASSERT((m_pd.Flags & PD_ENABLESETUPHOOK) != 0); | 
 |  2221                 ATLASSERT(m_pd.lpfnPrintHook != NULL);   // can still be a user 
      hook | 
 |  2222                 ATLASSERT(m_pd.lpfnSetupHook != NULL);   // can still be a user 
      hook | 
 |  2223                 ATLASSERT((m_pd.Flags & PD_RETURNDEFAULT) == 0);   // use GetDef
      aults for this | 
 |  2224  | 
 |  2225                 if(m_pd.hwndOwner == NULL)   // set only if not specified before | 
 |  2226                         m_pd.hwndOwner = hWndParent; | 
 |  2227  | 
 |  2228                 ATLASSERT(m_hWnd == NULL); | 
 |  2229                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBa
      se*)this); | 
 |  2230  | 
 |  2231                 BOOL bRet = ::PrintDlg(&m_pd); | 
 |  2232  | 
 |  2233                 m_hWnd = NULL; | 
 |  2234  | 
 |  2235                 return bRet ? IDOK : IDCANCEL; | 
 |  2236         } | 
 |  2237  | 
 |  2238         // GetDefaults will not display a dialog but will get device defaults | 
 |  2239         BOOL GetDefaults() | 
 |  2240         { | 
 |  2241                 m_pd.Flags |= PD_RETURNDEFAULT; | 
 |  2242                 ATLASSERT(m_pd.hDevMode == NULL);    // must be NULL | 
 |  2243                 ATLASSERT(m_pd.hDevNames == NULL);   // must be NULL | 
 |  2244  | 
 |  2245                 return ::PrintDlg(&m_pd); | 
 |  2246         } | 
 |  2247  | 
 |  2248         // Helpers for parsing information after successful return num. copies r
      equested | 
 |  2249         int GetCopies() const | 
 |  2250         { | 
 |  2251                 if((m_pd.Flags & PD_USEDEVMODECOPIES) != 0) | 
 |  2252                 { | 
 |  2253                         LPDEVMODE lpDevMode = GetDevMode(); | 
 |  2254                         return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; | 
 |  2255                 } | 
 |  2256  | 
 |  2257                 return m_pd.nCopies; | 
 |  2258         } | 
 |  2259  | 
 |  2260         BOOL PrintCollate() const       // TRUE if collate checked | 
 |  2261         { | 
 |  2262                 return ((m_pd.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; | 
 |  2263         } | 
 |  2264  | 
 |  2265         BOOL PrintSelection() const     // TRUE if printing selection | 
 |  2266         { | 
 |  2267                 return ((m_pd.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; | 
 |  2268         } | 
 |  2269  | 
 |  2270         BOOL PrintAll() const           // TRUE if printing all pages | 
 |  2271         { | 
 |  2272                 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; | 
 |  2273         } | 
 |  2274  | 
 |  2275         BOOL PrintRange() const         // TRUE if printing page range | 
 |  2276         { | 
 |  2277                 return ((m_pd.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; | 
 |  2278         } | 
 |  2279  | 
 |  2280         BOOL PrintToFile() const        // TRUE if printing to a file | 
 |  2281         { | 
 |  2282                 return ((m_pd.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; | 
 |  2283         } | 
 |  2284  | 
 |  2285         int GetFromPage() const         // starting page if valid | 
 |  2286         { | 
 |  2287                 return PrintRange() ? m_pd.nFromPage : -1; | 
 |  2288         } | 
 |  2289  | 
 |  2290         int GetToPage() const           // ending page if valid | 
 |  2291         { | 
 |  2292                 return PrintRange() ? m_pd.nToPage : -1; | 
 |  2293         } | 
 |  2294  | 
 |  2295         LPDEVMODE GetDevMode() const    // return DEVMODE | 
 |  2296         { | 
 |  2297                 if(m_pd.hDevMode == NULL) | 
 |  2298                         return NULL; | 
 |  2299  | 
 |  2300                 return (LPDEVMODE)::GlobalLock(m_pd.hDevMode); | 
 |  2301         } | 
 |  2302  | 
 |  2303         LPCTSTR GetDriverName() const   // return driver name | 
 |  2304         { | 
 |  2305                 if(m_pd.hDevNames == NULL) | 
 |  2306                         return NULL; | 
 |  2307  | 
 |  2308                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); | 
 |  2309                 if(lpDev == NULL) | 
 |  2310                         return NULL; | 
 |  2311  | 
 |  2312                 return (LPCTSTR)lpDev + lpDev->wDriverOffset; | 
 |  2313         } | 
 |  2314  | 
 |  2315         LPCTSTR GetDeviceName() const   // return device name | 
 |  2316         { | 
 |  2317                 if(m_pd.hDevNames == NULL) | 
 |  2318                         return NULL; | 
 |  2319  | 
 |  2320                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); | 
 |  2321                 if(lpDev == NULL) | 
 |  2322                         return NULL; | 
 |  2323  | 
 |  2324                 return (LPCTSTR)lpDev + lpDev->wDeviceOffset; | 
 |  2325         } | 
 |  2326  | 
 |  2327         LPCTSTR GetPortName() const     // return output port name | 
 |  2328         { | 
 |  2329                 if(m_pd.hDevNames == NULL) | 
 |  2330                         return NULL; | 
 |  2331  | 
 |  2332                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames); | 
 |  2333                 if(lpDev == NULL) | 
 |  2334                         return NULL; | 
 |  2335  | 
 |  2336                 return (LPCTSTR)lpDev + lpDev->wOutputOffset; | 
 |  2337         } | 
 |  2338  | 
 |  2339         HDC GetPrinterDC() const        // return HDC (caller must delete) | 
 |  2340         { | 
 |  2341                 ATLASSERT((m_pd.Flags & PD_RETURNDC) != 0); | 
 |  2342                 return m_pd.hDC; | 
 |  2343         } | 
 |  2344  | 
 |  2345         // This helper creates a DC based on the DEVNAMES and DEVMODE structures
      . | 
 |  2346         // This DC is returned, but also stored in m_pd.hDC as though it had bee
      n | 
 |  2347         // returned by CommDlg.  It is assumed that any previously obtained DC | 
 |  2348         // has been/will be deleted by the user.  This may be | 
 |  2349         // used without ever invoking the print/print setup dialogs. | 
 |  2350         HDC CreatePrinterDC() | 
 |  2351         { | 
 |  2352                 m_pd.hDC = _AtlCreateDC(m_pd.hDevNames, m_pd.hDevMode); | 
 |  2353                 return m_pd.hDC; | 
 |  2354         } | 
 |  2355  | 
 |  2356 // Implementation | 
 |  2357         PRINTDLG m_pdActual; // the Print/Print Setup need to share this | 
 |  2358  | 
 |  2359         // The following handle the case of print setup... from the print dialog | 
 |  2360         CPrintDialogImpl(PRINTDLG& pdInit) : m_pd(pdInit) | 
 |  2361         { } | 
 |  2362  | 
 |  2363         BEGIN_MSG_MAP(CPrintDialogImpl) | 
 |  2364 #ifdef psh1 | 
 |  2365                 COMMAND_ID_HANDLER(psh1, OnPrintSetup) // print setup button whe
      n print is displayed | 
 |  2366 #else // !psh1 | 
 |  2367                 COMMAND_ID_HANDLER(0x0400, OnPrintSetup) // value from dlgs.h | 
 |  2368 #endif // !psh1 | 
 |  2369         END_MSG_MAP() | 
 |  2370  | 
 |  2371         LRESULT OnPrintSetup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& /*b
      Handled*/) | 
 |  2372         { | 
 |  2373                 T dlgSetup(m_pd); | 
 |  2374                 ModuleHelper::AddCreateWndData(&dlgSetup.m_thunk.cd, (CCommonDia
      logImplBase*)&dlgSetup); | 
 |  2375                 return DefWindowProc(WM_COMMAND, MAKEWPARAM(wID, wNotifyCode), (
      LPARAM)hWndCtl); | 
 |  2376         } | 
 |  2377 }; | 
 |  2378  | 
 |  2379 class CPrintDialog : public CPrintDialogImpl<CPrintDialog> | 
 |  2380 { | 
 |  2381 public: | 
 |  2382         CPrintDialog(BOOL bPrintSetupOnly = FALSE, | 
 |  2383                 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUM
      S | PD_NOSELECTION, | 
 |  2384                 HWND hWndParent = NULL) | 
 |  2385                 : CPrintDialogImpl<CPrintDialog>(bPrintSetupOnly, dwFlags, hWndP
      arent) | 
 |  2386         { } | 
 |  2387  | 
 |  2388         CPrintDialog(PRINTDLG& pdInit) : CPrintDialogImpl<CPrintDialog>(pdInit) | 
 |  2389         { } | 
 |  2390 }; | 
 |  2391  | 
 |  2392 #endif // _WIN32_WCE | 
 |  2393  | 
 |  2394  | 
 |  2395 /////////////////////////////////////////////////////////////////////////////// | 
 |  2396 // CPrintDialogExImpl - new print dialog for Windows 2000 | 
 |  2397  | 
 |  2398 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE) | 
 |  2399  | 
 |  2400 }; // namespace WTL | 
 |  2401  | 
 |  2402 #include <atlcom.h> | 
 |  2403  | 
 |  2404 extern "C" const __declspec(selectany) IID IID_IPrintDialogCallback = {0x5852a2c
      3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; | 
 |  2405 extern "C" const __declspec(selectany) IID IID_IPrintDialogServices = {0x509aaed
      a, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}}; | 
 |  2406  | 
 |  2407 namespace WTL | 
 |  2408 { | 
 |  2409  | 
 |  2410 template <class T> | 
 |  2411 class ATL_NO_VTABLE CPrintDialogExImpl :  | 
 |  2412                                 public ATL::CWindow, | 
 |  2413                                 public ATL::CMessageMap, | 
 |  2414                                 public IPrintDialogCallback, | 
 |  2415                                 public ATL::IObjectWithSiteImpl< T > | 
 |  2416 { | 
 |  2417 public: | 
 |  2418         PRINTDLGEX m_pdex; | 
 |  2419  | 
 |  2420 // Constructor | 
 |  2421         CPrintDialogExImpl(DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | P
      D_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE, | 
 |  2422                                 HWND hWndParent = NULL) | 
 |  2423         { | 
 |  2424                 memset(&m_pdex, 0, sizeof(m_pdex)); | 
 |  2425  | 
 |  2426                 m_pdex.lStructSize = sizeof(PRINTDLGEX); | 
 |  2427                 m_pdex.hwndOwner = hWndParent; | 
 |  2428                 m_pdex.Flags = dwFlags; | 
 |  2429                 m_pdex.nStartPage = START_PAGE_GENERAL; | 
 |  2430                 // callback object will be set in DoModal | 
 |  2431  | 
 |  2432                 m_pdex.Flags &= ~PD_RETURNIC; // do not support information cont
      ext | 
 |  2433         } | 
 |  2434  | 
 |  2435 // Operations | 
 |  2436         HRESULT DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  2437         { | 
 |  2438                 ATLASSERT(m_hWnd == NULL); | 
 |  2439                 ATLASSERT((m_pdex.Flags & PD_RETURNDEFAULT) == 0);   // use GetD
      efaults for this | 
 |  2440  | 
 |  2441                 if(m_pdex.hwndOwner == NULL)   // set only if not specified befo
      re | 
 |  2442                         m_pdex.hwndOwner = hWndParent; | 
 |  2443  | 
 |  2444                 T* pT = static_cast<T*>(this); | 
 |  2445                 m_pdex.lpCallback = (IUnknown*)(IPrintDialogCallback*)pT; | 
 |  2446  | 
 |  2447                 HRESULT hResult = ::PrintDlgEx(&m_pdex); | 
 |  2448  | 
 |  2449                 m_hWnd = NULL; | 
 |  2450  | 
 |  2451                 return hResult; | 
 |  2452         } | 
 |  2453  | 
 |  2454         BOOL EndDialog(INT_PTR /*nRetCode*/ = 0) | 
 |  2455         { | 
 |  2456                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  2457                 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0)); | 
 |  2458                 return TRUE; | 
 |  2459         } | 
 |  2460  | 
 |  2461         // GetDefaults will not display a dialog but will get device defaults | 
 |  2462         HRESULT GetDefaults() | 
 |  2463         { | 
 |  2464                 m_pdex.Flags |= PD_RETURNDEFAULT; | 
 |  2465                 ATLASSERT(m_pdex.hDevMode == NULL);    // must be NULL | 
 |  2466                 ATLASSERT(m_pdex.hDevNames == NULL);   // must be NULL | 
 |  2467  | 
 |  2468                 return ::PrintDlgEx(&m_pdex); | 
 |  2469         } | 
 |  2470  | 
 |  2471         // Helpers for parsing information after successful return num. copies r
      equested | 
 |  2472         int GetCopies() const | 
 |  2473         { | 
 |  2474                 if((m_pdex.Flags & PD_USEDEVMODECOPIES) != 0) | 
 |  2475                 { | 
 |  2476                         LPDEVMODE lpDevMode = GetDevMode(); | 
 |  2477                         return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1; | 
 |  2478                 } | 
 |  2479  | 
 |  2480                 return m_pdex.nCopies; | 
 |  2481         } | 
 |  2482  | 
 |  2483         BOOL PrintCollate() const       // TRUE if collate checked | 
 |  2484         { | 
 |  2485                 return ((m_pdex.Flags & PD_COLLATE) != 0) ? TRUE : FALSE; | 
 |  2486         } | 
 |  2487  | 
 |  2488         BOOL PrintSelection() const     // TRUE if printing selection | 
 |  2489         { | 
 |  2490                 return ((m_pdex.Flags & PD_SELECTION) != 0) ? TRUE : FALSE; | 
 |  2491         } | 
 |  2492  | 
 |  2493         BOOL PrintAll() const           // TRUE if printing all pages | 
 |  2494         { | 
 |  2495                 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE; | 
 |  2496         } | 
 |  2497  | 
 |  2498         BOOL PrintRange() const         // TRUE if printing page range | 
 |  2499         { | 
 |  2500                 return ((m_pdex.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE; | 
 |  2501         } | 
 |  2502  | 
 |  2503         BOOL PrintToFile() const        // TRUE if printing to a file | 
 |  2504         { | 
 |  2505                 return ((m_pdex.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE; | 
 |  2506         } | 
 |  2507  | 
 |  2508         LPDEVMODE GetDevMode() const    // return DEVMODE | 
 |  2509         { | 
 |  2510                 if(m_pdex.hDevMode == NULL) | 
 |  2511                         return NULL; | 
 |  2512  | 
 |  2513                 return (LPDEVMODE)::GlobalLock(m_pdex.hDevMode); | 
 |  2514         } | 
 |  2515  | 
 |  2516         LPCTSTR GetDriverName() const   // return driver name | 
 |  2517         { | 
 |  2518                 if(m_pdex.hDevNames == NULL) | 
 |  2519                         return NULL; | 
 |  2520  | 
 |  2521                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); | 
 |  2522                 if(lpDev == NULL) | 
 |  2523                         return NULL; | 
 |  2524  | 
 |  2525                 return (LPCTSTR)lpDev + lpDev->wDriverOffset; | 
 |  2526         } | 
 |  2527  | 
 |  2528         LPCTSTR GetDeviceName() const   // return device name | 
 |  2529         { | 
 |  2530                 if(m_pdex.hDevNames == NULL) | 
 |  2531                         return NULL; | 
 |  2532  | 
 |  2533                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); | 
 |  2534                 if(lpDev == NULL) | 
 |  2535                         return NULL; | 
 |  2536  | 
 |  2537                 return (LPCTSTR)lpDev + lpDev->wDeviceOffset; | 
 |  2538         } | 
 |  2539  | 
 |  2540         LPCTSTR GetPortName() const     // return output port name | 
 |  2541         { | 
 |  2542                 if(m_pdex.hDevNames == NULL) | 
 |  2543                         return NULL; | 
 |  2544  | 
 |  2545                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames); | 
 |  2546                 if(lpDev == NULL) | 
 |  2547                         return NULL; | 
 |  2548  | 
 |  2549                 return (LPCTSTR)lpDev + lpDev->wOutputOffset; | 
 |  2550         } | 
 |  2551  | 
 |  2552         HDC GetPrinterDC() const        // return HDC (caller must delete) | 
 |  2553         { | 
 |  2554                 ATLASSERT((m_pdex.Flags & PD_RETURNDC) != 0); | 
 |  2555                 return m_pdex.hDC; | 
 |  2556         } | 
 |  2557  | 
 |  2558         // This helper creates a DC based on the DEVNAMES and DEVMODE structures
      . | 
 |  2559         // This DC is returned, but also stored in m_pdex.hDC as though it had b
      een | 
 |  2560         // returned by CommDlg.  It is assumed that any previously obtained DC | 
 |  2561         // has been/will be deleted by the user.  This may be | 
 |  2562         // used without ever invoking the print/print setup dialogs. | 
 |  2563         HDC CreatePrinterDC() | 
 |  2564         { | 
 |  2565                 m_pdex.hDC = _AtlCreateDC(m_pdex.hDevNames, m_pdex.hDevMode); | 
 |  2566                 return m_pdex.hDC; | 
 |  2567         } | 
 |  2568  | 
 |  2569 // Implementation - interfaces | 
 |  2570  | 
 |  2571 // IUnknown | 
 |  2572         STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject) | 
 |  2573         { | 
 |  2574                 if(ppvObject == NULL) | 
 |  2575                         return E_POINTER; | 
 |  2576  | 
 |  2577                 T* pT = static_cast<T*>(this); | 
 |  2578                 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IPri
      ntDialogCallback)) | 
 |  2579                 { | 
 |  2580                         *ppvObject = (IPrintDialogCallback*)pT; | 
 |  2581                         // AddRef() not needed | 
 |  2582                         return S_OK; | 
 |  2583                 } | 
 |  2584                 else if(IsEqualGUID(riid, IID_IObjectWithSite)) | 
 |  2585                 { | 
 |  2586                         *ppvObject = (IObjectWithSite*)pT; | 
 |  2587                         // AddRef() not needed | 
 |  2588                         return S_OK; | 
 |  2589                 } | 
 |  2590  | 
 |  2591                 return E_NOINTERFACE; | 
 |  2592         } | 
 |  2593  | 
 |  2594         virtual ULONG STDMETHODCALLTYPE AddRef() | 
 |  2595         { | 
 |  2596                 return 1; | 
 |  2597         } | 
 |  2598  | 
 |  2599         virtual ULONG STDMETHODCALLTYPE Release() | 
 |  2600         { | 
 |  2601                 return 1; | 
 |  2602         } | 
 |  2603  | 
 |  2604 // IPrintDialogCallback | 
 |  2605         STDMETHOD(InitDone)() | 
 |  2606         { | 
 |  2607                 return S_FALSE; | 
 |  2608         } | 
 |  2609  | 
 |  2610         STDMETHOD(SelectionChange)() | 
 |  2611         { | 
 |  2612                 return S_FALSE; | 
 |  2613         } | 
 |  2614  | 
 |  2615         STDMETHOD(HandleMessage)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPa
      ram, LRESULT* plResult) | 
 |  2616         { | 
 |  2617                 // set up m_hWnd the first time | 
 |  2618                 if(m_hWnd == NULL) | 
 |  2619                         Attach(hWnd); | 
 |  2620  | 
 |  2621                 // call message map | 
 |  2622                 HRESULT hRet = ProcessWindowMessage(hWnd, uMsg, wParam, lParam, 
      *plResult, 0) ? S_OK : S_FALSE; | 
 |  2623                 if(hRet == S_OK && uMsg == WM_NOTIFY)   // return in DWLP_MSGRES
      ULT | 
 |  2624                         ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT, (LONG_PT
      R)*plResult); | 
 |  2625  | 
 |  2626                 if(uMsg == WM_INITDIALOG && hRet == S_OK && (BOOL)*plResult != F
      ALSE) | 
 |  2627                         hRet = S_FALSE; | 
 |  2628  | 
 |  2629                 return hRet; | 
 |  2630         } | 
 |  2631 }; | 
 |  2632  | 
 |  2633 class CPrintDialogEx : public CPrintDialogExImpl<CPrintDialogEx> | 
 |  2634 { | 
 |  2635 public: | 
 |  2636         CPrintDialogEx( | 
 |  2637                 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUM
      S | PD_NOSELECTION | PD_NOCURRENTPAGE, | 
 |  2638                 HWND hWndParent = NULL) | 
 |  2639                 : CPrintDialogExImpl<CPrintDialogEx>(dwFlags, hWndParent) | 
 |  2640         { } | 
 |  2641  | 
 |  2642         DECLARE_EMPTY_MSG_MAP() | 
 |  2643 }; | 
 |  2644  | 
 |  2645 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE) | 
 |  2646  | 
 |  2647  | 
 |  2648 /////////////////////////////////////////////////////////////////////////////// | 
 |  2649 // CPageSetupDialogImpl - Page Setup dialog | 
 |  2650  | 
 |  2651 #ifndef _WIN32_WCE | 
 |  2652  | 
 |  2653 template <class T> | 
 |  2654 class ATL_NO_VTABLE CPageSetupDialogImpl : public CCommonDialogImplBase | 
 |  2655 { | 
 |  2656 public: | 
 |  2657         PAGESETUPDLG m_psd; | 
 |  2658         ATL::CWndProcThunk m_thunkPaint; | 
 |  2659  | 
 |  2660 // Constructors | 
 |  2661         CPageSetupDialogImpl(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASU
      RE, HWND hWndParent = NULL) | 
 |  2662         { | 
 |  2663                 memset(&m_psd, 0, sizeof(m_psd)); | 
 |  2664  | 
 |  2665                 m_psd.lStructSize = sizeof(m_psd); | 
 |  2666                 m_psd.hwndOwner = hWndParent; | 
 |  2667                 m_psd.Flags = (dwFlags | PSD_ENABLEPAGESETUPHOOK | PSD_ENABLEPAG
      EPAINTHOOK); | 
 |  2668                 m_psd.lpfnPageSetupHook = (LPPAGESETUPHOOK)T::HookProc; | 
 |  2669                 m_thunkPaint.Init((WNDPROC)T::PaintHookProc, this); | 
 |  2670 #if (_ATL_VER >= 0x0700) | 
 |  2671                 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)m_thunkPaint.GetWNDPR
      OC(); | 
 |  2672 #else | 
 |  2673                 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)&(m_thunkPaint.thunk)
      ; | 
 |  2674 #endif | 
 |  2675         } | 
 |  2676  | 
 |  2677         DECLARE_EMPTY_MSG_MAP() | 
 |  2678  | 
 |  2679 // Attributes | 
 |  2680         LPDEVMODE GetDevMode() const    // return DEVMODE | 
 |  2681         { | 
 |  2682                 if(m_psd.hDevMode == NULL) | 
 |  2683                         return NULL; | 
 |  2684  | 
 |  2685                 return (LPDEVMODE)::GlobalLock(m_psd.hDevMode); | 
 |  2686         } | 
 |  2687  | 
 |  2688         LPCTSTR GetDriverName() const   // return driver name | 
 |  2689         { | 
 |  2690                 if(m_psd.hDevNames == NULL) | 
 |  2691                         return NULL; | 
 |  2692  | 
 |  2693                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); | 
 |  2694                 return (LPCTSTR)lpDev + lpDev->wDriverOffset; | 
 |  2695         } | 
 |  2696  | 
 |  2697         LPCTSTR GetDeviceName() const   // return device name | 
 |  2698         { | 
 |  2699                 if(m_psd.hDevNames == NULL) | 
 |  2700                         return NULL; | 
 |  2701  | 
 |  2702                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); | 
 |  2703                 return (LPCTSTR)lpDev + lpDev->wDeviceOffset; | 
 |  2704         } | 
 |  2705  | 
 |  2706         LPCTSTR GetPortName() const     // return output port name | 
 |  2707         { | 
 |  2708                 if(m_psd.hDevNames == NULL) | 
 |  2709                         return NULL; | 
 |  2710  | 
 |  2711                 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames); | 
 |  2712                 return (LPCTSTR)lpDev + lpDev->wOutputOffset; | 
 |  2713         } | 
 |  2714  | 
 |  2715         HDC CreatePrinterDC() | 
 |  2716         { | 
 |  2717                 return _AtlCreateDC(m_psd.hDevNames, m_psd.hDevMode); | 
 |  2718         } | 
 |  2719  | 
 |  2720         SIZE GetPaperSize() const | 
 |  2721         { | 
 |  2722                 SIZE size; | 
 |  2723                 size.cx = m_psd.ptPaperSize.x; | 
 |  2724                 size.cy = m_psd.ptPaperSize.y; | 
 |  2725                 return size; | 
 |  2726         } | 
 |  2727  | 
 |  2728         void GetMargins(LPRECT lpRectMargins, LPRECT lpRectMinMargins) const | 
 |  2729         { | 
 |  2730                 if(lpRectMargins != NULL) | 
 |  2731                         *lpRectMargins = m_psd.rtMargin; | 
 |  2732                 if(lpRectMinMargins != NULL) | 
 |  2733                         *lpRectMinMargins = m_psd.rtMinMargin; | 
 |  2734         } | 
 |  2735  | 
 |  2736 // Operations | 
 |  2737         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  2738         { | 
 |  2739                 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGESETUPHOOK) != 0); | 
 |  2740                 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGEPAINTHOOK) != 0); | 
 |  2741                 ATLASSERT(m_psd.lpfnPageSetupHook != NULL);   // can still be a 
      user hook | 
 |  2742                 ATLASSERT(m_psd.lpfnPagePaintHook != NULL);   // can still be a 
      user hook | 
 |  2743  | 
 |  2744                 if(m_psd.hwndOwner == NULL)   // set only if not specified befor
      e | 
 |  2745                         m_psd.hwndOwner = hWndParent; | 
 |  2746  | 
 |  2747                 ATLASSERT(m_hWnd == NULL); | 
 |  2748                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBa
      se*)this); | 
 |  2749  | 
 |  2750                 BOOL bRet = ::PageSetupDlg(&m_psd); | 
 |  2751  | 
 |  2752                 m_hWnd = NULL; | 
 |  2753  | 
 |  2754                 return bRet ? IDOK : IDCANCEL; | 
 |  2755         } | 
 |  2756  | 
 |  2757 // Implementation | 
 |  2758         static UINT_PTR CALLBACK PaintHookProc(HWND hWnd, UINT uMsg, WPARAM wPar
      am, LPARAM lParam) | 
 |  2759         { | 
 |  2760                 T* pT = (T*)hWnd; | 
 |  2761                 UINT_PTR uRet = 0; | 
 |  2762                 switch(uMsg) | 
 |  2763                 { | 
 |  2764                 case WM_PSD_PAGESETUPDLG: | 
 |  2765                         uRet = pT->PreDrawPage(LOWORD(wParam), HIWORD(wParam), (
      LPPAGESETUPDLG)lParam); | 
 |  2766                         break; | 
 |  2767                 case WM_PSD_FULLPAGERECT: | 
 |  2768                 case WM_PSD_MINMARGINRECT: | 
 |  2769                 case WM_PSD_MARGINRECT: | 
 |  2770                 case WM_PSD_GREEKTEXTRECT: | 
 |  2771                 case WM_PSD_ENVSTAMPRECT: | 
 |  2772                 case WM_PSD_YAFULLPAGERECT: | 
 |  2773                         uRet = pT->OnDrawPage(uMsg, (HDC)wParam, (LPRECT)lParam)
      ; | 
 |  2774                         break; | 
 |  2775                 default: | 
 |  2776                         ATLTRACE2(atlTraceUI, 0, _T("CPageSetupDialogImpl::Paint
      HookProc - unknown message received\n")); | 
 |  2777                         break; | 
 |  2778                 } | 
 |  2779                 return uRet; | 
 |  2780         } | 
 |  2781  | 
 |  2782 // Overridables | 
 |  2783         UINT_PTR PreDrawPage(WORD /*wPaper*/, WORD /*wFlags*/, LPPAGESETUPDLG /*
      pPSD*/) | 
 |  2784         { | 
 |  2785                 // return 1 to prevent any more drawing | 
 |  2786                 return 0; | 
 |  2787         } | 
 |  2788  | 
 |  2789         UINT_PTR OnDrawPage(UINT /*uMsg*/, HDC /*hDC*/, LPRECT /*lpRect*/) | 
 |  2790         { | 
 |  2791                 return 0; // do the default | 
 |  2792         } | 
 |  2793 }; | 
 |  2794  | 
 |  2795 class CPageSetupDialog : public CPageSetupDialogImpl<CPageSetupDialog> | 
 |  2796 { | 
 |  2797 public: | 
 |  2798         CPageSetupDialog(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, 
      HWND hWndParent = NULL) | 
 |  2799                 : CPageSetupDialogImpl<CPageSetupDialog>(dwFlags, hWndParent) | 
 |  2800         { } | 
 |  2801  | 
 |  2802         // override PaintHookProc and references to handlers | 
 |  2803         static UINT_PTR CALLBACK PaintHookProc(HWND, UINT, WPARAM, LPARAM) | 
 |  2804         { | 
 |  2805                 return 0; | 
 |  2806         } | 
 |  2807 }; | 
 |  2808  | 
 |  2809 #endif // _WIN32_WCE | 
 |  2810  | 
 |  2811  | 
 |  2812 /////////////////////////////////////////////////////////////////////////////// | 
 |  2813 // CFindReplaceDialogImpl - Find/FindReplace modeless dialogs | 
 |  2814  | 
 |  2815 #ifndef _WIN32_WCE | 
 |  2816  | 
 |  2817 template <class T> | 
 |  2818 class ATL_NO_VTABLE CFindReplaceDialogImpl : public CCommonDialogImplBase | 
 |  2819 { | 
 |  2820 public: | 
 |  2821         enum { _cchFindReplaceBuffer = 128 }; | 
 |  2822  | 
 |  2823         FINDREPLACE m_fr; | 
 |  2824         TCHAR m_szFindWhat[_cchFindReplaceBuffer]; | 
 |  2825         TCHAR m_szReplaceWith[_cchFindReplaceBuffer]; | 
 |  2826  | 
 |  2827 // Constructors | 
 |  2828         CFindReplaceDialogImpl() | 
 |  2829         { | 
 |  2830                 memset(&m_fr, 0, sizeof(m_fr)); | 
 |  2831                 m_szFindWhat[0] = _T('\0'); | 
 |  2832                 m_szReplaceWith[0] = _T('\0'); | 
 |  2833  | 
 |  2834                 m_fr.lStructSize = sizeof(m_fr); | 
 |  2835                 m_fr.Flags = FR_ENABLEHOOK; | 
 |  2836                 m_fr.lpfnHook = (LPFRHOOKPROC)T::HookProc; | 
 |  2837                 m_fr.lpstrFindWhat = (LPTSTR)m_szFindWhat; | 
 |  2838                 m_fr.wFindWhatLen = _cchFindReplaceBuffer; | 
 |  2839                 m_fr.lpstrReplaceWith = (LPTSTR)m_szReplaceWith; | 
 |  2840                 m_fr.wReplaceWithLen = _cchFindReplaceBuffer; | 
 |  2841         } | 
 |  2842  | 
 |  2843         // Note: You must allocate the object on the heap. | 
 |  2844         //       If you do not, you must override OnFinalMessage() | 
 |  2845         virtual void OnFinalMessage(HWND /*hWnd*/) | 
 |  2846         { | 
 |  2847                 delete this; | 
 |  2848         } | 
 |  2849  | 
 |  2850         HWND Create(BOOL bFindDialogOnly, // TRUE for Find, FALSE for FindReplac
      e | 
 |  2851                         LPCTSTR lpszFindWhat, | 
 |  2852                         LPCTSTR lpszReplaceWith = NULL, | 
 |  2853                         DWORD dwFlags = FR_DOWN, | 
 |  2854                         HWND hWndParent = NULL) | 
 |  2855         { | 
 |  2856                 ATLASSERT((m_fr.Flags & FR_ENABLEHOOK) != 0); | 
 |  2857                 ATLASSERT(m_fr.lpfnHook != NULL); | 
 |  2858  | 
 |  2859                 m_fr.Flags |= dwFlags; | 
 |  2860  | 
 |  2861                 if(hWndParent == NULL) | 
 |  2862                         m_fr.hwndOwner = ::GetActiveWindow(); | 
 |  2863                 else | 
 |  2864                         m_fr.hwndOwner = hWndParent; | 
 |  2865                 ATLASSERT(m_fr.hwndOwner != NULL); // must have an owner for mod
      eless dialog | 
 |  2866  | 
 |  2867                 if(lpszFindWhat != NULL) | 
 |  2868                         SecureHelper::strncpy_x(m_szFindWhat, _countof(m_szFindW
      hat), lpszFindWhat, _TRUNCATE); | 
 |  2869  | 
 |  2870                 if(lpszReplaceWith != NULL) | 
 |  2871                         SecureHelper::strncpy_x(m_szReplaceWith, _countof(m_szRe
      placeWith), lpszReplaceWith, _TRUNCATE); | 
 |  2872  | 
 |  2873                 ATLASSERT(m_hWnd == NULL); | 
 |  2874                 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBa
      se*)this); | 
 |  2875  | 
 |  2876                 HWND hWnd = NULL; | 
 |  2877                 if(bFindDialogOnly) | 
 |  2878                         hWnd = ::FindText(&m_fr); | 
 |  2879                 else | 
 |  2880                         hWnd = ::ReplaceText(&m_fr); | 
 |  2881  | 
 |  2882                 ATLASSERT(m_hWnd == hWnd); | 
 |  2883                 return hWnd; | 
 |  2884         } | 
 |  2885  | 
 |  2886         static const UINT GetFindReplaceMsg() | 
 |  2887         { | 
 |  2888                 static const UINT nMsgFindReplace = ::RegisterWindowMessage(FIND
      MSGSTRING); | 
 |  2889                 return nMsgFindReplace; | 
 |  2890         } | 
 |  2891         // call while handling FINDMSGSTRING registered message | 
 |  2892         // to retreive the object | 
 |  2893         static T* PASCAL GetNotifier(LPARAM lParam) | 
 |  2894         { | 
 |  2895                 ATLASSERT(lParam != NULL); | 
 |  2896                 T* pDlg = (T*)(lParam - offsetof(T, m_fr)); | 
 |  2897                 return pDlg; | 
 |  2898         } | 
 |  2899  | 
 |  2900 // Operations | 
 |  2901         // Helpers for parsing information after successful return | 
 |  2902         LPCTSTR GetFindString() const    // get find string | 
 |  2903         { | 
 |  2904                 return (LPCTSTR)m_fr.lpstrFindWhat; | 
 |  2905         } | 
 |  2906  | 
 |  2907         LPCTSTR GetReplaceString() const // get replacement string | 
 |  2908         { | 
 |  2909                 return (LPCTSTR)m_fr.lpstrReplaceWith; | 
 |  2910         } | 
 |  2911  | 
 |  2912         BOOL SearchDown() const          // TRUE if search down, FALSE is up | 
 |  2913         { | 
 |  2914                 return ((m_fr.Flags & FR_DOWN) != 0) ? TRUE : FALSE; | 
 |  2915         } | 
 |  2916  | 
 |  2917         BOOL FindNext() const            // TRUE if command is find next | 
 |  2918         { | 
 |  2919                 return ((m_fr.Flags & FR_FINDNEXT) != 0) ? TRUE : FALSE; | 
 |  2920         } | 
 |  2921  | 
 |  2922         BOOL MatchCase() const           // TRUE if matching case | 
 |  2923         { | 
 |  2924                 return ((m_fr.Flags & FR_MATCHCASE) != 0) ? TRUE : FALSE; | 
 |  2925         } | 
 |  2926  | 
 |  2927         BOOL MatchWholeWord() const      // TRUE if matching whole words only | 
 |  2928         { | 
 |  2929                 return ((m_fr.Flags & FR_WHOLEWORD) != 0) ? TRUE : FALSE; | 
 |  2930         } | 
 |  2931  | 
 |  2932         BOOL ReplaceCurrent() const      // TRUE if replacing current string | 
 |  2933         { | 
 |  2934                 return ((m_fr. Flags & FR_REPLACE) != 0) ? TRUE : FALSE; | 
 |  2935         } | 
 |  2936  | 
 |  2937         BOOL ReplaceAll() const          // TRUE if replacing all occurrences | 
 |  2938         { | 
 |  2939                 return ((m_fr.Flags & FR_REPLACEALL) != 0) ? TRUE : FALSE; | 
 |  2940         } | 
 |  2941  | 
 |  2942         BOOL IsTerminating() const       // TRUE if terminating dialog | 
 |  2943         { | 
 |  2944                 return ((m_fr.Flags & FR_DIALOGTERM) != 0) ? TRUE : FALSE ; | 
 |  2945         } | 
 |  2946 }; | 
 |  2947  | 
 |  2948 class CFindReplaceDialog : public CFindReplaceDialogImpl<CFindReplaceDialog> | 
 |  2949 { | 
 |  2950 public: | 
 |  2951         DECLARE_EMPTY_MSG_MAP() | 
 |  2952 }; | 
 |  2953  | 
 |  2954 #endif // !_WIN32_WCE | 
 |  2955  | 
 |  2956  | 
 |  2957 #if (_ATL_VER >= 0x800) | 
 |  2958 typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX; | 
 |  2959 typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX; | 
 |  2960 #else // (_ATL_VER >= 0x800) | 
 |  2961 typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX; | 
 |  2962 #pragma pack(push, 4) | 
 |  2963 struct DLGITEMTEMPLATEEX | 
 |  2964 { | 
 |  2965         DWORD helpID; | 
 |  2966         DWORD exStyle; | 
 |  2967         DWORD style; | 
 |  2968         short x; | 
 |  2969         short y; | 
 |  2970         short cx; | 
 |  2971         short cy; | 
 |  2972         WORD id; | 
 |  2973 }; | 
 |  2974 #pragma pack(pop) | 
 |  2975 #endif // (_ATL_VER >= 0x800) | 
 |  2976  | 
 |  2977  | 
 |  2978 /////////////////////////////////////////////////////////////////////////////// | 
 |  2979 // CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX | 
 |  2980  | 
 |  2981 class CMemDlgTemplate | 
 |  2982 { | 
 |  2983 public: | 
 |  2984         enum StdCtrlType | 
 |  2985         { | 
 |  2986                 CTRL_BUTTON    = 0x0080, | 
 |  2987                 CTRL_EDIT      = 0x0081, | 
 |  2988                 CTRL_STATIC    = 0x0082, | 
 |  2989                 CTRL_LISTBOX   = 0x0083, | 
 |  2990                 CTRL_SCROLLBAR = 0x0084, | 
 |  2991                 CTRL_COMBOBOX  = 0x0085 | 
 |  2992         }; | 
 |  2993  | 
 |  2994         CMemDlgTemplate() : m_pData(NULL), m_pPtr(NULL), m_cAllocated(0) | 
 |  2995         { } | 
 |  2996  | 
 |  2997         ~CMemDlgTemplate() | 
 |  2998         { | 
 |  2999                 Reset(); | 
 |  3000         } | 
 |  3001  | 
 |  3002         bool IsValid() const | 
 |  3003         { | 
 |  3004                 return (m_pData != NULL); | 
 |  3005         } | 
 |  3006  | 
 |  3007         bool IsTemplateEx() const | 
 |  3008         { | 
 |  3009                 return (IsValid() && ((DLGTEMPLATEEX*)m_pData)->signature == 0xF
      FFF); | 
 |  3010         } | 
 |  3011  | 
 |  3012         LPDLGTEMPLATE GetTemplatePtr() | 
 |  3013         { | 
 |  3014                 return reinterpret_cast<LPDLGTEMPLATE>(m_pData); | 
 |  3015         } | 
 |  3016  | 
 |  3017         DLGTEMPLATEEX* GetTemplateExPtr() | 
 |  3018         { | 
 |  3019                 return reinterpret_cast<DLGTEMPLATEEX*>(m_pData); | 
 |  3020         } | 
 |  3021  | 
 |  3022         void Reset() | 
 |  3023         { | 
 |  3024                 if (IsValid()) | 
 |  3025                         ATLVERIFY(::GlobalFree(m_pData) == NULL); | 
 |  3026  | 
 |  3027                 m_pData = NULL; | 
 |  3028                 m_pPtr = NULL; | 
 |  3029                 m_cAllocated = 0; | 
 |  3030         } | 
 |  3031  | 
 |  3032         void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short 
      nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0,  | 
 |  3033                     LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeig
      ht = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0, | 
 |  3034                                 ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRIN
      GorID Menu = 0U) | 
 |  3035         { | 
 |  3036                 // Should have DS_SETFONT style to set the dialog font name and 
      size | 
 |  3037                 if (lpstrFontName != NULL) | 
 |  3038                 { | 
 |  3039                         dwStyle |= DS_SETFONT; | 
 |  3040                 } | 
 |  3041                 else | 
 |  3042                 { | 
 |  3043                         dwStyle &= ~DS_SETFONT; | 
 |  3044                 } | 
 |  3045  | 
 |  3046                 if (bDlgEx) | 
 |  3047                 { | 
 |  3048                         DLGTEMPLATEEX dlg = {1, 0xFFFF, dwHelpID, dwExStyle, dwS
      tyle, 0, nX, nY, nWidth, nHeight}; | 
 |  3049                         AddData(&dlg, sizeof(dlg)); | 
 |  3050                 } | 
 |  3051                 else | 
 |  3052                 { | 
 |  3053                         DLGTEMPLATE dlg = {dwStyle, dwExStyle, 0, nX, nY, nWidth
      , nHeight}; | 
 |  3054                         AddData(&dlg, sizeof(dlg)); | 
 |  3055                 } | 
 |  3056  | 
 |  3057 #ifndef _WIN32_WCE | 
 |  3058                 if (Menu.m_lpstr == NULL) | 
 |  3059                 { | 
 |  3060                         WORD menuData = 0; | 
 |  3061                         AddData(&menuData, sizeof(WORD)); | 
 |  3062                 } | 
 |  3063                 else if (IS_INTRESOURCE(Menu.m_lpstr)) | 
 |  3064                 { | 
 |  3065                         WORD menuData[] = {0xFFFF, (WORD)Menu.m_lpstr}; | 
 |  3066                         AddData(menuData, sizeof(menuData)); | 
 |  3067                 } | 
 |  3068                 else | 
 |  3069                 { | 
 |  3070                         AddString(Menu.m_lpstr); | 
 |  3071                 } | 
 |  3072 #else // _WIN32_WCE | 
 |  3073                 // Windows CE doesn't support the addition of menus to a dialog 
      box | 
 |  3074                 ATLASSERT(Menu.m_lpstr == NULL); | 
 |  3075                 Menu.m_lpstr;   // avoid level 4 warning | 
 |  3076                 WORD menuData = 0; | 
 |  3077                 AddData(&menuData, sizeof(WORD)); | 
 |  3078 #endif // _WIN32_WCE | 
 |  3079  | 
 |  3080                 if (ClassName.m_lpstr == NULL) | 
 |  3081                 { | 
 |  3082                         WORD classData = 0; | 
 |  3083                         AddData(&classData, sizeof(WORD)); | 
 |  3084                 } | 
 |  3085                 else if (IS_INTRESOURCE(ClassName.m_lpstr)) | 
 |  3086                 { | 
 |  3087                         WORD classData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; | 
 |  3088                         AddData(classData, sizeof(classData)); | 
 |  3089                 } | 
 |  3090                 else | 
 |  3091                 { | 
 |  3092                         AddString(ClassName.m_lpstr); | 
 |  3093                 } | 
 |  3094  | 
 |  3095                 // Set dialog caption | 
 |  3096                 AddString(lpszCaption); | 
 |  3097  | 
 |  3098                 if (lpstrFontName != NULL) | 
 |  3099                 { | 
 |  3100                         AddData(&wFontSize, sizeof(wFontSize)); | 
 |  3101  | 
 |  3102                         if (bDlgEx) | 
 |  3103                         { | 
 |  3104                                 AddData(&wWeight, sizeof(wWeight)); | 
 |  3105                                 AddData(&bItalic, sizeof(bItalic)); | 
 |  3106                                 AddData(&bCharset, sizeof(bCharset)); | 
 |  3107                         } | 
 |  3108  | 
 |  3109                         AddString(lpstrFontName); | 
 |  3110                 } | 
 |  3111         } | 
 |  3112  | 
 |  3113         void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short 
      nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle, | 
 |  3114                         ATL::_U_STRINGorID Text, const WORD* pCreationData = NUL
      L, WORD nCreationData = 0, DWORD dwHelpID = 0) | 
 |  3115         { | 
 |  3116                 ATLASSERT(IsValid()); | 
 |  3117  | 
 |  3118                 // DWORD align data | 
 |  3119                 m_pPtr = (LPBYTE)(DWORD_PTR)((DWORD)(DWORD_PTR)(m_pPtr + 3) & (~
      3)); | 
 |  3120  | 
 |  3121                 if (IsTemplateEx()) | 
 |  3122                 { | 
 |  3123                         DLGTEMPLATEEX* dlg = (DLGTEMPLATEEX*)m_pData; | 
 |  3124                         dlg->cDlgItems++; | 
 |  3125  | 
 |  3126                         DLGITEMTEMPLATEEX item = {dwHelpID, ATL::CControlWinTrai
      ts::GetWndExStyle(0) | dwExStyle, ATL::CControlWinTraits::GetWndStyle(0) | dwSty
      le, nX, nY, nWidth, nHeight, wId}; | 
 |  3127                         AddData(&item, sizeof(item)); | 
 |  3128                 } | 
 |  3129                 else | 
 |  3130                 { | 
 |  3131                         LPDLGTEMPLATE dlg = (LPDLGTEMPLATE)m_pData; | 
 |  3132                         dlg->cdit++; | 
 |  3133  | 
 |  3134                         DLGITEMTEMPLATE item = {ATL::CControlWinTraits::GetWndSt
      yle(0) | dwStyle, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, nX, nY, 
      nWidth, nHeight, wId}; | 
 |  3135                         AddData(&item, sizeof(item)); | 
 |  3136                 } | 
 |  3137  | 
 |  3138                 ATLASSERT(ClassName.m_lpstr != NULL); | 
 |  3139                 if (IS_INTRESOURCE(ClassName.m_lpstr)) | 
 |  3140                 { | 
 |  3141                         WORD wData[] = {0xFFFF, (WORD)ClassName.m_lpstr}; | 
 |  3142                         AddData(wData, sizeof(wData)); | 
 |  3143                 } | 
 |  3144                 else | 
 |  3145                 { | 
 |  3146                         AddString(ClassName.m_lpstr); | 
 |  3147                 } | 
 |  3148  | 
 |  3149                 if (Text.m_lpstr == NULL) | 
 |  3150                 { | 
 |  3151                         WORD classData = 0; | 
 |  3152                         AddData(&classData, sizeof(WORD)); | 
 |  3153                 } | 
 |  3154                 else if (IS_INTRESOURCE(Text.m_lpstr)) | 
 |  3155                 { | 
 |  3156                         WORD wData[] = {0xFFFF, (WORD)Text.m_lpstr}; | 
 |  3157                         AddData(wData, sizeof(wData)); | 
 |  3158                 } | 
 |  3159                 else | 
 |  3160                 { | 
 |  3161                         AddString(Text.m_lpstr); | 
 |  3162                 } | 
 |  3163  | 
 |  3164                 AddData(&nCreationData, sizeof(nCreationData)); | 
 |  3165  | 
 |  3166                 if ((nCreationData != 0)) | 
 |  3167                 { | 
 |  3168                         ATLASSERT(pCreationData != NULL); | 
 |  3169                         AddData(pCreationData, nCreationData * sizeof(WORD)); | 
 |  3170                 } | 
 |  3171         } | 
 |  3172  | 
 |  3173         void AddStdControl(StdCtrlType CtrlType, WORD wId, short nX, short nY, s
      hort nWidth, short nHeight, | 
 |  3174                            DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Te
      xt, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0
      ) | 
 |  3175         { | 
 |  3176                 AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwEx
      Style, Text, pCreationData, nCreationData, dwHelpID); | 
 |  3177         } | 
 |  3178  | 
 |  3179 protected: | 
 |  3180         void AddData(LPCVOID pData, size_t nData) | 
 |  3181         { | 
 |  3182                 ATLASSERT(pData != NULL); | 
 |  3183  | 
 |  3184                 const size_t ALLOCATION_INCREMENT = 1024; | 
 |  3185  | 
 |  3186                 if (m_pData == NULL) | 
 |  3187                 { | 
 |  3188                         m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * AL
      LOCATION_INCREMENT; | 
 |  3189                         m_pPtr = m_pData = static_cast<LPBYTE>(::GlobalAlloc(GPT
      R, m_cAllocated)); | 
 |  3190                         ATLASSERT(m_pData != NULL); | 
 |  3191                 } | 
 |  3192                 else if (((m_pPtr - m_pData) + nData) > m_cAllocated) | 
 |  3193                 { | 
 |  3194                         size_t ptrPos = (m_pPtr - m_pData); | 
 |  3195                         m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * A
      LLOCATION_INCREMENT; | 
 |  3196                         m_pData = static_cast<LPBYTE>(::GlobalReAlloc(m_pData, m
      _cAllocated, 0)); | 
 |  3197                         ATLASSERT(m_pData != NULL); | 
 |  3198                         m_pPtr = m_pData + ptrPos; | 
 |  3199                 } | 
 |  3200  | 
 |  3201                 SecureHelper::memcpy_x(m_pPtr, m_cAllocated - (m_pPtr - m_pData)
      , pData, nData); | 
 |  3202  | 
 |  3203                 m_pPtr += nData; | 
 |  3204         } | 
 |  3205  | 
 |  3206         void AddString(LPCTSTR lpszStr) | 
 |  3207         { | 
 |  3208                 if (lpszStr == NULL) | 
 |  3209                 { | 
 |  3210                         WCHAR szEmpty = 0; | 
 |  3211                         AddData(&szEmpty, sizeof(szEmpty)); | 
 |  3212                 } | 
 |  3213                 else | 
 |  3214                 { | 
 |  3215                         USES_CONVERSION; | 
 |  3216                         LPCWSTR lpstr = T2CW(lpszStr); | 
 |  3217                         int nSize = lstrlenW(lpstr) + 1; | 
 |  3218                         AddData(lpstr, nSize * sizeof(WCHAR)); | 
 |  3219                 } | 
 |  3220         } | 
 |  3221  | 
 |  3222         LPBYTE m_pData; | 
 |  3223         LPBYTE m_pPtr; | 
 |  3224         SIZE_T m_cAllocated; | 
 |  3225 }; | 
 |  3226  | 
 |  3227  | 
 |  3228 /////////////////////////////////////////////////////////////////////////////// | 
 |  3229 // Dialog and control macros for indirect dialogs | 
 |  3230  | 
 |  3231 // for DLGTEMPLATE | 
 |  3232 #define BEGIN_DIALOG(x, y, width, height) \ | 
 |  3233         void DoInitTemplate() \ | 
 |  3234         { \ | 
 |  3235                 bool bExTemplate = false; \ | 
 |  3236                 short nX = x, nY = y, nWidth = width, nHeight = height; \ | 
 |  3237                 LPCTSTR szCaption = NULL; \ | 
 |  3238                 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ | 
 |  3239                 DWORD dwExStyle = 0; \ | 
 |  3240                 LPCTSTR szFontName = NULL; \ | 
 |  3241                 WORD wFontSize = 0; \ | 
 |  3242                 WORD wWeight = 0; \ | 
 |  3243                 BYTE bItalic = 0; \ | 
 |  3244                 BYTE bCharset = 0; \ | 
 |  3245                 DWORD dwHelpID = 0; \ | 
 |  3246                 ATL::_U_STRINGorID Menu = 0U; \ | 
 |  3247                 ATL::_U_STRINGorID ClassName = 0U; | 
 |  3248  | 
 |  3249 // for DLGTEMPLATEEX | 
 |  3250 #define BEGIN_DIALOG_EX(x, y, width, height, helpID) \ | 
 |  3251         void DoInitTemplate() \ | 
 |  3252         { \ | 
 |  3253                 bool bExTemplate = true; \ | 
 |  3254                 short nX = x, nY = y, nWidth = width, nHeight = height; \ | 
 |  3255                 LPCTSTR szCaption = NULL; \ | 
 |  3256                 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \ | 
 |  3257                 DWORD dwExStyle = 0; \ | 
 |  3258                 LPCTSTR szFontName = NULL; \ | 
 |  3259                 WORD wFontSize = 0; \ | 
 |  3260                 WORD wWeight = 0; \ | 
 |  3261                 BYTE bItalic = 0; \ | 
 |  3262                 BYTE bCharset = 0; \ | 
 |  3263                 DWORD dwHelpID = helpID; \ | 
 |  3264                 ATL::_U_STRINGorID Menu = 0U; \ | 
 |  3265                 ATL::_U_STRINGorID ClassName = 0U; | 
 |  3266  | 
 |  3267 #define END_DIALOG() \ | 
 |  3268                 m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeigh
      t, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelp
      ID, ClassName, Menu); \ | 
 |  3269         }; | 
 |  3270  | 
 |  3271 #define DIALOG_CAPTION(caption) \ | 
 |  3272                 szCaption = caption; | 
 |  3273 #define DIALOG_STYLE(style) \ | 
 |  3274                 dwStyle = style; | 
 |  3275 #define DIALOG_EXSTYLE(exStyle) \ | 
 |  3276                 dwExStyle = exStyle; | 
 |  3277 #define DIALOG_FONT(pointSize, typeFace) \ | 
 |  3278                 wFontSize = pointSize; \ | 
 |  3279                 szFontName = typeFace; | 
 |  3280 #define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \ | 
 |  3281                 ATLASSERT(bExTemplate); \ | 
 |  3282                 wFontSize = pointsize; \ | 
 |  3283                 szFontName = typeface; \ | 
 |  3284                 wWeight = weight; \ | 
 |  3285                 bItalic = italic; \ | 
 |  3286                 bCharset = charset; | 
 |  3287 #define DIALOG_MENU(menuName) \ | 
 |  3288                 Menu = menuName; | 
 |  3289 #define DIALOG_CLASS(className) \ | 
 |  3290                 ClassName = className; | 
 |  3291  | 
 |  3292 #define BEGIN_CONTROLS_MAP() \ | 
 |  3293         void DoInitControls() \ | 
 |  3294         { | 
 |  3295  | 
 |  3296 #define END_CONTROLS_MAP() \ | 
 |  3297         }; | 
 |  3298  | 
 |  3299  | 
 |  3300 #define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \ | 
 |  3301         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x,
       y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0); | 
 |  3302 #define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \ | 
 |  3303         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x,
       y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0); | 
 |  3304 #define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \ | 
 |  3305         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x,
       y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0); | 
 |  3306 #define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ | 
 |  3307         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3308 #define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \ | 
 |  3309         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0
      ); | 
 |  3310 #ifndef _WIN32_WCE | 
 |  3311 #define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \ | 
 |  3312         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3313 #endif // !_WIN32_WCE | 
 |  3314 #define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \ | 
 |  3315         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3316 #define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \ | 
 |  3317         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3318 #define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \ | 
 |  3319         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3320 #define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \ | 
 |  3321         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0)
      ; | 
 |  3322 #define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ | 
 |  3323         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0); | 
 |  3324 #define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \ | 
 |  3325         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL,
       0); | 
 |  3326 #define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \ | 
 |  3327         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_COMBOBOX, (WORD)id, 
      x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, 
      NULL, 0); | 
 |  3328 #define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \ | 
 |  3329         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_EDIT, (WORD)id, x, y
      , width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NUL
      L, NULL, 0); | 
 |  3330 #define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \ | 
 |  3331         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x,
       y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0); | 
 |  3332 #define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \ | 
 |  3333         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_LISTBOX, (WORD)id, x
      , y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL
      , 0); | 
 |  3334 #define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \ | 
 |  3335         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_SCROLLBAR, (WORD)id,
       x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0); | 
 |  3336 #define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \ | 
 |  3337         m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x,
       y, width, height, style | SS_ICON, exStyle, text, NULL, 0); | 
 |  3338 #define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle
      ) \ | 
 |  3339         m_Template.AddControl(className, (WORD)id, x, y, width, height, style, e
      xStyle, text, NULL, 0); | 
 |  3340  | 
 |  3341  | 
 |  3342 /////////////////////////////////////////////////////////////////////////////// | 
 |  3343 // CIndirectDialogImpl - dialogs with template in memory | 
 |  3344  | 
 |  3345 template <class T, class TDlgTemplate = CMemDlgTemplate, class TBase = ATL::CDia
      logImpl<T, ATL::CWindow> > | 
 |  3346 class ATL_NO_VTABLE CIndirectDialogImpl : public TBase | 
 |  3347 { | 
 |  3348 public: | 
 |  3349         enum { IDD = 0 };   // no dialog template resource | 
 |  3350  | 
 |  3351         TDlgTemplate m_Template; | 
 |  3352  | 
 |  3353         void CreateTemplate() | 
 |  3354         { | 
 |  3355                 T* pT = static_cast<T*>(this); | 
 |  3356                 pT->DoInitTemplate(); | 
 |  3357                 pT->DoInitControls(); | 
 |  3358         } | 
 |  3359  | 
 |  3360         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitPara
      m = NULL) | 
 |  3361         { | 
 |  3362                 T* pT = static_cast<T*>(this); | 
 |  3363                 ATLASSERT(pT->m_hWnd == NULL); | 
 |  3364  | 
 |  3365                 if (!m_Template.IsValid()) | 
 |  3366                         CreateTemplate(); | 
 |  3367  | 
 |  3368 #if (_ATL_VER >= 0x0800) | 
 |  3369                 // Allocate the thunk structure here, where we can fail graceful
      ly. | 
 |  3370                 BOOL result = m_thunk.Init(NULL, NULL); | 
 |  3371                 if (result == FALSE) | 
 |  3372                 { | 
 |  3373                         SetLastError(ERROR_OUTOFMEMORY); | 
 |  3374                         return -1; | 
 |  3375                 } | 
 |  3376 #endif // (_ATL_VER >= 0x0800) | 
 |  3377  | 
 |  3378                 ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); | 
 |  3379  | 
 |  3380 #ifdef _DEBUG | 
 |  3381                 m_bModal = true; | 
 |  3382 #endif // _DEBUG | 
 |  3383  | 
 |  3384                 return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstanc
      e(), m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwIni
      tParam); | 
 |  3385         } | 
 |  3386  | 
 |  3387         HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL) | 
 |  3388         { | 
 |  3389                 T* pT = static_cast<T*>(this); | 
 |  3390                 ATLASSERT(pT->m_hWnd == NULL); | 
 |  3391  | 
 |  3392                 if (!m_Template.IsValid()) | 
 |  3393                         CreateTemplate(); | 
 |  3394  | 
 |  3395 #if (_ATL_VER >= 0x0800) | 
 |  3396                 // Allocate the thunk structure here, where we can fail graceful
      ly. | 
 |  3397                 BOOL result = m_thunk.Init(NULL, NULL); | 
 |  3398                 if (result == FALSE)  | 
 |  3399                 { | 
 |  3400                         SetLastError(ERROR_OUTOFMEMORY); | 
 |  3401                         return NULL; | 
 |  3402                 } | 
 |  3403 #endif // (_ATL_VER >= 0x0800) | 
 |  3404  | 
 |  3405                 ModuleHelper::AddCreateWndData(&m_thunk.cd, pT); | 
 |  3406  | 
 |  3407 #ifdef _DEBUG | 
 |  3408                 m_bModal = false; | 
 |  3409 #endif // _DEBUG | 
 |  3410  | 
 |  3411                 HWND hWnd = ::CreateDialogIndirectParam(ModuleHelper::GetResourc
      eInstance(), (LPCDLGTEMPLATE)m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T
      ::StartDialogProc, dwInitParam); | 
 |  3412                 ATLASSERT(m_hWnd == hWnd); | 
 |  3413  | 
 |  3414                 return hWnd; | 
 |  3415         } | 
 |  3416  | 
 |  3417         // for CComControl | 
 |  3418         HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL) | 
 |  3419         { | 
 |  3420                 return Create(hWndParent, dwInitParam); | 
 |  3421         } | 
 |  3422  | 
 |  3423         void DoInitTemplate()  | 
 |  3424         { | 
 |  3425                 ATLASSERT(FALSE);   // MUST be defined in derived class | 
 |  3426         } | 
 |  3427  | 
 |  3428         void DoInitControls()  | 
 |  3429         { | 
 |  3430                 ATLASSERT(FALSE);   // MUST be defined in derived class | 
 |  3431         } | 
 |  3432 }; | 
 |  3433  | 
 |  3434 /////////////////////////////////////////////////////////////////////////////// | 
 |  3435 // CPropertySheetWindow - client side for a property sheet | 
 |  3436  | 
 |  3437 class CPropertySheetWindow : public ATL::CWindow | 
 |  3438 { | 
 |  3439 public: | 
 |  3440 // Constructors | 
 |  3441         CPropertySheetWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) | 
 |  3442         { } | 
 |  3443  | 
 |  3444         CPropertySheetWindow& operator =(HWND hWnd) | 
 |  3445         { | 
 |  3446                 m_hWnd = hWnd; | 
 |  3447                 return *this; | 
 |  3448         } | 
 |  3449  | 
 |  3450 // Attributes | 
 |  3451         int GetPageCount() const | 
 |  3452         { | 
 |  3453                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3454                 HWND hWndTabCtrl = GetTabControl(); | 
 |  3455                 ATLASSERT(hWndTabCtrl != NULL); | 
 |  3456                 return (int)::SendMessage(hWndTabCtrl, TCM_GETITEMCOUNT, 0, 0L); | 
 |  3457         } | 
 |  3458  | 
 |  3459         HWND GetActivePage() const | 
 |  3460         { | 
 |  3461                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3462                 return (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0L
      ); | 
 |  3463         } | 
 |  3464  | 
 |  3465         int GetActiveIndex() const | 
 |  3466         { | 
 |  3467                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3468                 HWND hWndTabCtrl = GetTabControl(); | 
 |  3469                 ATLASSERT(hWndTabCtrl != NULL); | 
 |  3470                 return (int)::SendMessage(hWndTabCtrl, TCM_GETCURSEL, 0, 0L); | 
 |  3471         } | 
 |  3472  | 
 |  3473         BOOL SetActivePage(int nPageIndex) | 
 |  3474         { | 
 |  3475                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3476                 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, nPageIndex, 0L
      ); | 
 |  3477         } | 
 |  3478  | 
 |  3479         BOOL SetActivePage(HPROPSHEETPAGE hPage) | 
 |  3480         { | 
 |  3481                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3482                 ATLASSERT(hPage != NULL); | 
 |  3483                 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, 0, (LPARAM)hPa
      ge); | 
 |  3484         } | 
 |  3485  | 
 |  3486         BOOL SetActivePageByID(int nPageID) | 
 |  3487         { | 
 |  3488                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3489                 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSELID, 0, nPageID); | 
 |  3490         } | 
 |  3491  | 
 |  3492         void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) | 
 |  3493         { | 
 |  3494                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3495                 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE
       is valid | 
 |  3496                 ATLASSERT(lpszText != NULL); | 
 |  3497                 ::SendMessage(m_hWnd, PSM_SETTITLE, nStyle, (LPARAM)lpszText); | 
 |  3498         } | 
 |  3499  | 
 |  3500         HWND GetTabControl() const | 
 |  3501         { | 
 |  3502                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3503                 return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0L); | 
 |  3504         } | 
 |  3505  | 
 |  3506         void SetFinishText(LPCTSTR lpszText) | 
 |  3507         { | 
 |  3508                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3509                 ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText); | 
 |  3510         } | 
 |  3511  | 
 |  3512         void SetWizardButtons(DWORD dwFlags) | 
 |  3513         { | 
 |  3514                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3515                 ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags); | 
 |  3516         } | 
 |  3517  | 
 |  3518 // Operations | 
 |  3519         BOOL AddPage(HPROPSHEETPAGE hPage) | 
 |  3520         { | 
 |  3521                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3522                 ATLASSERT(hPage != NULL); | 
 |  3523                 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage
      ); | 
 |  3524         } | 
 |  3525  | 
 |  3526         BOOL AddPage(LPCPROPSHEETPAGE pPage) | 
 |  3527         { | 
 |  3528                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3529                 ATLASSERT(pPage != NULL); | 
 |  3530                 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); | 
 |  3531                 if(hPage == NULL) | 
 |  3532                         return FALSE; | 
 |  3533                 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage
      ); | 
 |  3534         } | 
 |  3535  | 
 |  3536 #ifndef _WIN32_WCE | 
 |  3537         BOOL InsertPage(int nNewPageIndex, HPROPSHEETPAGE hPage) | 
 |  3538         { | 
 |  3539                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3540                 ATLASSERT(hPage != NULL); | 
 |  3541                 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex
      , (LPARAM)hPage); | 
 |  3542         } | 
 |  3543  | 
 |  3544         BOOL InsertPage(int nNewPageIndex, LPCPROPSHEETPAGE pPage) | 
 |  3545         { | 
 |  3546                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3547                 ATLASSERT(pPage != NULL); | 
 |  3548                 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); | 
 |  3549                 if(hPage == NULL) | 
 |  3550                         return FALSE; | 
 |  3551                 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex
      , (LPARAM)hPage); | 
 |  3552         } | 
 |  3553  | 
 |  3554         BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, HPROPSHEETPAGE hPage) | 
 |  3555         { | 
 |  3556                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3557                 ATLASSERT(hPage != NULL); | 
 |  3558                 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPage
      InsertAfter, (LPARAM)hPage); | 
 |  3559         } | 
 |  3560  | 
 |  3561         BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, LPCPROPSHEETPAGE pPage) | 
 |  3562         { | 
 |  3563                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3564                 ATLASSERT(pPage != NULL); | 
 |  3565                 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); | 
 |  3566                 if(hPage == NULL) | 
 |  3567                         return FALSE; | 
 |  3568                 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPage
      InsertAfter, (LPARAM)hPage); | 
 |  3569         } | 
 |  3570 #endif // !_WIN32_WCE | 
 |  3571  | 
 |  3572         void RemovePage(int nPageIndex) | 
 |  3573         { | 
 |  3574                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3575                 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, nPageIndex, 0L); | 
 |  3576         } | 
 |  3577  | 
 |  3578         void RemovePage(HPROPSHEETPAGE hPage) | 
 |  3579         { | 
 |  3580                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3581                 ATLASSERT(hPage != NULL); | 
 |  3582                 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, 0, (LPARAM)hPage); | 
 |  3583         } | 
 |  3584  | 
 |  3585         BOOL PressButton(int nButton) | 
 |  3586         { | 
 |  3587                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3588                 return (BOOL)::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0L)
      ; | 
 |  3589         } | 
 |  3590  | 
 |  3591         BOOL Apply() | 
 |  3592         { | 
 |  3593                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3594                 return (BOOL)::SendMessage(m_hWnd, PSM_APPLY, 0, 0L); | 
 |  3595         } | 
 |  3596  | 
 |  3597         void CancelToClose() | 
 |  3598         { | 
 |  3599                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3600                 ::SendMessage(m_hWnd, PSM_CANCELTOCLOSE, 0, 0L); | 
 |  3601         } | 
 |  3602  | 
 |  3603         void SetModified(HWND hWndPage, BOOL bChanged = TRUE) | 
 |  3604         { | 
 |  3605                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3606                 ATLASSERT(::IsWindow(hWndPage)); | 
 |  3607                 UINT uMsg = bChanged ? PSM_CHANGED : PSM_UNCHANGED; | 
 |  3608                 ::SendMessage(m_hWnd, uMsg, (WPARAM)hWndPage, 0L); | 
 |  3609         } | 
 |  3610  | 
 |  3611         LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) | 
 |  3612         { | 
 |  3613                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3614                 return ::SendMessage(m_hWnd, PSM_QUERYSIBLINGS, wParam, lParam); | 
 |  3615         } | 
 |  3616  | 
 |  3617         void RebootSystem() | 
 |  3618         { | 
 |  3619                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3620                 ::SendMessage(m_hWnd, PSM_REBOOTSYSTEM, 0, 0L); | 
 |  3621         } | 
 |  3622  | 
 |  3623         void RestartWindows() | 
 |  3624         { | 
 |  3625                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3626                 ::SendMessage(m_hWnd, PSM_RESTARTWINDOWS, 0, 0L); | 
 |  3627         } | 
 |  3628  | 
 |  3629         BOOL IsDialogMessage(LPMSG lpMsg) | 
 |  3630         { | 
 |  3631                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3632                 return (BOOL)::SendMessage(m_hWnd, PSM_ISDIALOGMESSAGE, 0, (LPAR
      AM)lpMsg); | 
 |  3633         } | 
 |  3634  | 
 |  3635 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  3636         int HwndToIndex(HWND hWnd) const | 
 |  3637         { | 
 |  3638                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3639                 return (int)::SendMessage(m_hWnd, PSM_HWNDTOINDEX, (WPARAM)hWnd,
       0L); | 
 |  3640         } | 
 |  3641  | 
 |  3642         HWND IndexToHwnd(int nIndex) const | 
 |  3643         { | 
 |  3644                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3645                 return (HWND)::SendMessage(m_hWnd, PSM_INDEXTOHWND, nIndex, 0L); | 
 |  3646         } | 
 |  3647  | 
 |  3648         int PageToIndex(HPROPSHEETPAGE hPage) const | 
 |  3649         { | 
 |  3650                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3651                 return (int)::SendMessage(m_hWnd, PSM_PAGETOINDEX, 0, (LPARAM)hP
      age); | 
 |  3652         } | 
 |  3653  | 
 |  3654         HPROPSHEETPAGE IndexToPage(int nIndex) const | 
 |  3655         { | 
 |  3656                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3657                 return (HPROPSHEETPAGE)::SendMessage(m_hWnd, PSM_INDEXTOPAGE, nI
      ndex, 0L); | 
 |  3658         } | 
 |  3659  | 
 |  3660         int IdToIndex(int nID) const | 
 |  3661         { | 
 |  3662                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3663                 return (int)::SendMessage(m_hWnd, PSM_IDTOINDEX, 0, nID); | 
 |  3664         } | 
 |  3665  | 
 |  3666         int IndexToId(int nIndex) const | 
 |  3667         { | 
 |  3668                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3669                 return (int)::SendMessage(m_hWnd, PSM_INDEXTOID, nIndex, 0L); | 
 |  3670         } | 
 |  3671  | 
 |  3672         int GetResult() const | 
 |  3673         { | 
 |  3674                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3675                 return (int)::SendMessage(m_hWnd, PSM_GETRESULT, 0, 0L); | 
 |  3676         } | 
 |  3677  | 
 |  3678         BOOL RecalcPageSizes() | 
 |  3679         { | 
 |  3680                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3681                 return (BOOL)::SendMessage(m_hWnd, PSM_RECALCPAGESIZES, 0, 0L); | 
 |  3682         } | 
 |  3683  | 
 |  3684         void SetHeaderTitle(int nIndex, LPCTSTR lpstrHeaderTitle) | 
 |  3685         { | 
 |  3686                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3687                 ::SendMessage(m_hWnd, PSM_SETHEADERTITLE, nIndex, (LPARAM)lpstrH
      eaderTitle); | 
 |  3688         } | 
 |  3689  | 
 |  3690         void SetHeaderSubTitle(int nIndex, LPCTSTR lpstrHeaderSubTitle) | 
 |  3691         { | 
 |  3692                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  3693                 ::SendMessage(m_hWnd, PSM_SETHEADERSUBTITLE, nIndex, (LPARAM)lps
      trHeaderSubTitle); | 
 |  3694         } | 
 |  3695 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  3696  | 
 |  3697 // Implementation - override to prevent usage | 
 |  3698         HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 
      0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) | 
 |  3699         { | 
 |  3700                 ATLASSERT(FALSE); | 
 |  3701                 return NULL; | 
 |  3702         } | 
 |  3703 }; | 
 |  3704  | 
 |  3705 /////////////////////////////////////////////////////////////////////////////// | 
 |  3706 // CPropertySheetImpl - implements a property sheet | 
 |  3707  | 
 |  3708 template <class T, class TBase = CPropertySheetWindow> | 
 |  3709 class ATL_NO_VTABLE CPropertySheetImpl : public ATL::CWindowImplBaseT< TBase > | 
 |  3710 { | 
 |  3711 public: | 
 |  3712         PROPSHEETHEADER m_psh; | 
 |  3713         ATL::CSimpleArray<HPROPSHEETPAGE> m_arrPages; | 
 |  3714  | 
 |  3715 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific | 
 |  3716   #ifndef PROPSHEET_LINK_SIZE | 
 |  3717         #define PROPSHEET_LINK_SIZE 128 | 
 |  3718   #endif // PROPSHEET_LINK_SIZE | 
 |  3719         TCHAR m_szLink[PROPSHEET_LINK_SIZE]; | 
 |  3720         static LPCTSTR m_pszTitle; | 
 |  3721         static LPCTSTR m_pszLink; | 
 |  3722 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)  | 
 |  3723  | 
 |  3724 // Construction/Destruction | 
 |  3725         CPropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStart
      Page = 0, HWND hWndParent = NULL) | 
 |  3726         { | 
 |  3727                 memset(&m_psh, 0, sizeof(PROPSHEETHEADER)); | 
 |  3728                 m_psh.dwSize = sizeof(PROPSHEETHEADER); | 
 |  3729                 m_psh.dwFlags = PSH_USECALLBACK; | 
 |  3730                 m_psh.hInstance = ModuleHelper::GetResourceInstance(); | 
 |  3731                 m_psh.phpage = NULL;   // will be set later | 
 |  3732                 m_psh.nPages = 0;      // will be set later | 
 |  3733                 m_psh.pszCaption = title.m_lpstr; | 
 |  3734                 m_psh.nStartPage = uStartPage; | 
 |  3735                 m_psh.hwndParent = hWndParent;   // if NULL, will be set in DoMo
      dal/Create | 
 |  3736                 m_psh.pfnCallback = T::PropSheetCallback; | 
 |  3737  | 
 |  3738 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific  | 
 |  3739                 m_psh.dwFlags |= PSH_MAXIMIZE; | 
 |  3740                 m_szLink[0] = 0; | 
 |  3741 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) | 
 |  3742         } | 
 |  3743  | 
 |  3744         ~CPropertySheetImpl() | 
 |  3745         { | 
 |  3746                 if(m_arrPages.GetSize() > 0)   // sheet never created, destroy a
      ll pages | 
 |  3747                 { | 
 |  3748                         for(int i = 0; i < m_arrPages.GetSize(); i++) | 
 |  3749                                 ::DestroyPropertySheetPage((HPROPSHEETPAGE)m_arr
      Pages[i]); | 
 |  3750                 } | 
 |  3751         } | 
 |  3752  | 
 |  3753 // Callback function and overrideables | 
 |  3754         static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lPara
      m) | 
 |  3755         { | 
 |  3756                 lParam;   // avoid level 4 warning | 
 |  3757                 int nRet = 0; | 
 |  3758  | 
 |  3759                 if(uMsg == PSCB_INITIALIZED) | 
 |  3760                 { | 
 |  3761                         ATLASSERT(hWnd != NULL); | 
 |  3762                         T* pT = (T*)ModuleHelper::ExtractCreateWndData(); | 
 |  3763                         // subclass the sheet window | 
 |  3764                         pT->SubclassWindow(hWnd); | 
 |  3765                         // remove page handles array | 
 |  3766                         pT->_CleanUpPages(); | 
 |  3767  | 
 |  3768 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific | 
 |  3769                         m_pszTitle = pT->m_psh.pszCaption; | 
 |  3770                         if(*pT->m_szLink != 0) | 
 |  3771                                 m_pszLink = pT->m_szLink; | 
 |  3772 #endif  // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific | 
 |  3773  | 
 |  3774                         pT->OnSheetInitialized(); | 
 |  3775                 } | 
 |  3776 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg | 
 |  3777                 else | 
 |  3778                 { | 
 |  3779                         switch(uMsg) | 
 |  3780                         { | 
 |  3781                         case PSCB_GETVERSION : | 
 |  3782                                 nRet = COMCTL32_VERSION; | 
 |  3783                                 break; | 
 |  3784                         case PSCB_GETTITLE : | 
 |  3785                                 if(m_pszTitle != NULL) | 
 |  3786                                 { | 
 |  3787                                         lstrcpy((LPTSTR)lParam, m_pszTitle); | 
 |  3788                                         m_pszTitle = NULL; | 
 |  3789                                 } | 
 |  3790                                 break; | 
 |  3791                         case PSCB_GETLINKTEXT: | 
 |  3792                                 if(m_pszLink != NULL) | 
 |  3793                                 { | 
 |  3794                                         lstrcpy((LPTSTR)lParam, m_pszLink); | 
 |  3795                                         m_pszLink = NULL; | 
 |  3796                                 } | 
 |  3797                                 break; | 
 |  3798                         default: | 
 |  3799                                 break; | 
 |  3800                         } | 
 |  3801                 } | 
 |  3802 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)  | 
 |  3803  | 
 |  3804                 return nRet; | 
 |  3805         } | 
 |  3806  | 
 |  3807         void OnSheetInitialized() | 
 |  3808         { | 
 |  3809         } | 
 |  3810  | 
 |  3811 // Create method | 
 |  3812         HWND Create(HWND hWndParent = NULL) | 
 |  3813         { | 
 |  3814                 ATLASSERT(m_hWnd == NULL); | 
 |  3815  | 
 |  3816                 m_psh.dwFlags |= PSH_MODELESS; | 
 |  3817                 if(m_psh.hwndParent == NULL) | 
 |  3818                         m_psh.hwndParent = hWndParent; | 
 |  3819                 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); | 
 |  3820                 m_psh.nPages = m_arrPages.GetSize(); | 
 |  3821  | 
 |  3822                 T* pT = static_cast<T*>(this); | 
 |  3823                 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); | 
 |  3824  | 
 |  3825                 HWND hWnd = (HWND)::PropertySheet(&m_psh); | 
 |  3826                 _CleanUpPages();   // ensure clean-up, required if call failed | 
 |  3827  | 
 |  3828                 ATLASSERT(m_hWnd == hWnd); | 
 |  3829  | 
 |  3830                 return hWnd; | 
 |  3831         } | 
 |  3832  | 
 |  3833         INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow()) | 
 |  3834         { | 
 |  3835                 ATLASSERT(m_hWnd == NULL); | 
 |  3836  | 
 |  3837                 m_psh.dwFlags &= ~PSH_MODELESS; | 
 |  3838                 if(m_psh.hwndParent == NULL) | 
 |  3839                         m_psh.hwndParent = hWndParent; | 
 |  3840                 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData(); | 
 |  3841                 m_psh.nPages = m_arrPages.GetSize(); | 
 |  3842  | 
 |  3843                 T* pT = static_cast<T*>(this); | 
 |  3844                 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT); | 
 |  3845  | 
 |  3846                 INT_PTR nRet = ::PropertySheet(&m_psh); | 
 |  3847                 _CleanUpPages();   // ensure clean-up, required if call failed | 
 |  3848  | 
 |  3849                 return nRet; | 
 |  3850         } | 
 |  3851  | 
 |  3852         // implementation helper - clean up pages array | 
 |  3853         void _CleanUpPages() | 
 |  3854         { | 
 |  3855                 m_psh.nPages = 0; | 
 |  3856                 m_psh.phpage = NULL; | 
 |  3857                 m_arrPages.RemoveAll(); | 
 |  3858         } | 
 |  3859  | 
 |  3860 // Attributes (extended overrides of client class methods) | 
 |  3861 // These now can be called before the sheet is created | 
 |  3862 // Note: Calling these after the sheet is created gives unpredictable results | 
 |  3863         int GetPageCount() const | 
 |  3864         { | 
 |  3865                 if(m_hWnd == NULL)   // not created yet | 
 |  3866                         return m_arrPages.GetSize(); | 
 |  3867                 return TBase::GetPageCount(); | 
 |  3868         } | 
 |  3869  | 
 |  3870         int GetActiveIndex() const | 
 |  3871         { | 
 |  3872                 if(m_hWnd == NULL)   // not created yet | 
 |  3873                         return m_psh.nStartPage; | 
 |  3874                 return TBase::GetActiveIndex(); | 
 |  3875         } | 
 |  3876  | 
 |  3877         HPROPSHEETPAGE GetPage(int nPageIndex) const | 
 |  3878         { | 
 |  3879                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  3880                 return (HPROPSHEETPAGE)m_arrPages[nPageIndex]; | 
 |  3881         } | 
 |  3882  | 
 |  3883         int GetPageIndex(HPROPSHEETPAGE hPage) const | 
 |  3884         { | 
 |  3885                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  3886                 return m_arrPages.Find((HPROPSHEETPAGE&)hPage); | 
 |  3887         } | 
 |  3888  | 
 |  3889         BOOL SetActivePage(int nPageIndex) | 
 |  3890         { | 
 |  3891                 if(m_hWnd == NULL)   // not created yet | 
 |  3892                 { | 
 |  3893                         ATLASSERT(nPageIndex >= 0 && nPageIndex < m_arrPages.Get
      Size()); | 
 |  3894                         m_psh.nStartPage = nPageIndex; | 
 |  3895                         return TRUE; | 
 |  3896                 } | 
 |  3897                 return TBase::SetActivePage(nPageIndex); | 
 |  3898         } | 
 |  3899  | 
 |  3900         BOOL SetActivePage(HPROPSHEETPAGE hPage) | 
 |  3901         { | 
 |  3902                 ATLASSERT(hPage != NULL); | 
 |  3903                 if (m_hWnd == NULL)   // not created yet | 
 |  3904                 { | 
 |  3905                         int nPageIndex = GetPageIndex(hPage); | 
 |  3906                         if(nPageIndex == -1) | 
 |  3907                                 return FALSE; | 
 |  3908  | 
 |  3909                         return SetActivePage(nPageIndex); | 
 |  3910                 } | 
 |  3911                 return TBase::SetActivePage(hPage); | 
 |  3912  | 
 |  3913         } | 
 |  3914  | 
 |  3915         void SetTitle(LPCTSTR lpszText, UINT nStyle = 0) | 
 |  3916         { | 
 |  3917                 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0);   // only PSH_PROPTIT
      LE is valid | 
 |  3918                 ATLASSERT(lpszText != NULL); | 
 |  3919  | 
 |  3920                 if(m_hWnd == NULL) | 
 |  3921                 { | 
 |  3922                         // set internal state | 
 |  3923                         m_psh.pszCaption = lpszText;   // must exist until sheet
       is created | 
 |  3924                         m_psh.dwFlags &= ~PSH_PROPTITLE; | 
 |  3925                         m_psh.dwFlags |= nStyle; | 
 |  3926                 } | 
 |  3927                 else | 
 |  3928                 { | 
 |  3929                         // set external state | 
 |  3930                         TBase::SetTitle(lpszText, nStyle); | 
 |  3931                 } | 
 |  3932         } | 
 |  3933  | 
 |  3934 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field  | 
 |  3935         void SetLinkText(LPCTSTR lpszText) | 
 |  3936         { | 
 |  3937                 ATLASSERT(lpszText != NULL); | 
 |  3938                 ATLASSERT(lstrlen(lpszText) < PROPSHEET_LINK_SIZE); | 
 |  3939                 lstrcpy(m_szLink, lpszText); | 
 |  3940         } | 
 |  3941 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)  | 
 |  3942  | 
 |  3943         void SetWizardMode() | 
 |  3944         { | 
 |  3945                 m_psh.dwFlags |= PSH_WIZARD; | 
 |  3946         } | 
 |  3947  | 
 |  3948         void EnableHelp() | 
 |  3949         { | 
 |  3950                 m_psh.dwFlags |= PSH_HASHELP; | 
 |  3951         } | 
 |  3952  | 
 |  3953 // Operations | 
 |  3954         BOOL AddPage(HPROPSHEETPAGE hPage) | 
 |  3955         { | 
 |  3956                 ATLASSERT(hPage != NULL); | 
 |  3957                 BOOL bRet = FALSE; | 
 |  3958                 if(m_hWnd != NULL) | 
 |  3959                         bRet = TBase::AddPage(hPage); | 
 |  3960                 else    // sheet not created yet, use internal data | 
 |  3961                         bRet = m_arrPages.Add((HPROPSHEETPAGE&)hPage); | 
 |  3962                 return bRet; | 
 |  3963         } | 
 |  3964  | 
 |  3965         BOOL AddPage(LPCPROPSHEETPAGE pPage) | 
 |  3966         { | 
 |  3967                 ATLASSERT(pPage != NULL); | 
 |  3968                 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage); | 
 |  3969                 if(hPage == NULL) | 
 |  3970                         return FALSE; | 
 |  3971                 BOOL bRet = AddPage(hPage); | 
 |  3972                 if(!bRet) | 
 |  3973                         ::DestroyPropertySheetPage(hPage); | 
 |  3974                 return bRet; | 
 |  3975         } | 
 |  3976  | 
 |  3977         BOOL RemovePage(HPROPSHEETPAGE hPage) | 
 |  3978         { | 
 |  3979                 ATLASSERT(hPage != NULL); | 
 |  3980                 if (m_hWnd == NULL)   // not created yet | 
 |  3981                 { | 
 |  3982                         int nPage = GetPageIndex(hPage); | 
 |  3983                         if(nPage == -1) | 
 |  3984                                 return FALSE; | 
 |  3985                         return RemovePage(nPage); | 
 |  3986                 } | 
 |  3987                 TBase::RemovePage(hPage); | 
 |  3988                 return TRUE; | 
 |  3989  | 
 |  3990         } | 
 |  3991  | 
 |  3992         BOOL RemovePage(int nPageIndex) | 
 |  3993         { | 
 |  3994                 BOOL bRet = TRUE; | 
 |  3995                 if(m_hWnd != NULL) | 
 |  3996                         TBase::RemovePage(nPageIndex); | 
 |  3997                 else    // sheet not created yet, use internal data | 
 |  3998                         bRet = m_arrPages.RemoveAt(nPageIndex); | 
 |  3999                 return bRet; | 
 |  4000         } | 
 |  4001  | 
 |  4002 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) | 
 |  4003         void SetHeader(LPCTSTR szbmHeader) | 
 |  4004         { | 
 |  4005                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4006  | 
 |  4007                 m_psh.dwFlags &= ~PSH_WIZARD; | 
 |  4008                 m_psh.dwFlags |= (PSH_HEADER | PSH_WIZARD97); | 
 |  4009                 m_psh.pszbmHeader = szbmHeader; | 
 |  4010         } | 
 |  4011  | 
 |  4012         void SetHeader(HBITMAP hbmHeader) | 
 |  4013         { | 
 |  4014                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4015  | 
 |  4016                 m_psh.dwFlags &= ~PSH_WIZARD; | 
 |  4017                 m_psh.dwFlags |= (PSH_HEADER | PSH_USEHBMHEADER | PSH_WIZARD97); | 
 |  4018                 m_psh.hbmHeader = hbmHeader; | 
 |  4019         } | 
 |  4020  | 
 |  4021         void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL) | 
 |  4022         { | 
 |  4023                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4024  | 
 |  4025                 m_psh.dwFlags &= ~PSH_WIZARD; | 
 |  4026                 m_psh.dwFlags |= PSH_WATERMARK | PSH_WIZARD97; | 
 |  4027                 m_psh.pszbmWatermark = szbmWatermark; | 
 |  4028  | 
 |  4029                 if (hplWatermark != NULL) | 
 |  4030                 { | 
 |  4031                         m_psh.dwFlags |= PSH_USEHPLWATERMARK; | 
 |  4032                         m_psh.hplWatermark = hplWatermark; | 
 |  4033                 } | 
 |  4034         } | 
 |  4035  | 
 |  4036         void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL) | 
 |  4037         { | 
 |  4038                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4039  | 
 |  4040                 m_psh.dwFlags &= ~PSH_WIZARD; | 
 |  4041                 m_psh.dwFlags |= (PSH_WATERMARK | PSH_USEHBMWATERMARK | PSH_WIZA
      RD97); | 
 |  4042                 m_psh.hbmWatermark = hbmWatermark; | 
 |  4043  | 
 |  4044                 if (hplWatermark != NULL) | 
 |  4045                 { | 
 |  4046                         m_psh.dwFlags |= PSH_USEHPLWATERMARK; | 
 |  4047                         m_psh.hplWatermark = hplWatermark; | 
 |  4048                 } | 
 |  4049         } | 
 |  4050  | 
 |  4051         void StretchWatermark(bool bStretchWatermark) | 
 |  4052         { | 
 |  4053                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4054                 if (bStretchWatermark) | 
 |  4055                         m_psh.dwFlags |= PSH_STRETCHWATERMARK; | 
 |  4056                 else | 
 |  4057                         m_psh.dwFlags &= ~PSH_STRETCHWATERMARK; | 
 |  4058         } | 
 |  4059 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE) | 
 |  4060  | 
 |  4061 // Message map and handlers | 
 |  4062         BEGIN_MSG_MAP(CPropertySheetImpl) | 
 |  4063                 MESSAGE_HANDLER(WM_COMMAND, OnCommand) | 
 |  4064                 MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand) | 
 |  4065         END_MSG_MAP() | 
 |  4066  | 
 |  4067         LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHand
      led*/) | 
 |  4068         { | 
 |  4069                 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam); | 
 |  4070                 if(HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LO
      WORD(wParam) == IDCANCEL) && | 
 |  4071                    ((m_psh.dwFlags & PSH_MODELESS) != 0) && (GetActivePage() == 
      NULL)) | 
 |  4072                         DestroyWindow(); | 
 |  4073                 return lRet; | 
 |  4074         } | 
 |  4075  | 
 |  4076         LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BO
      OL& bHandled) | 
 |  4077         { | 
 |  4078                 if(((m_psh.dwFlags & PSH_MODELESS) == PSH_MODELESS) && ((wParam 
      & 0xFFF0) == SC_CLOSE)) | 
 |  4079                         SendMessage(WM_CLOSE); | 
 |  4080                 else | 
 |  4081                         bHandled = FALSE; | 
 |  4082                 return 0; | 
 |  4083         } | 
 |  4084 }; | 
 |  4085  | 
 |  4086 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers | 
 |  4087 template < class T, class TBase > | 
 |  4088 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszTitle = NULL; | 
 |  4089 template < class T, class TBase> | 
 |  4090 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszLink = NULL; | 
 |  4091 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) | 
 |  4092  | 
 |  4093 // for non-customized sheets | 
 |  4094 class CPropertySheet : public CPropertySheetImpl<CPropertySheet> | 
 |  4095 { | 
 |  4096 public: | 
 |  4097         CPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage
       = 0, HWND hWndParent = NULL) | 
 |  4098                 : CPropertySheetImpl<CPropertySheet>(title, uStartPage, hWndPare
      nt) | 
 |  4099         { } | 
 |  4100 }; | 
 |  4101  | 
 |  4102  | 
 |  4103 /////////////////////////////////////////////////////////////////////////////// | 
 |  4104 // CPropertyPageWindow - client side for a property page | 
 |  4105  | 
 |  4106 class CPropertyPageWindow : public ATL::CWindow | 
 |  4107 { | 
 |  4108 public: | 
 |  4109 // Constructors | 
 |  4110         CPropertyPageWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd) | 
 |  4111         { } | 
 |  4112  | 
 |  4113         CPropertyPageWindow& operator =(HWND hWnd) | 
 |  4114         { | 
 |  4115                 m_hWnd = hWnd; | 
 |  4116                 return *this; | 
 |  4117         } | 
 |  4118  | 
 |  4119 // Attributes | 
 |  4120         CPropertySheetWindow GetPropertySheet() const | 
 |  4121         { | 
 |  4122                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4123                 return CPropertySheetWindow(GetParent()); | 
 |  4124         } | 
 |  4125  | 
 |  4126 // Operations | 
 |  4127         BOOL Apply() | 
 |  4128         { | 
 |  4129                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4130                 ATLASSERT(GetParent() != NULL); | 
 |  4131                 return GetPropertySheet().Apply(); | 
 |  4132         } | 
 |  4133  | 
 |  4134         void CancelToClose() | 
 |  4135         { | 
 |  4136                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4137                 ATLASSERT(GetParent() != NULL); | 
 |  4138                 GetPropertySheet().CancelToClose(); | 
 |  4139         } | 
 |  4140  | 
 |  4141         void SetModified(BOOL bChanged = TRUE) | 
 |  4142         { | 
 |  4143                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4144                 ATLASSERT(GetParent() != NULL); | 
 |  4145                 GetPropertySheet().SetModified(m_hWnd, bChanged); | 
 |  4146         } | 
 |  4147  | 
 |  4148         LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) | 
 |  4149         { | 
 |  4150                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4151                 ATLASSERT(GetParent() != NULL); | 
 |  4152                 return GetPropertySheet().QuerySiblings(wParam, lParam); | 
 |  4153         } | 
 |  4154  | 
 |  4155         void RebootSystem() | 
 |  4156         { | 
 |  4157                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4158                 ATLASSERT(GetParent() != NULL); | 
 |  4159                 GetPropertySheet().RebootSystem(); | 
 |  4160         } | 
 |  4161  | 
 |  4162         void RestartWindows() | 
 |  4163         { | 
 |  4164                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4165                 ATLASSERT(GetParent() != NULL); | 
 |  4166                 GetPropertySheet().RestartWindows(); | 
 |  4167         } | 
 |  4168  | 
 |  4169         void SetWizardButtons(DWORD dwFlags) | 
 |  4170         { | 
 |  4171                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4172                 ATLASSERT(GetParent() != NULL); | 
 |  4173                 GetPropertySheet().SetWizardButtons(dwFlags); | 
 |  4174         } | 
 |  4175  | 
 |  4176 // Implementation - overrides to prevent usage | 
 |  4177         HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 
      0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) | 
 |  4178         { | 
 |  4179                 ATLASSERT(FALSE); | 
 |  4180                 return NULL; | 
 |  4181         } | 
 |  4182 }; | 
 |  4183  | 
 |  4184 /////////////////////////////////////////////////////////////////////////////// | 
 |  4185 // CPropertyPageImpl - implements a property page | 
 |  4186  | 
 |  4187 template <class T, class TBase = CPropertyPageWindow> | 
 |  4188 class ATL_NO_VTABLE CPropertyPageImpl : public ATL::CDialogImplBaseT< TBase > | 
 |  4189 { | 
 |  4190 public: | 
 |  4191         PROPSHEETPAGE m_psp; | 
 |  4192  | 
 |  4193         operator PROPSHEETPAGE*() { return &m_psp; } | 
 |  4194  | 
 |  4195 // Construction | 
 |  4196         CPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) | 
 |  4197         { | 
 |  4198                 // initialize PROPSHEETPAGE struct | 
 |  4199                 memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); | 
 |  4200                 m_psp.dwSize = sizeof(PROPSHEETPAGE); | 
 |  4201                 m_psp.dwFlags = PSP_USECALLBACK; | 
 |  4202                 m_psp.hInstance = ModuleHelper::GetResourceInstance(); | 
 |  4203                 T* pT = static_cast<T*>(this); | 
 |  4204                 m_psp.pszTemplate = MAKEINTRESOURCE(pT->IDD); | 
 |  4205                 m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; | 
 |  4206                 m_psp.pfnCallback = T::PropPageCallback; | 
 |  4207                 m_psp.lParam = (LPARAM)pT; | 
 |  4208  | 
 |  4209                 if(title.m_lpstr != NULL) | 
 |  4210                         SetTitle(title); | 
 |  4211         } | 
 |  4212  | 
 |  4213 // Callback function and overrideables | 
 |  4214         static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETP
      AGE ppsp) | 
 |  4215         { | 
 |  4216                 hWnd;   // avoid level 4 warning | 
 |  4217                 ATLASSERT(hWnd == NULL); | 
 |  4218                 T* pT = (T*)ppsp->lParam; | 
 |  4219                 UINT uRet = 0; | 
 |  4220  | 
 |  4221                 switch(uMsg) | 
 |  4222                 { | 
 |  4223                 case PSPCB_CREATE: | 
 |  4224                         { | 
 |  4225                                 ATL::CDialogImplBaseT< TBase >* pPage = (ATL::CD
      ialogImplBaseT< TBase >*)pT; | 
 |  4226                                 ModuleHelper::AddCreateWndData(&pPage->m_thunk.c
      d, pPage); | 
 |  4227                                 uRet = pT->OnPageCreate() ? 1 : 0; | 
 |  4228                         } | 
 |  4229                         break; | 
 |  4230 #if (_WIN32_IE >= 0x0500) | 
 |  4231                 case PSPCB_ADDREF: | 
 |  4232                         pT->OnPageAddRef(); | 
 |  4233                         break; | 
 |  4234 #endif // (_WIN32_IE >= 0x0500) | 
 |  4235                 case PSPCB_RELEASE: | 
 |  4236                         pT->OnPageRelease(); | 
 |  4237                         break; | 
 |  4238                 default: | 
 |  4239                         break; | 
 |  4240                 } | 
 |  4241  | 
 |  4242                 return uRet; | 
 |  4243         } | 
 |  4244  | 
 |  4245         bool OnPageCreate() | 
 |  4246         { | 
 |  4247                 return true;   // true - allow page to be created, false - preve
      nt creation | 
 |  4248         } | 
 |  4249  | 
 |  4250 #if (_WIN32_IE >= 0x0500) | 
 |  4251         void OnPageAddRef() | 
 |  4252         { | 
 |  4253         } | 
 |  4254 #endif // (_WIN32_IE >= 0x0500) | 
 |  4255  | 
 |  4256         void OnPageRelease() | 
 |  4257         { | 
 |  4258         } | 
 |  4259  | 
 |  4260 // Create method | 
 |  4261         HPROPSHEETPAGE Create() | 
 |  4262         { | 
 |  4263                 return ::CreatePropertySheetPage(&m_psp); | 
 |  4264         } | 
 |  4265  | 
 |  4266 // Attributes | 
 |  4267         void SetTitle(ATL::_U_STRINGorID title) | 
 |  4268         { | 
 |  4269                 m_psp.pszTitle = title.m_lpstr; | 
 |  4270                 m_psp.dwFlags |= PSP_USETITLE; | 
 |  4271         } | 
 |  4272  | 
 |  4273 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  4274         void SetHeaderTitle(LPCTSTR lpstrHeaderTitle) | 
 |  4275         { | 
 |  4276                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4277                 m_psp.dwFlags |= PSP_USEHEADERTITLE; | 
 |  4278                 m_psp.pszHeaderTitle = lpstrHeaderTitle; | 
 |  4279         } | 
 |  4280  | 
 |  4281         void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle) | 
 |  4282         { | 
 |  4283                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  4284                 m_psp.dwFlags |= PSP_USEHEADERSUBTITLE; | 
 |  4285                 m_psp.pszHeaderSubTitle = lpstrHeaderSubTitle; | 
 |  4286         } | 
 |  4287 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  4288  | 
 |  4289 // Operations | 
 |  4290         void EnableHelp() | 
 |  4291         { | 
 |  4292                 m_psp.dwFlags |= PSP_HASHELP; | 
 |  4293         } | 
 |  4294  | 
 |  4295 // Message map and handlers | 
 |  4296         BEGIN_MSG_MAP(CPropertyPageImpl) | 
 |  4297                 MESSAGE_HANDLER(WM_NOTIFY, OnNotify) | 
 |  4298         END_MSG_MAP() | 
 |  4299  | 
 |  4300         // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification | 
 |  4301         // handlers that return direct values without any restrictions | 
 |  4302         LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& 
      bHandled) | 
 |  4303         { | 
 |  4304 #ifndef _WIN32_WCE | 
 |  4305                 // This notification is sometimes received on Windows CE after t
      he window is already destroyed | 
 |  4306                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4307 #endif | 
 |  4308                 NMHDR* pNMHDR = (NMHDR*)lParam; | 
 |  4309  | 
 |  4310                 // don't handle messages not from the page/sheet itself | 
 |  4311                 if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent
      (m_hWnd)) | 
 |  4312                 { | 
 |  4313                         bHandled = FALSE; | 
 |  4314                         return 1; | 
 |  4315                 } | 
 |  4316 #ifdef _WIN32_WCE | 
 |  4317                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  4318 #endif | 
 |  4319  | 
 |  4320                 T* pT = static_cast<T*>(this); | 
 |  4321                 LRESULT lResult = 0; | 
 |  4322                 switch(pNMHDR->code) | 
 |  4323                 { | 
 |  4324 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4325                 case PSN_SETACTIVE: | 
 |  4326                         lResult = pT->OnSetActive(); | 
 |  4327                         break; | 
 |  4328                 case PSN_KILLACTIVE: | 
 |  4329                         lResult = pT->OnKillActive(); | 
 |  4330                         break; | 
 |  4331                 case PSN_APPLY: | 
 |  4332                         lResult = pT->OnApply(); | 
 |  4333                         break; | 
 |  4334                 case PSN_RESET: | 
 |  4335                         pT->OnReset(); | 
 |  4336                         break; | 
 |  4337                 case PSN_QUERYCANCEL: | 
 |  4338                         lResult = pT->OnQueryCancel(); | 
 |  4339                         break; | 
 |  4340                 case PSN_WIZNEXT: | 
 |  4341                         lResult = pT->OnWizardNext(); | 
 |  4342                         break; | 
 |  4343                 case PSN_WIZBACK: | 
 |  4344                         lResult = pT->OnWizardBack(); | 
 |  4345                         break; | 
 |  4346                 case PSN_WIZFINISH: | 
 |  4347                         lResult = pT->OnWizardFinish(); | 
 |  4348                         break; | 
 |  4349                 case PSN_HELP: | 
 |  4350                         pT->OnHelp(); | 
 |  4351                         break; | 
 |  4352 #ifndef _WIN32_WCE | 
 |  4353 #if (_WIN32_IE >= 0x0400) | 
 |  4354                 case PSN_GETOBJECT: | 
 |  4355                         if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) | 
 |  4356                                 bHandled = FALSE; | 
 |  4357                         break; | 
 |  4358 #endif // (_WIN32_IE >= 0x0400) | 
 |  4359 #if (_WIN32_IE >= 0x0500) | 
 |  4360                 case PSN_TRANSLATEACCELERATOR: | 
 |  4361                         { | 
 |  4362                                 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; | 
 |  4363                                 lResult = pT->OnTranslateAccelerator((LPMSG)lpPS
      HNotify->lParam); | 
 |  4364                         } | 
 |  4365                         break; | 
 |  4366                 case PSN_QUERYINITIALFOCUS: | 
 |  4367                         { | 
 |  4368                                 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; | 
 |  4369                                 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND
      )lpPSHNotify->lParam); | 
 |  4370                         } | 
 |  4371                         break; | 
 |  4372 #endif // (_WIN32_IE >= 0x0500) | 
 |  4373 #endif // !_WIN32_WCE | 
 |  4374  | 
 |  4375 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4376                 case PSN_SETACTIVE: | 
 |  4377                         lResult = pT->OnSetActive() ? 0 : -1; | 
 |  4378                         break; | 
 |  4379                 case PSN_KILLACTIVE: | 
 |  4380                         lResult = !pT->OnKillActive(); | 
 |  4381                         break; | 
 |  4382                 case PSN_APPLY: | 
 |  4383                         lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALI
      D_NOCHANGEPAGE; | 
 |  4384                         break; | 
 |  4385                 case PSN_RESET: | 
 |  4386                         pT->OnReset(); | 
 |  4387                         break; | 
 |  4388                 case PSN_QUERYCANCEL: | 
 |  4389                         lResult = !pT->OnQueryCancel(); | 
 |  4390                         break; | 
 |  4391                 case PSN_WIZNEXT: | 
 |  4392                         lResult = pT->OnWizardNext(); | 
 |  4393                         break; | 
 |  4394                 case PSN_WIZBACK: | 
 |  4395                         lResult = pT->OnWizardBack(); | 
 |  4396                         break; | 
 |  4397                 case PSN_WIZFINISH: | 
 |  4398                         lResult = !pT->OnWizardFinish(); | 
 |  4399                         break; | 
 |  4400                 case PSN_HELP: | 
 |  4401                         pT->OnHelp(); | 
 |  4402                         break; | 
 |  4403 #ifndef _WIN32_WCE | 
 |  4404 #if (_WIN32_IE >= 0x0400) | 
 |  4405                 case PSN_GETOBJECT: | 
 |  4406                         if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam)) | 
 |  4407                                 bHandled = FALSE; | 
 |  4408                         break; | 
 |  4409 #endif // (_WIN32_IE >= 0x0400) | 
 |  4410 #if (_WIN32_IE >= 0x0500) | 
 |  4411                 case PSN_TRANSLATEACCELERATOR: | 
 |  4412                         { | 
 |  4413                                 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; | 
 |  4414                                 lResult = pT->OnTranslateAccelerator((LPMSG)lpPS
      HNotify->lParam) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR; | 
 |  4415                         } | 
 |  4416                         break; | 
 |  4417                 case PSN_QUERYINITIALFOCUS: | 
 |  4418                         { | 
 |  4419                                 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam; | 
 |  4420                                 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND
      )lpPSHNotify->lParam); | 
 |  4421                         } | 
 |  4422                         break; | 
 |  4423 #endif // (_WIN32_IE >= 0x0500) | 
 |  4424 #endif // !_WIN32_WCE | 
 |  4425  | 
 |  4426 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4427                 default: | 
 |  4428                         bHandled = FALSE;   // not handled | 
 |  4429                 } | 
 |  4430  | 
 |  4431                 return lResult; | 
 |  4432         } | 
 |  4433  | 
 |  4434 // Overridables | 
 |  4435         // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification | 
 |  4436         // handlers that return direct values without any restrictions | 
 |  4437 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4438         int OnSetActive() | 
 |  4439         { | 
 |  4440                 // 0 = allow activate | 
 |  4441                 // -1 = go back that was active | 
 |  4442                 // page ID = jump to page | 
 |  4443                 return 0; | 
 |  4444         } | 
 |  4445  | 
 |  4446         BOOL OnKillActive() | 
 |  4447         { | 
 |  4448                 // FALSE = allow deactivate | 
 |  4449                 // TRUE = prevent deactivation | 
 |  4450                 return FALSE; | 
 |  4451         } | 
 |  4452  | 
 |  4453         int OnApply() | 
 |  4454         { | 
 |  4455                 // PSNRET_NOERROR = apply OK | 
 |  4456                 // PSNRET_INVALID = apply not OK, return to this page | 
 |  4457                 // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focu
      s | 
 |  4458                 return PSNRET_NOERROR; | 
 |  4459         } | 
 |  4460  | 
 |  4461         void OnReset() | 
 |  4462         { | 
 |  4463         } | 
 |  4464  | 
 |  4465         BOOL OnQueryCancel() | 
 |  4466         { | 
 |  4467                 // FALSE = allow cancel | 
 |  4468                 // TRUE = prevent cancel | 
 |  4469                 return FALSE; | 
 |  4470         } | 
 |  4471  | 
 |  4472         int OnWizardBack() | 
 |  4473         { | 
 |  4474                 // 0  = goto previous page | 
 |  4475                 // -1 = prevent page change | 
 |  4476                 // >0 = jump to page by dlg ID | 
 |  4477                 return 0; | 
 |  4478         } | 
 |  4479  | 
 |  4480         int OnWizardNext() | 
 |  4481         { | 
 |  4482                 // 0  = goto next page | 
 |  4483                 // -1 = prevent page change | 
 |  4484                 // >0 = jump to page by dlg ID | 
 |  4485                 return 0; | 
 |  4486         } | 
 |  4487  | 
 |  4488         INT_PTR OnWizardFinish() | 
 |  4489         { | 
 |  4490                 // FALSE = allow finish | 
 |  4491                 // TRUE = prevent finish | 
 |  4492                 // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 on
      ly) | 
 |  4493                 return FALSE; | 
 |  4494         } | 
 |  4495  | 
 |  4496         void OnHelp() | 
 |  4497         { | 
 |  4498         } | 
 |  4499  | 
 |  4500 #ifndef _WIN32_WCE | 
 |  4501 #if (_WIN32_IE >= 0x0400) | 
 |  4502         BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) | 
 |  4503         { | 
 |  4504                 return FALSE;   // not processed | 
 |  4505         } | 
 |  4506 #endif // (_WIN32_IE >= 0x0400) | 
 |  4507  | 
 |  4508 #if (_WIN32_IE >= 0x0500) | 
 |  4509         int OnTranslateAccelerator(LPMSG /*lpMsg*/) | 
 |  4510         { | 
 |  4511                 // PSNRET_NOERROR - message not handled | 
 |  4512                 // PSNRET_MESSAGEHANDLED - message handled | 
 |  4513                 return PSNRET_NOERROR; | 
 |  4514         } | 
 |  4515  | 
 |  4516         HWND OnQueryInitialFocus(HWND /*hWndFocus*/) | 
 |  4517         { | 
 |  4518                 // NULL = set focus to default control | 
 |  4519                 // HWND = set focus to HWND | 
 |  4520                 return NULL; | 
 |  4521         } | 
 |  4522 #endif // (_WIN32_IE >= 0x0500) | 
 |  4523 #endif // !_WIN32_WCE | 
 |  4524  | 
 |  4525 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4526         BOOL OnSetActive() | 
 |  4527         { | 
 |  4528                 return TRUE; | 
 |  4529         } | 
 |  4530  | 
 |  4531         BOOL OnKillActive() | 
 |  4532         { | 
 |  4533                 return TRUE; | 
 |  4534         } | 
 |  4535  | 
 |  4536         BOOL OnApply() | 
 |  4537         { | 
 |  4538                 return TRUE; | 
 |  4539         } | 
 |  4540  | 
 |  4541         void OnReset() | 
 |  4542         { | 
 |  4543         } | 
 |  4544  | 
 |  4545         BOOL OnQueryCancel() | 
 |  4546         { | 
 |  4547                 return TRUE;    // ok to cancel | 
 |  4548         } | 
 |  4549  | 
 |  4550         int OnWizardBack() | 
 |  4551         { | 
 |  4552                 // 0  = goto previous page | 
 |  4553                 // -1 = prevent page change | 
 |  4554                 // >0 = jump to page by dlg ID | 
 |  4555                 return 0; | 
 |  4556         } | 
 |  4557  | 
 |  4558         int OnWizardNext() | 
 |  4559         { | 
 |  4560                 // 0  = goto next page | 
 |  4561                 // -1 = prevent page change | 
 |  4562                 // >0 = jump to page by dlg ID | 
 |  4563                 return 0; | 
 |  4564         } | 
 |  4565  | 
 |  4566         BOOL OnWizardFinish() | 
 |  4567         { | 
 |  4568                 return TRUE; | 
 |  4569         } | 
 |  4570  | 
 |  4571         void OnHelp() | 
 |  4572         { | 
 |  4573         } | 
 |  4574  | 
 |  4575 #ifndef _WIN32_WCE | 
 |  4576 #if (_WIN32_IE >= 0x0400) | 
 |  4577         BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/) | 
 |  4578         { | 
 |  4579                 return FALSE;   // not processed | 
 |  4580         } | 
 |  4581 #endif // (_WIN32_IE >= 0x0400) | 
 |  4582  | 
 |  4583 #if (_WIN32_IE >= 0x0500) | 
 |  4584         BOOL OnTranslateAccelerator(LPMSG /*lpMsg*/) | 
 |  4585         { | 
 |  4586                 return FALSE;   // not translated | 
 |  4587         } | 
 |  4588  | 
 |  4589         HWND OnQueryInitialFocus(HWND /*hWndFocus*/) | 
 |  4590         { | 
 |  4591                 return NULL;   // default | 
 |  4592         } | 
 |  4593 #endif // (_WIN32_IE >= 0x0500) | 
 |  4594 #endif // !_WIN32_WCE | 
 |  4595  | 
 |  4596 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4597 }; | 
 |  4598  | 
 |  4599 // for non-customized pages | 
 |  4600 template <WORD t_wDlgTemplateID> | 
 |  4601 class CPropertyPage : public CPropertyPageImpl<CPropertyPage<t_wDlgTemplateID> > | 
 |  4602 { | 
 |  4603 public: | 
 |  4604         enum { IDD = t_wDlgTemplateID }; | 
 |  4605  | 
 |  4606         CPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageI
      mpl<CPropertyPage>(title) | 
 |  4607         { } | 
 |  4608  | 
 |  4609         DECLARE_EMPTY_MSG_MAP() | 
 |  4610 }; | 
 |  4611  | 
 |  4612 /////////////////////////////////////////////////////////////////////////////// | 
 |  4613 // CAxPropertyPageImpl - property page that hosts ActiveX controls | 
 |  4614  | 
 |  4615 #ifndef _ATL_NO_HOSTING | 
 |  4616  | 
 |  4617 // Note: You must #include <atlhost.h> to use these classes | 
 |  4618  | 
 |  4619 template <class T, class TBase = CPropertyPageWindow> | 
 |  4620 class ATL_NO_VTABLE CAxPropertyPageImpl : public CPropertyPageImpl< T, TBase > | 
 |  4621 { | 
 |  4622 public: | 
 |  4623 // Data members | 
 |  4624         HGLOBAL m_hInitData; | 
 |  4625         HGLOBAL m_hDlgRes; | 
 |  4626         HGLOBAL m_hDlgResSplit; | 
 |  4627  | 
 |  4628 // Constructor/destructor | 
 |  4629         CAxPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) :  | 
 |  4630                         CPropertyPageImpl< T, TBase >(title), | 
 |  4631                         m_hInitData(NULL), m_hDlgRes(NULL), m_hDlgResSplit(NULL) | 
 |  4632         { | 
 |  4633                 T* pT = static_cast<T*>(this); | 
 |  4634                 pT;   // avoid level 4 warning | 
 |  4635  | 
 |  4636                 // initialize ActiveX hosting and modify dialog template | 
 |  4637                 ATL::AtlAxWinInit(); | 
 |  4638  | 
 |  4639                 HINSTANCE hInstance = ModuleHelper::GetResourceInstance(); | 
 |  4640                 LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD); | 
 |  4641                 HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)R
      T_DIALOG); | 
 |  4642                 if(hDlg != NULL) | 
 |  4643                 { | 
 |  4644                         HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateNam
      e, (LPTSTR)_ATL_RT_DLGINIT); | 
 |  4645  | 
 |  4646                         BYTE* pInitData = NULL; | 
 |  4647                         if(hDlgInit != NULL) | 
 |  4648                         { | 
 |  4649                                 m_hInitData = ::LoadResource(hInstance, hDlgInit
      ); | 
 |  4650                                 pInitData = (BYTE*)::LockResource(m_hInitData); | 
 |  4651                         } | 
 |  4652  | 
 |  4653                         m_hDlgRes = ::LoadResource(hInstance, hDlg); | 
 |  4654                         DLGTEMPLATE* pDlg = (DLGTEMPLATE*)::LockResource(m_hDlgR
      es); | 
 |  4655                         LPCDLGTEMPLATE lpDialogTemplate = ATL::_DialogSplitHelpe
      r::SplitDialogTemplate(pDlg, pInitData); | 
 |  4656                         if(lpDialogTemplate != pDlg) | 
 |  4657                                 m_hDlgResSplit = GlobalHandle(lpDialogTemplate); | 
 |  4658  | 
 |  4659                         // set up property page to use in-memory dialog template | 
 |  4660                         if(lpDialogTemplate != NULL) | 
 |  4661                         { | 
 |  4662                                 m_psp.dwFlags |= PSP_DLGINDIRECT; | 
 |  4663                                 m_psp.pResource = lpDialogTemplate; | 
 |  4664                         } | 
 |  4665                         else | 
 |  4666                         { | 
 |  4667                                 ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Act
      iveX initializtion failed!")); | 
 |  4668                         } | 
 |  4669                 } | 
 |  4670                 else | 
 |  4671                 { | 
 |  4672                         ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Cannot find
       dialog template!")); | 
 |  4673                 } | 
 |  4674         } | 
 |  4675  | 
 |  4676         ~CAxPropertyPageImpl() | 
 |  4677         { | 
 |  4678                 if(m_hInitData != NULL) | 
 |  4679                 { | 
 |  4680                         UnlockResource(m_hInitData); | 
 |  4681                         FreeResource(m_hInitData); | 
 |  4682                 } | 
 |  4683                 if(m_hDlgRes != NULL) | 
 |  4684                 { | 
 |  4685                         UnlockResource(m_hDlgRes); | 
 |  4686                         FreeResource(m_hDlgRes); | 
 |  4687                 } | 
 |  4688                 if(m_hDlgResSplit != NULL) | 
 |  4689                 { | 
 |  4690                         ::GlobalFree(m_hDlgResSplit); | 
 |  4691                 } | 
 |  4692         } | 
 |  4693  | 
 |  4694 // Methods | 
 |  4695         // call this one to handle keyboard message for ActiveX controls | 
 |  4696         BOOL PreTranslateMessage(LPMSG pMsg) | 
 |  4697         { | 
 |  4698                 if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) 
      && | 
 |  4699                    (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAS
      T)) | 
 |  4700                         return FALSE; | 
 |  4701                 // find a direct child of the dialog from the window that has fo
      cus | 
 |  4702                 HWND hWndCtl = ::GetFocus(); | 
 |  4703                 if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd) | 
 |  4704                 { | 
 |  4705                         do | 
 |  4706                         { | 
 |  4707                                 hWndCtl = ::GetParent(hWndCtl); | 
 |  4708                         } | 
 |  4709                         while (::GetParent(hWndCtl) != m_hWnd); | 
 |  4710                 } | 
 |  4711                 // give controls a chance to translate this message | 
 |  4712                 return (BOOL)::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pM
      sg); | 
 |  4713         } | 
 |  4714  | 
 |  4715 // Overridables | 
 |  4716 #if (_WIN32_IE >= 0x0500) | 
 |  4717         // new default implementation for ActiveX hosting pages | 
 |  4718 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4719         int OnTranslateAccelerator(LPMSG lpMsg) | 
 |  4720         { | 
 |  4721                 T* pT = static_cast<T*>(this); | 
 |  4722                 return (pT->PreTranslateMessage(lpMsg) != FALSE) ? PSNRET_MESSAG
      EHANDLED : PSNRET_NOERROR; | 
 |  4723         } | 
 |  4724 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4725         BOOL OnTranslateAccelerator(LPMSG lpMsg) | 
 |  4726         { | 
 |  4727                 T* pT = static_cast<T*>(this); | 
 |  4728                 return pT->PreTranslateMessage(lpMsg); | 
 |  4729         } | 
 |  4730 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS | 
 |  4731 #endif // (_WIN32_IE >= 0x0500) | 
 |  4732  | 
 |  4733 // Support for new stuff in ATL7 | 
 |  4734 #if (_ATL_VER >= 0x0700) | 
 |  4735         int GetIDD() | 
 |  4736         { | 
 |  4737                 return( static_cast<T*>(this)->IDD ); | 
 |  4738         } | 
 |  4739  | 
 |  4740         virtual DLGPROC GetDialogProc() | 
 |  4741         { | 
 |  4742                 return DialogProc; | 
 |  4743         } | 
 |  4744  | 
 |  4745         static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, 
      LPARAM lParam) | 
 |  4746         { | 
 |  4747                 CAxPropertyPageImpl< T, TBase >* pThis = (CAxPropertyPageImpl< T
      , TBase >*)hWnd; | 
 |  4748                 if (uMsg == WM_INITDIALOG) | 
 |  4749                 { | 
 |  4750                         HRESULT hr; | 
 |  4751                         if (FAILED(hr = pThis->CreateActiveXControls(pThis->GetI
      DD()))) | 
 |  4752                         { | 
 |  4753                                 ATLASSERT(FALSE); | 
 |  4754                                 return FALSE; | 
 |  4755                         } | 
 |  4756                 } | 
 |  4757                 return CPropertyPageImpl< T, TBase >::DialogProc(hWnd, uMsg, wPa
      ram, lParam); | 
 |  4758         } | 
 |  4759  | 
 |  4760 // ActiveX controls creation | 
 |  4761         virtual HRESULT CreateActiveXControls(UINT nID) | 
 |  4762         { | 
 |  4763                 // Load dialog template and InitData | 
 |  4764                 HRSRC hDlgInit = ::FindResource(ATL::_AtlBaseModule.GetResourceI
      nstance(), MAKEINTRESOURCE(nID), (LPTSTR)_ATL_RT_DLGINIT); | 
 |  4765                 BYTE* pInitData = NULL; | 
 |  4766                 HGLOBAL hData = NULL; | 
 |  4767                 HRESULT hr = S_OK; | 
 |  4768                 if (hDlgInit != NULL) | 
 |  4769                 { | 
 |  4770                         hData = ::LoadResource(ATL::_AtlBaseModule.GetResourceIn
      stance(), hDlgInit); | 
 |  4771                         if (hData != NULL) | 
 |  4772                                 pInitData = (BYTE*) ::LockResource(hData); | 
 |  4773                 } | 
 |  4774  | 
 |  4775                 HRSRC hDlg = ::FindResource(ATL::_AtlBaseModule.GetResourceInsta
      nce(), MAKEINTRESOURCE(nID), (LPTSTR)RT_DIALOG); | 
 |  4776                 if (hDlg != NULL) | 
 |  4777                 { | 
 |  4778                         HGLOBAL hResource = ::LoadResource(ATL::_AtlBaseModule.G
      etResourceInstance(), hDlg); | 
 |  4779                         DLGTEMPLATE* pDlg = NULL; | 
 |  4780                         if (hResource != NULL) | 
 |  4781                         { | 
 |  4782                                 pDlg = (DLGTEMPLATE*) ::LockResource(hResource); | 
 |  4783                                 if (pDlg != NULL) | 
 |  4784                                 { | 
 |  4785                                         // Get first control on the template | 
 |  4786                                         BOOL bDialogEx = ATL::_DialogSplitHelper
      ::IsDialogEx(pDlg); | 
 |  4787                                         WORD nItems = ATL::_DialogSplitHelper::D
      lgTemplateItemCount(pDlg); | 
 |  4788  | 
 |  4789                                         // Get first control on the dialog | 
 |  4790                                         DLGITEMTEMPLATE* pItem = ATL::_DialogSpl
      itHelper::FindFirstDlgItem(pDlg); | 
 |  4791                                         HWND hWndPrev = GetWindow(GW_CHILD); | 
 |  4792  | 
 |  4793                                         // Create all ActiveX cotnrols in the di
      alog template and place them in the correct tab order (z-order) | 
 |  4794                                         for (WORD nItem = 0; nItem < nItems; nIt
      em++) | 
 |  4795                                         { | 
 |  4796                                                 DWORD wID = bDialogEx ? ((ATL::_
      DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : pItem->id; | 
 |  4797                                                 if (ATL::_DialogSplitHelper::IsA
      ctiveXControl(pItem, bDialogEx)) | 
 |  4798                                                 { | 
 |  4799                                                         BYTE* pData = NULL; | 
 |  4800                                                         DWORD dwLen = ATL::_Dial
      ogSplitHelper::FindCreateData(wID, pInitData, &pData); | 
 |  4801                                                         ATL::CComPtr<IStream> sp
      Stream; | 
 |  4802                                                         if (dwLen != 0) | 
 |  4803                                                         { | 
 |  4804                                                                 HGLOBAL h = Glob
      alAlloc(GHND, dwLen); | 
 |  4805                                                                 if (h != NULL) | 
 |  4806                                                                 { | 
 |  4807                                                                         BYTE* pB
      ytes = (BYTE*) GlobalLock(h); | 
 |  4808                                                                         BYTE* pS
      ource = pData;  | 
 |  4809                                                                         SecureHe
      lper::memcpy_x(pBytes, dwLen, pSource, dwLen); | 
 |  4810                                                                         GlobalUn
      lock(h); | 
 |  4811                                                                         CreateSt
      reamOnHGlobal(h, TRUE, &spStream); | 
 |  4812                                                                 } | 
 |  4813                                                                 else | 
 |  4814                                                                 { | 
 |  4815                                                                         hr = E_O
      UTOFMEMORY; | 
 |  4816                                                                         break; | 
 |  4817                                                                 } | 
 |  4818                                                         } | 
 |  4819  | 
 |  4820                                                         ATL::CComBSTR bstrLicKey
      ; | 
 |  4821                                                         hr = ATL::_DialogSplitHe
      lper::ParseInitData(spStream, &bstrLicKey.m_str); | 
 |  4822                                                         if (SUCCEEDED(hr)) | 
 |  4823                                                         { | 
 |  4824                                                                 ATL::CAxWindow2 
      wnd; | 
 |  4825                                                                 // Get control c
      aption. | 
 |  4826                                                                 LPWSTR pszClassN
      ame =  | 
 |  4827                                                                         bDialogE
      x ?  | 
 |  4828                                                                                 
      (LPWSTR)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem) + 1) : | 
 |  4829                                                                                 
      (LPWSTR)(pItem + 1); | 
 |  4830                                                                 // Get control r
      ect. | 
 |  4831                                                                 RECT rect; | 
 |  4832                                                                 rect.left =  | 
 |  4833                                                                         bDialogE
      x ?  | 
 |  4834                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->x :  | 
 |  4835                                                                                 
      pItem->x; | 
 |  4836                                                                 rect.top =  | 
 |  4837                                                                         bDialogE
      x ?  | 
 |  4838                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->y :  | 
 |  4839                                                                                 
      pItem->y; | 
 |  4840                                                                 rect.right = rec
      t.left +  | 
 |  4841                                                                         (bDialog
      Ex ?  | 
 |  4842                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cx :  | 
 |  4843                                                                                 
      pItem->cx); | 
 |  4844                                                                 rect.bottom = re
      ct.top +  | 
 |  4845                                                                         (bDialog
      Ex ?  | 
 |  4846                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cy :  | 
 |  4847                                                                                 
      pItem->cy); | 
 |  4848  | 
 |  4849                                                                 // Convert from 
      dialog units to screen units | 
 |  4850                                                                 MapDialogRect(&r
      ect); | 
 |  4851  | 
 |  4852                                                                 // Create AxWind
      ow with a NULL caption. | 
 |  4853                                                                 wnd.Create(m_hWn
      d,  | 
 |  4854                                                                         &rect,  | 
 |  4855                                                                         NULL,  | 
 |  4856                                                                         (bDialog
      Ex ?  | 
 |  4857                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->style :  | 
 |  4858                                                                                 
      pItem->style) | WS_TABSTOP,  | 
 |  4859                                                                         bDialogE
      x ?  | 
 |  4860                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->exStyle :  | 
 |  4861                                                                                 
      0, | 
 |  4862                                                                         bDialogE
      x ?  | 
 |  4863                                                                                 
      ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id :  | 
 |  4864                                                                                 
      pItem->id, | 
 |  4865                                                                         NULL); | 
 |  4866  | 
 |  4867                                                                 if (wnd != NULL) | 
 |  4868                                                                 { | 
 |  4869 #ifndef _WIN32_WCE | 
 |  4870                                                                         // Set t
      he Help ID | 
 |  4871                                                                         if (bDia
      logEx && ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID != 0) | 
 |  4872                                                                                 
      wnd.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)-
      >helpID); | 
 |  4873 #endif // !_WIN32_WCE | 
 |  4874                                                                         // Try t
      o create the ActiveX control. | 
 |  4875                                                                         hr = wnd
      .CreateControlLic(pszClassName, spStream, NULL, bstrLicKey); | 
 |  4876                                                                         if (FAIL
      ED(hr)) | 
 |  4877                                                                                 
      break; | 
 |  4878                                                                         // Set t
      he correct tab position. | 
 |  4879                                                                         if (nIte
      m == 0) | 
 |  4880                                                                                 
      hWndPrev = HWND_TOP; | 
 |  4881                                                                         wnd.SetW
      indowPos(hWndPrev, 0,0,0,0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | 
 |  4882                                                                         hWndPrev
       = wnd; | 
 |  4883                                                                 } | 
 |  4884                                                                 else | 
 |  4885                                                                 { | 
 |  4886                                                                         hr = ATL
      ::AtlHresultFromLastError(); | 
 |  4887                                                                 } | 
 |  4888                                                         } | 
 |  4889                                                 } | 
 |  4890                                                 else | 
 |  4891                                                 { | 
 |  4892                                                         if (nItem != 0) | 
 |  4893                                                                 hWndPrev = ::Get
      Window(hWndPrev, GW_HWNDNEXT); | 
 |  4894                                                 } | 
 |  4895                                                 pItem = ATL::_DialogSplitHelper:
      :FindNextDlgItem(pItem, bDialogEx); | 
 |  4896                                         } | 
 |  4897                                 } | 
 |  4898                                 else | 
 |  4899                                         hr = ATL::AtlHresultFromLastError(); | 
 |  4900                         } | 
 |  4901                         else | 
 |  4902                                 hr = ATL::AtlHresultFromLastError(); | 
 |  4903                 } | 
 |  4904                 return hr; | 
 |  4905         } | 
 |  4906  | 
 |  4907 // Event handling support | 
 |  4908         HRESULT AdviseSinkMap(bool bAdvise) | 
 |  4909         { | 
 |  4910                 if(!bAdvise && m_hWnd == NULL) | 
 |  4911                 { | 
 |  4912                         // window is gone, controls are already unadvised | 
 |  4913                         ATLTRACE2(atlTraceUI, 0, _T("CAxPropertyPageImpl::Advise
      SinkMap called after the window was destroyed\n")); | 
 |  4914                         return S_OK; | 
 |  4915                 } | 
 |  4916                 HRESULT hRet = E_NOTIMPL; | 
 |  4917                 __if_exists(T::_GetSinkMapFinder) | 
 |  4918                 { | 
 |  4919                         T* pT = static_cast<T*>(this); | 
 |  4920                         hRet = AtlAdviseSinkMap(pT, bAdvise); | 
 |  4921                 } | 
 |  4922                 return hRet; | 
 |  4923         } | 
 |  4924  | 
 |  4925 // Message map and handlers | 
 |  4926         typedef CPropertyPageImpl< T, TBase>   _baseClass; | 
 |  4927         BEGIN_MSG_MAP(CAxPropertyPageImpl) | 
 |  4928                 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) | 
 |  4929                 MESSAGE_HANDLER(WM_DESTROY, OnDestroy) | 
 |  4930                 CHAIN_MSG_MAP(_baseClass) | 
 |  4931         END_MSG_MAP() | 
 |  4932  | 
 |  4933         LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/
      , BOOL& bHandled) | 
 |  4934         { | 
 |  4935                 // initialize controls in dialog with DLGINIT resource section | 
 |  4936                 ExecuteDlgInit(static_cast<T*>(this)->IDD); | 
 |  4937                 AdviseSinkMap(true); | 
 |  4938                 bHandled = FALSE; | 
 |  4939                 return 1; | 
 |  4940         } | 
 |  4941  | 
 |  4942         LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, B
      OOL& bHandled) | 
 |  4943         { | 
 |  4944                 AdviseSinkMap(false); | 
 |  4945                 bHandled = FALSE; | 
 |  4946                 return 1; | 
 |  4947         } | 
 |  4948 #endif // (_ATL_VER >= 0x0700) | 
 |  4949 }; | 
 |  4950  | 
 |  4951 // for non-customized pages | 
 |  4952 template <WORD t_wDlgTemplateID> | 
 |  4953 class CAxPropertyPage : public CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplat
      eID> > | 
 |  4954 { | 
 |  4955 public: | 
 |  4956         enum { IDD = t_wDlgTemplateID }; | 
 |  4957  | 
 |  4958         CAxPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyP
      ageImpl<CAxPropertyPage>(title) | 
 |  4959         { } | 
 |  4960  | 
 |  4961 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) | 
 |  4962         // not empty so we handle accelerators/create controls | 
 |  4963         BEGIN_MSG_MAP(CAxPropertyPage) | 
 |  4964                 CHAIN_MSG_MAP(CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplate
      ID> >) | 
 |  4965         END_MSG_MAP() | 
 |  4966 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) | 
 |  4967         DECLARE_EMPTY_MSG_MAP() | 
 |  4968 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) | 
 |  4969 }; | 
 |  4970  | 
 |  4971 #endif // _ATL_NO_HOSTING | 
 |  4972  | 
 |  4973  | 
 |  4974 /////////////////////////////////////////////////////////////////////////////// | 
 |  4975 // Wizard97 Support | 
 |  4976  | 
 |  4977 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  4978  | 
 |  4979 // Sample wizard dialog resources: | 
 |  4980 // | 
 |  4981 // IDD_WIZ97_INTERIOR_BLANK DIALOG  0, 0, 317, 143 | 
 |  4982 // STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION | 
 |  4983 // CAPTION "Wizard97 Property Page - Interior" | 
 |  4984 // FONT 8, "MS Shell Dlg" | 
 |  4985 // BEGIN | 
 |  4986 // END | 
 |  4987 // | 
 |  4988 // IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193 | 
 |  4989 // STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION | 
 |  4990 // CAPTION "Wizard97 Property Page - Welcome/Complete" | 
 |  4991 // FONT 8, "MS Shell Dlg", 0, 0, 0x0 | 
 |  4992 // BEGIN | 
 |  4993 //    LTEXT           "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8, | 
 |  4994 //                    195,24 | 
 |  4995 //    LTEXT           "Wizard Explanation\r\n(The height of the static text shou
      ld be in multiples of 8 dlus)", | 
 |  4996 //                    IDC_STATIC,115,40,195,16 | 
 |  4997 //    LTEXT           "h",IDC_WIZ97_BULLET1,118,64,8,8 | 
 |  4998 //    LTEXT           "List Item 1 (the h is turned into a bullet)",IDC_STATIC, | 
 |  4999 //                    127,63,122,8 | 
 |  5000 //    LTEXT           "h",IDC_WIZ97_BULLET2,118,79,8,8 | 
 |  5001 //    LTEXT           "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC, | 
 |  5002 //                    127,78,33,8 | 
 |  5003 //    CONTROL         "&Do not show this Welcome page again", | 
 |  5004 //                    IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX |  | 
 |  5005 //                    WS_TABSTOP,115,169,138,10 | 
 |  5006 // END | 
 |  5007 // | 
 |  5008 // GUIDELINES DESIGNINFO  | 
 |  5009 // BEGIN | 
 |  5010 //    IDD_WIZ97_INTERIOR_BLANK, DIALOG | 
 |  5011 //    BEGIN | 
 |  5012 //        LEFTMARGIN, 7 | 
 |  5013 //        RIGHTMARGIN, 310 | 
 |  5014 //        VERTGUIDE, 21 | 
 |  5015 //        VERTGUIDE, 31 | 
 |  5016 //        VERTGUIDE, 286 | 
 |  5017 //        VERTGUIDE, 296 | 
 |  5018 //        TOPMARGIN, 7 | 
 |  5019 //        BOTTOMMARGIN, 136 | 
 |  5020 //        HORZGUIDE, 8 | 
 |  5021 //    END | 
 |  5022 // | 
 |  5023 //    IDD_WIZ97_EXTERIOR_BLANK, DIALOG | 
 |  5024 //    BEGIN | 
 |  5025 //        RIGHTMARGIN, 310 | 
 |  5026 //        VERTGUIDE, 115 | 
 |  5027 //        VERTGUIDE, 118 | 
 |  5028 //        VERTGUIDE, 127 | 
 |  5029 //        TOPMARGIN, 7 | 
 |  5030 //        BOTTOMMARGIN, 186 | 
 |  5031 //        HORZGUIDE, 8 | 
 |  5032 //        HORZGUIDE, 32 | 
 |  5033 //        HORZGUIDE, 40 | 
 |  5034 //        HORZGUIDE, 169 | 
 |  5035 //    END | 
 |  5036 // END | 
 |  5037  | 
 |  5038 /////////////////////////////////////////////////////////////////////////////// | 
 |  5039 // CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet | 
 |  5040  | 
 |  5041 class CWizard97SheetWindow : public CPropertySheetWindow | 
 |  5042 { | 
 |  5043 public: | 
 |  5044 // Constructors | 
 |  5045         CWizard97SheetWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) | 
 |  5046         { } | 
 |  5047  | 
 |  5048         CWizard97SheetWindow& operator =(HWND hWnd) | 
 |  5049         { | 
 |  5050                 m_hWnd = hWnd; | 
 |  5051                 return *this; | 
 |  5052         } | 
 |  5053  | 
 |  5054 // Operations | 
 |  5055         HFONT GetExteriorPageTitleFont(void) | 
 |  5056         { | 
 |  5057                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5058                 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetExteriorPageTi
      tleFont(), 0, 0L); | 
 |  5059         } | 
 |  5060  | 
 |  5061         HFONT GetBulletFont(void) | 
 |  5062         { | 
 |  5063                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5064                 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetBulletFont(), 
      0, 0L); | 
 |  5065         } | 
 |  5066  | 
 |  5067 // Helpers | 
 |  5068         static UINT GetMessage_GetExteriorPageTitleFont() | 
 |  5069         { | 
 |  5070                 static UINT uGetExteriorPageTitleFont = 0; | 
 |  5071                 if(uGetExteriorPageTitleFont == 0) | 
 |  5072                 { | 
 |  5073                         CStaticDataInitCriticalSectionLock lock; | 
 |  5074                         if(FAILED(lock.Lock())) | 
 |  5075                         { | 
 |  5076                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFon
      t().\n")); | 
 |  5077                                 ATLASSERT(FALSE); | 
 |  5078                                 return 0; | 
 |  5079                         } | 
 |  5080  | 
 |  5081                         if(uGetExteriorPageTitleFont == 0) | 
 |  5082                                 uGetExteriorPageTitleFont = ::RegisterWindowMess
      age(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12")); | 
 |  5083  | 
 |  5084                         lock.Unlock(); | 
 |  5085                 } | 
 |  5086                 ATLASSERT(uGetExteriorPageTitleFont != 0); | 
 |  5087                 return uGetExteriorPageTitleFont; | 
 |  5088         } | 
 |  5089  | 
 |  5090         static UINT GetMessage_GetBulletFont() | 
 |  5091         { | 
 |  5092                 static UINT uGetBulletFont = 0; | 
 |  5093                 if(uGetBulletFont == 0) | 
 |  5094                 { | 
 |  5095                         CStaticDataInitCriticalSectionLock lock; | 
 |  5096                         if(FAILED(lock.Lock())) | 
 |  5097                         { | 
 |  5098                                 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to l
      ock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n")); | 
 |  5099                                 ATLASSERT(FALSE); | 
 |  5100                                 return 0; | 
 |  5101                         } | 
 |  5102  | 
 |  5103                         if(uGetBulletFont == 0) | 
 |  5104                                 uGetBulletFont = ::RegisterWindowMessage(_T("Get
      BulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5")); | 
 |  5105  | 
 |  5106                         lock.Unlock(); | 
 |  5107                 } | 
 |  5108                 ATLASSERT(uGetBulletFont != 0); | 
 |  5109                 return uGetBulletFont; | 
 |  5110         } | 
 |  5111  | 
 |  5112 // Implementation - override to prevent usage | 
 |  5113         HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 
      0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) | 
 |  5114         { | 
 |  5115                 ATLASSERT(FALSE); | 
 |  5116                 return NULL; | 
 |  5117         } | 
 |  5118 }; | 
 |  5119  | 
 |  5120  | 
 |  5121 /////////////////////////////////////////////////////////////////////////////// | 
 |  5122 // CWizard97SheetImpl - implements a Wizard 97 style wizard sheet | 
 |  5123  | 
 |  5124 template <class T, class TBase = CWizard97SheetWindow> | 
 |  5125 class ATL_NO_VTABLE CWizard97SheetImpl : public CPropertySheetImpl< T, TBase > | 
 |  5126 { | 
 |  5127 protected: | 
 |  5128 // Typedefs | 
 |  5129         typedef CWizard97SheetImpl< T, TBase > thisClass; | 
 |  5130         typedef CPropertySheetImpl< T, TBase > baseClass; | 
 |  5131  | 
 |  5132 // Member variables | 
 |  5133         CFont m_fontExteriorPageTitle;   // Welcome and Completion page title fo
      nt | 
 |  5134         CFont m_fontBullet;              // Bullet font (used on static text 'h'
       to produce a small bullet) | 
 |  5135         bool m_bReceivedFirstSizeMessage;    | 
 |  5136  | 
 |  5137 public: | 
 |  5138         CWizard97SheetImpl(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBi
      tmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent =
       NULL) : | 
 |  5139                         baseClass(title, uStartPage, hWndParent), | 
 |  5140                         m_bReceivedFirstSizeMessage(false) | 
 |  5141         { | 
 |  5142                 m_psh.dwFlags &= ~(PSH_NOCONTEXTHELP); | 
 |  5143                 m_psh.dwFlags &= ~(PSH_WIZARD | PSH_WIZARD_LITE); | 
 |  5144  | 
 |  5145                 m_psh.dwFlags |= (PSH_HASHELP | PSH_WIZARDCONTEXTHELP); | 
 |  5146                 m_psh.dwFlags |= PSH_WIZARD97; | 
 |  5147  | 
 |  5148                 baseClass::SetHeader(headerBitmap.m_lpstr); | 
 |  5149                 baseClass::SetWatermark(watermarkBitmap.m_lpstr); | 
 |  5150         } | 
 |  5151  | 
 |  5152 // Overrides from base class | 
 |  5153         void OnSheetInitialized() | 
 |  5154         { | 
 |  5155                 T* pT = static_cast<T*>(this); | 
 |  5156                 pT->_InitializeFonts(); | 
 |  5157  | 
 |  5158                 // We'd like to center the wizard here, but its too early. | 
 |  5159                 // Instead, we'll do CenterWindow upon our first WM_SIZE message | 
 |  5160         } | 
 |  5161  | 
 |  5162 // Initialization | 
 |  5163         void _InitializeFonts() | 
 |  5164         { | 
 |  5165                 // Setup the Title and Bullet Font | 
 |  5166                 // (Property pages can send the "get external page title font" a
      nd "get bullet font" messages) | 
 |  5167                 // The derived class needs to do the actual SetFont for the dial
      og items) | 
 |  5168  | 
 |  5169                 CFontHandle fontThisDialog = this->GetFont(); | 
 |  5170                 CClientDC dcScreen(NULL); | 
 |  5171  | 
 |  5172                 LOGFONT titleLogFont = {0}; | 
 |  5173                 LOGFONT bulletLogFont = {0}; | 
 |  5174                 fontThisDialog.GetLogFont(&titleLogFont); | 
 |  5175                 fontThisDialog.GetLogFont(&bulletLogFont); | 
 |  5176  | 
 |  5177                 // The Wizard 97 Spec recommends to do the Title Font | 
 |  5178                 // as Verdana Bold, 12pt. | 
 |  5179                 titleLogFont.lfCharSet = DEFAULT_CHARSET; | 
 |  5180                 titleLogFont.lfWeight = FW_BOLD; | 
 |  5181                 SecureHelper::strcpy_x(titleLogFont.lfFaceName, _countof(titleLo
      gFont.lfFaceName), _T("Verdana Bold")); | 
 |  5182                 INT titleFontPointSize = 12; | 
 |  5183                 titleLogFont.lfHeight = -::MulDiv(titleFontPointSize, dcScreen.G
      etDeviceCaps(LOGPIXELSY), 72); | 
 |  5184                 m_fontExteriorPageTitle.CreateFontIndirect(&titleLogFont); | 
 |  5185  | 
 |  5186                 // The Wizard 97 Spec recommends to do Bullets by having | 
 |  5187                 // static text of "h" in the Marlett font. | 
 |  5188                 bulletLogFont.lfCharSet = DEFAULT_CHARSET; | 
 |  5189                 bulletLogFont.lfWeight = FW_NORMAL; | 
 |  5190                 SecureHelper::strcpy_x(bulletLogFont.lfFaceName, _countof(bullet
      LogFont.lfFaceName), _T("Marlett")); | 
 |  5191                 INT bulletFontSize = 8; | 
 |  5192                 bulletLogFont.lfHeight = -::MulDiv(bulletFontSize, dcScreen.GetD
      eviceCaps(LOGPIXELSY), 72); | 
 |  5193                 m_fontBullet.CreateFontIndirect(&bulletLogFont); | 
 |  5194         } | 
 |  5195  | 
 |  5196 // Message Handling | 
 |  5197         BEGIN_MSG_MAP(thisClass) | 
 |  5198                 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPage
      TitleFont(), OnGetExteriorPageTitleFont) | 
 |  5199                 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont()
      , OnGetBulletFont) | 
 |  5200                 MESSAGE_HANDLER(WM_SIZE, OnSize) | 
 |  5201                 CHAIN_MSG_MAP(baseClass) | 
 |  5202         END_MSG_MAP() | 
 |  5203  | 
 |  5204         LRESULT OnGetExteriorPageTitleFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPA
      RAM /*lParam*/, BOOL& /*bHandled*/) | 
 |  5205         { | 
 |  5206                 return (LRESULT)(HFONT)m_fontExteriorPageTitle; | 
 |  5207         } | 
 |  5208  | 
 |  5209         LRESULT OnGetBulletFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lPara
      m*/, BOOL& /*bHandled*/) | 
 |  5210         { | 
 |  5211                 return (LRESULT)(HFONT)m_fontBullet; | 
 |  5212         } | 
 |  5213  | 
 |  5214         LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL
      & bHandled) | 
 |  5215         { | 
 |  5216                 if(!m_bReceivedFirstSizeMessage) | 
 |  5217                 { | 
 |  5218                         m_bReceivedFirstSizeMessage = true; | 
 |  5219                         this->CenterWindow(); | 
 |  5220                 } | 
 |  5221  | 
 |  5222                 bHandled = FALSE; | 
 |  5223                 return 0; | 
 |  5224         } | 
 |  5225 }; | 
 |  5226  | 
 |  5227 // for non-customized sheets | 
 |  5228 class CWizard97Sheet : public CWizard97SheetImpl<CWizard97Sheet> | 
 |  5229 { | 
 |  5230 protected: | 
 |  5231 // Typedefs | 
 |  5232         typedef CWizard97Sheet thisClass; | 
 |  5233         typedef CWizard97SheetImpl<CWizard97Sheet> baseClass; | 
 |  5234  | 
 |  5235 public: | 
 |  5236         CWizard97Sheet(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap
      , ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NUL
      L) : | 
 |  5237                 baseClass(title, headerBitmap, watermarkBitmap, uStartPage, hWnd
      Parent) | 
 |  5238         { } | 
 |  5239  | 
 |  5240         BEGIN_MSG_MAP(thisClass) | 
 |  5241                 CHAIN_MSG_MAP(baseClass) | 
 |  5242         END_MSG_MAP() | 
 |  5243 }; | 
 |  5244  | 
 |  5245  | 
 |  5246 /////////////////////////////////////////////////////////////////////////////// | 
 |  5247 // CWizard97PageWindow - client side for a Wizard 97 style wizard page | 
 |  5248  | 
 |  5249 #define WIZARD97_EXTERIOR_CXDLG 317 | 
 |  5250 #define WIZARD97_EXTERIOR_CYDLG 193 | 
 |  5251  | 
 |  5252 #define WIZARD97_INTERIOR_CXDLG 317 | 
 |  5253 #define WIZARD97_INTERIOR_CYDLG 143 | 
 |  5254  | 
 |  5255 class CWizard97PageWindow : public CPropertyPageWindow | 
 |  5256 { | 
 |  5257 public: | 
 |  5258 // Constructors | 
 |  5259         CWizard97PageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) | 
 |  5260         { } | 
 |  5261  | 
 |  5262         CWizard97PageWindow& operator =(HWND hWnd) | 
 |  5263         { | 
 |  5264                 m_hWnd = hWnd; | 
 |  5265                 return *this; | 
 |  5266         } | 
 |  5267  | 
 |  5268 // Attributes | 
 |  5269         CWizard97SheetWindow GetPropertySheet() const | 
 |  5270         { | 
 |  5271                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5272                 return CWizard97SheetWindow(GetParent()); | 
 |  5273         } | 
 |  5274  | 
 |  5275 // Operations | 
 |  5276         HFONT GetExteriorPageTitleFont(void) | 
 |  5277         { | 
 |  5278                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5279                 return GetPropertySheet().GetExteriorPageTitleFont(); | 
 |  5280         } | 
 |  5281  | 
 |  5282         HFONT GetBulletFont(void) | 
 |  5283         { | 
 |  5284                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5285                 return GetPropertySheet().GetBulletFont(); | 
 |  5286         } | 
 |  5287  | 
 |  5288 // Implementation - overrides to prevent usage | 
 |  5289         HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 
      0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL) | 
 |  5290         { | 
 |  5291                 ATLASSERT(FALSE); | 
 |  5292                 return NULL; | 
 |  5293         } | 
 |  5294  | 
 |  5295 }; | 
 |  5296  | 
 |  5297  | 
 |  5298 /////////////////////////////////////////////////////////////////////////////// | 
 |  5299 // CWizard97PageImpl - implements a Wizard 97 style wizard page | 
 |  5300  | 
 |  5301 template <class T, class TBase = CWizard97PageWindow> | 
 |  5302 class ATL_NO_VTABLE CWizard97PageImpl : public CPropertyPageImpl< T, TBase > | 
 |  5303 { | 
 |  5304 protected: | 
 |  5305 // Typedefs | 
 |  5306         typedef CWizard97PageImpl< T, TBase > thisClass; | 
 |  5307         typedef CPropertyPageImpl< T, TBase > baseClass; | 
 |  5308  | 
 |  5309 public: | 
 |  5310         CWizard97PageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(
      title) | 
 |  5311         { } | 
 |  5312  | 
 |  5313 // Message Handling | 
 |  5314         BEGIN_MSG_MAP(thisClass) | 
 |  5315                 CHAIN_MSG_MAP(baseClass) | 
 |  5316         END_MSG_MAP() | 
 |  5317 }; | 
 |  5318  | 
 |  5319  | 
 |  5320 /////////////////////////////////////////////////////////////////////////////// | 
 |  5321 // CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page | 
 |  5322  | 
 |  5323 template <class T, class TBase = CWizard97PageWindow> | 
 |  5324 class ATL_NO_VTABLE CWizard97ExteriorPageImpl : public CPropertyPageImpl< T, TBa
      se > | 
 |  5325 { | 
 |  5326 protected: | 
 |  5327 // Typedefs | 
 |  5328         typedef CWizard97ExteriorPageImpl< T, TBase > thisClass; | 
 |  5329         typedef CPropertyPageImpl< T, TBase > baseClass; | 
 |  5330  | 
 |  5331 public: | 
 |  5332 // Constructors | 
 |  5333         CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : ba
      seClass(title) | 
 |  5334         { | 
 |  5335                 m_psp.dwFlags |= PSP_HASHELP; | 
 |  5336                 m_psp.dwFlags |= PSP_HIDEHEADER; | 
 |  5337         } | 
 |  5338  | 
 |  5339 // Message Handling | 
 |  5340         BEGIN_MSG_MAP(thisClass) | 
 |  5341                 CHAIN_MSG_MAP(baseClass) | 
 |  5342         END_MSG_MAP() | 
 |  5343 }; | 
 |  5344  | 
 |  5345  | 
 |  5346 /////////////////////////////////////////////////////////////////////////////// | 
 |  5347 // CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page | 
 |  5348  | 
 |  5349 template <class T, class TBase = CWizard97PageWindow> | 
 |  5350 class ATL_NO_VTABLE CWizard97InteriorPageImpl : public CPropertyPageImpl< T, TBa
      se > | 
 |  5351 { | 
 |  5352 protected: | 
 |  5353 // Typedefs | 
 |  5354         typedef CWizard97InteriorPageImpl< T, TBase > thisClass; | 
 |  5355         typedef CPropertyPageImpl< T, TBase > baseClass; | 
 |  5356  | 
 |  5357 public: | 
 |  5358 // Constructors | 
 |  5359         CWizard97InteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : ba
      seClass(title) | 
 |  5360         { | 
 |  5361                 m_psp.dwFlags |= PSP_HASHELP; | 
 |  5362                 m_psp.dwFlags &= ~PSP_HIDEHEADER; | 
 |  5363                 m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE; | 
 |  5364  | 
 |  5365                 // Be sure to have the derived class define this in the construc
      tor. | 
 |  5366                 // We'll default it to something obvious in case its forgotten. | 
 |  5367                 baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Cla
      ss")); | 
 |  5368                 baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the c
      onstructor of the Derived Class.")); | 
 |  5369         } | 
 |  5370  | 
 |  5371 // Message Handling | 
 |  5372         BEGIN_MSG_MAP(thisClass) | 
 |  5373                 CHAIN_MSG_MAP(baseClass) | 
 |  5374         END_MSG_MAP() | 
 |  5375 }; | 
 |  5376  | 
 |  5377 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE) | 
 |  5378  | 
 |  5379  | 
 |  5380 /////////////////////////////////////////////////////////////////////////////// | 
 |  5381 // Aero Wizard support | 
 |  5382  | 
 |  5383 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |  5384  | 
 |  5385 /////////////////////////////////////////////////////////////////////////////// | 
 |  5386 // CAeroWizardFrameWindow - client side for an Aero Wizard frame window | 
 |  5387  | 
 |  5388 class CAeroWizardFrameWindow : public CPropertySheetWindow | 
 |  5389 { | 
 |  5390 public: | 
 |  5391 // Constructors | 
 |  5392         CAeroWizardFrameWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd) | 
 |  5393         { } | 
 |  5394  | 
 |  5395         CAeroWizardFrameWindow& operator =(HWND hWnd) | 
 |  5396         { | 
 |  5397                 m_hWnd = hWnd; | 
 |  5398                 return *this; | 
 |  5399         } | 
 |  5400  | 
 |  5401 // Operations - new, Aero Wizard only | 
 |  5402         void SetNextText(LPCWSTR lpszText) | 
 |  5403         { | 
 |  5404                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5405                 ::SendMessage(m_hWnd, PSM_SETNEXTTEXT, 0, (LPARAM)lpszText); | 
 |  5406         } | 
 |  5407  | 
 |  5408         void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) | 
 |  5409         { | 
 |  5410                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5411                 ::PostMessage(m_hWnd, PSM_SHOWWIZBUTTONS, (WPARAM)dwStates, (LPA
      RAM)dwButtons); | 
 |  5412         } | 
 |  5413  | 
 |  5414         void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) | 
 |  5415         { | 
 |  5416                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5417                 ::PostMessage(m_hWnd, PSM_ENABLEWIZBUTTONS, (WPARAM)dwStates, (L
      PARAM)dwButtons); | 
 |  5418         } | 
 |  5419  | 
 |  5420         void SetButtonText(DWORD dwButton, LPCWSTR lpszText) | 
 |  5421         { | 
 |  5422                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5423                 ::SendMessage(m_hWnd, PSM_SETBUTTONTEXT, (WPARAM)dwButton, (LPAR
      AM)lpszText); | 
 |  5424         } | 
 |  5425 }; | 
 |  5426  | 
 |  5427  | 
 |  5428 /////////////////////////////////////////////////////////////////////////////// | 
 |  5429 // CAeroWizardFrameImpl - implements an Aero Wizard frame | 
 |  5430  | 
 |  5431 template <class T, class TBase = CAeroWizardFrameWindow> | 
 |  5432 class ATL_NO_VTABLE CAeroWizardFrameImpl : public CPropertySheetImpl<T, TBase > | 
 |  5433 { | 
 |  5434 public: | 
 |  5435 // Constructor | 
 |  5436         CAeroWizardFrameImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uSta
      rtPage = 0, HWND hWndParent = NULL) : | 
 |  5437                 CPropertySheetImpl<T, TBase >(title, uStartPage, hWndParent) | 
 |  5438         { | 
 |  5439                 m_psh.dwFlags |= PSH_WIZARD | PSH_AEROWIZARD; | 
 |  5440         } | 
 |  5441  | 
 |  5442 // Operations | 
 |  5443         void EnableResizing() | 
 |  5444         { | 
 |  5445                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  5446                 m_psh.dwFlags |= PSH_RESIZABLE; | 
 |  5447         } | 
 |  5448  | 
 |  5449         void UseHeaderBitmap() | 
 |  5450         { | 
 |  5451                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  5452                 m_psh.dwFlags |= PSH_HEADERBITMAP; | 
 |  5453         } | 
 |  5454  | 
 |  5455         void SetNoMargin() | 
 |  5456         { | 
 |  5457                 ATLASSERT(m_hWnd == NULL);   // can't do this after it's created | 
 |  5458                 m_psh.dwFlags |= PSH_NOMARGIN; | 
 |  5459         } | 
 |  5460  | 
 |  5461 // Override to prevent use | 
 |  5462         HWND Create(HWND /*hWndParent*/ = NULL) | 
 |  5463         { | 
 |  5464                 ATLASSERT(FALSE);   // not supported for Aero Wizard | 
 |  5465                 return NULL; | 
 |  5466         } | 
 |  5467 }; | 
 |  5468  | 
 |  5469  | 
 |  5470 /////////////////////////////////////////////////////////////////////////////// | 
 |  5471 // CAeroWizardFrame - for non-customized frames | 
 |  5472  | 
 |  5473 class CAeroWizardFrame : public CAeroWizardFrameImpl<CAeroWizardFrame> | 
 |  5474 { | 
 |  5475 public: | 
 |  5476         CAeroWizardFrame(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPa
      ge = 0, HWND hWndParent = NULL) | 
 |  5477                 : CAeroWizardFrameImpl<CAeroWizardFrame>(title, uStartPage, hWnd
      Parent) | 
 |  5478         { } | 
 |  5479  | 
 |  5480         BEGIN_MSG_MAP(CAeroWizardFrame) | 
 |  5481                 MESSAGE_HANDLER(WM_COMMAND, CAeroWizardFrameImpl<CAeroWizardFram
      e>::OnCommand) | 
 |  5482         END_MSG_MAP() | 
 |  5483 }; | 
 |  5484  | 
 |  5485  | 
 |  5486 /////////////////////////////////////////////////////////////////////////////// | 
 |  5487 // CAeroWizardPageWindow - client side for an Aero Wizard page | 
 |  5488  | 
 |  5489 class CAeroWizardPageWindow : public CPropertyPageWindow | 
 |  5490 { | 
 |  5491 public: | 
 |  5492 // Constructors | 
 |  5493         CAeroWizardPageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd) | 
 |  5494         { } | 
 |  5495  | 
 |  5496         CAeroWizardPageWindow& operator =(HWND hWnd) | 
 |  5497         { | 
 |  5498                 m_hWnd = hWnd; | 
 |  5499                 return *this; | 
 |  5500         } | 
 |  5501  | 
 |  5502 // Attributes | 
 |  5503         CAeroWizardFrameWindow GetAeroWizardFrame() const | 
 |  5504         { | 
 |  5505                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5506                 // This is not really top-level frame window, but it processes a
      ll frame messages | 
 |  5507                 return CAeroWizardFrameWindow(GetParent()); | 
 |  5508         } | 
 |  5509  | 
 |  5510 // Operations - new, Aero Wizard only | 
 |  5511         void SetNextText(LPCWSTR lpszText) | 
 |  5512         { | 
 |  5513                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5514                 ATLASSERT(GetParent() != NULL); | 
 |  5515                 GetAeroWizardFrame().SetNextText(lpszText); | 
 |  5516         } | 
 |  5517  | 
 |  5518         void ShowWizardButtons(DWORD dwButtons, DWORD dwStates) | 
 |  5519         { | 
 |  5520                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5521                 ATLASSERT(GetParent() != NULL); | 
 |  5522                 GetAeroWizardFrame().ShowWizardButtons(dwButtons, dwStates); | 
 |  5523         } | 
 |  5524  | 
 |  5525         void EnableWizardButtons(DWORD dwButtons, DWORD dwStates) | 
 |  5526         { | 
 |  5527                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5528                 ATLASSERT(GetParent() != NULL); | 
 |  5529                 GetAeroWizardFrame().EnableWizardButtons(dwButtons, dwStates); | 
 |  5530         } | 
 |  5531  | 
 |  5532         void SetButtonText(DWORD dwButton, LPCWSTR lpszText) | 
 |  5533         { | 
 |  5534                 ATLASSERT(::IsWindow(m_hWnd)); | 
 |  5535                 ATLASSERT(GetParent() != NULL); | 
 |  5536                 GetAeroWizardFrame().SetButtonText(dwButton, lpszText); | 
 |  5537         } | 
 |  5538 }; | 
 |  5539  | 
 |  5540  | 
 |  5541 /////////////////////////////////////////////////////////////////////////////// | 
 |  5542 // CAeroWizardPageImpl - implements an Aero Wizard page | 
 |  5543  | 
 |  5544 template <class T, class TBase = CAeroWizardPageWindow> | 
 |  5545 class ATL_NO_VTABLE CAeroWizardPageImpl : public CPropertyPageImpl<T, TBase > | 
 |  5546 { | 
 |  5547 public: | 
 |  5548         CAeroWizardPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropert
      yPageImpl<T, TBase >(title) | 
 |  5549         { } | 
 |  5550 }; | 
 |  5551  | 
 |  5552  | 
 |  5553 /////////////////////////////////////////////////////////////////////////////// | 
 |  5554 // CAeroWizardPage - for non-customized pages | 
 |  5555  | 
 |  5556 template <WORD t_wDlgTemplateID> | 
 |  5557 class CAeroWizardPage : public CAeroWizardPageImpl<CAeroWizardPage<t_wDlgTemplat
      eID> > | 
 |  5558 { | 
 |  5559 public: | 
 |  5560         enum { IDD = t_wDlgTemplateID }; | 
 |  5561  | 
 |  5562         CAeroWizardPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardP
      ageImpl<CAeroWizardPage>(title) | 
 |  5563         { } | 
 |  5564  | 
 |  5565         DECLARE_EMPTY_MSG_MAP() | 
 |  5566 }; | 
 |  5567  | 
 |  5568  | 
 |  5569 #ifndef _ATL_NO_HOSTING | 
 |  5570  | 
 |  5571 // Note: You must #include <atlhost.h> to use these classes | 
 |  5572  | 
 |  5573 /////////////////////////////////////////////////////////////////////////////// | 
 |  5574 // CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls | 
 |  5575  | 
 |  5576 template <class T, class TBase = CAeroWizardPageWindow> | 
 |  5577 class ATL_NO_VTABLE CAeroWizardAxPageImpl : public CAxPropertyPageImpl< T, TBase
       > | 
 |  5578 { | 
 |  5579 public: | 
 |  5580         CAeroWizardAxPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPro
      pertyPageImpl< T, TBase >(title) | 
 |  5581         { } | 
 |  5582 }; | 
 |  5583  | 
 |  5584  | 
 |  5585 /////////////////////////////////////////////////////////////////////////////// | 
 |  5586 // CAeroWizardAxPage - for non-customized pages | 
 |  5587  | 
 |  5588 template <WORD t_wDlgTemplateID> | 
 |  5589 class CAeroWizardAxPage : public CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgT
      emplateID> > | 
 |  5590 { | 
 |  5591 public: | 
 |  5592         enum { IDD = t_wDlgTemplateID }; | 
 |  5593  | 
 |  5594         CAeroWizardAxPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizar
      dAxPageImpl<CAeroWizardAxPage>(title) | 
 |  5595         { } | 
 |  5596  | 
 |  5597 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700) | 
 |  5598         // not empty so we handle accelerators/create controls | 
 |  5599         BEGIN_MSG_MAP(CAeroWizardAxPage) | 
 |  5600                 CHAIN_MSG_MAP(CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgTemp
      lateID> >) | 
 |  5601         END_MSG_MAP() | 
 |  5602 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) | 
 |  5603         DECLARE_EMPTY_MSG_MAP() | 
 |  5604 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)) | 
 |  5605 }; | 
 |  5606  | 
 |  5607 #endif // _ATL_NO_HOSTING | 
 |  5608  | 
 |  5609 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE) | 
 |  5610  | 
 |  5611  | 
 |  5612 /////////////////////////////////////////////////////////////////////////////// | 
 |  5613 // TaskDialog support | 
 |  5614  | 
 |  5615 #if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WC
      E) | 
 |  5616  | 
 |  5617 /////////////////////////////////////////////////////////////////////////////// | 
 |  5618 // AtlTaskDialog - support for TaskDialog() function | 
 |  5619  | 
 |  5620 inline int AtlTaskDialog(HWND hWndParent,  | 
 |  5621                          ATL::_U_STRINGorID WindowTitle, ATL::_U_STRINGorID Main
      InstructionText, ATL::_U_STRINGorID ContentText,  | 
 |  5622                          TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons = 0U, AT
      L::_U_STRINGorID Icon = (LPCTSTR)NULL) | 
 |  5623 { | 
 |  5624         int nRet = -1; | 
 |  5625  | 
 |  5626 #ifdef _WTL_TASKDIALOG_DIRECT | 
 |  5627         USES_CONVERSION; | 
 |  5628         HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstanc
      e(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpstr), T2CW(ContentT
      ext.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet); | 
 |  5629         ATLVERIFY(SUCCEEDED(hRet)); | 
 |  5630 #else | 
 |  5631         // This allows apps to run on older versions of Windows | 
 |  5632         typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialog)(HWND hwndParent, HINSTA
      NCE hInstance, PCWSTR pszWindowTitle, PCWSTR pszMainInstruction, PCWSTR pszConte
      nt, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, PCWSTR pszIcon, int* pnButto
      n); | 
 |  5633  | 
 |  5634         HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); | 
 |  5635         if(m_hCommCtrlDLL != NULL) | 
 |  5636         { | 
 |  5637                 PFN_TaskDialog pfnTaskDialog = (PFN_TaskDialog)::GetProcAddress(
      m_hCommCtrlDLL, "TaskDialog"); | 
 |  5638                 if(pfnTaskDialog != NULL) | 
 |  5639                 { | 
 |  5640                         USES_CONVERSION; | 
 |  5641                         HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::G
      etResourceInstance(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpst
      r), T2CW(ContentText.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet); | 
 |  5642                         ATLVERIFY(SUCCEEDED(hRet)); | 
 |  5643                 } | 
 |  5644  | 
 |  5645                 ::FreeLibrary(m_hCommCtrlDLL); | 
 |  5646         } | 
 |  5647 #endif | 
 |  5648  | 
 |  5649         return nRet; | 
 |  5650 } | 
 |  5651  | 
 |  5652  | 
 |  5653 /////////////////////////////////////////////////////////////////////////////// | 
 |  5654 // CTaskDialogConfig - TASKDIALOGCONFIG wrapper | 
 |  5655  | 
 |  5656 class CTaskDialogConfig : public TASKDIALOGCONFIG | 
 |  5657 { | 
 |  5658 public: | 
 |  5659 // Constructor | 
 |  5660         CTaskDialogConfig() | 
 |  5661         { | 
 |  5662                 Init(); | 
 |  5663         } | 
 |  5664  | 
 |  5665         void Init() | 
 |  5666         { | 
 |  5667                 memset(this, 0, sizeof(TASKDIALOGCONFIG));   // initialize struc
      ture to 0/NULL | 
 |  5668                 this->cbSize = sizeof(TASKDIALOGCONFIG); | 
 |  5669                 this->hInstance = ModuleHelper::GetResourceInstance(); | 
 |  5670         } | 
 |  5671  | 
 |  5672 // Operations - setting values | 
 |  5673         // common buttons | 
 |  5674         void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) | 
 |  5675         { | 
 |  5676                 this->dwCommonButtons = dwCommonButtons; | 
 |  5677         } | 
 |  5678  | 
 |  5679         // window title text | 
 |  5680         void SetWindowTitle(UINT nID) | 
 |  5681         { | 
 |  5682                 this->pszWindowTitle = MAKEINTRESOURCEW(nID); | 
 |  5683         } | 
 |  5684  | 
 |  5685         void SetWindowTitle(LPCWSTR lpstrWindowTitle) | 
 |  5686         { | 
 |  5687                 this->pszWindowTitle = lpstrWindowTitle; | 
 |  5688         } | 
 |  5689  | 
 |  5690         // main icon | 
 |  5691         void SetMainIcon(HICON hIcon) | 
 |  5692         { | 
 |  5693                 this->dwFlags |= TDF_USE_HICON_MAIN; | 
 |  5694                 this->hMainIcon = hIcon; | 
 |  5695         } | 
 |  5696  | 
 |  5697         void SetMainIcon(UINT nID) | 
 |  5698         { | 
 |  5699                 this->dwFlags &= ~TDF_USE_HICON_MAIN; | 
 |  5700                 this->pszMainIcon = MAKEINTRESOURCEW(nID); | 
 |  5701         } | 
 |  5702  | 
 |  5703         void SetMainIcon(LPCWSTR lpstrMainIcon) | 
 |  5704         { | 
 |  5705                 this->dwFlags &= ~TDF_USE_HICON_MAIN; | 
 |  5706                 this->pszMainIcon = lpstrMainIcon; | 
 |  5707         } | 
 |  5708  | 
 |  5709         // main instruction text | 
 |  5710         void SetMainInstructionText(UINT nID) | 
 |  5711         { | 
 |  5712                 this->pszMainInstruction = MAKEINTRESOURCEW(nID); | 
 |  5713         } | 
 |  5714  | 
 |  5715         void SetMainInstructionText(LPCWSTR lpstrMainInstruction) | 
 |  5716         { | 
 |  5717                 this->pszMainInstruction = lpstrMainInstruction; | 
 |  5718         } | 
 |  5719  | 
 |  5720         // content text | 
 |  5721         void SetContentText(UINT nID) | 
 |  5722         { | 
 |  5723                 this->pszContent = MAKEINTRESOURCEW(nID); | 
 |  5724         } | 
 |  5725  | 
 |  5726         void SetContentText(LPCWSTR lpstrContent) | 
 |  5727         { | 
 |  5728                 this->pszContent = lpstrContent; | 
 |  5729         } | 
 |  5730  | 
 |  5731         // buttons | 
 |  5732         void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nD
      efaultButton = 0) | 
 |  5733         { | 
 |  5734                 this->pButtons = pButtons; | 
 |  5735                 this->cButtons = cButtons; | 
 |  5736                 if(nDefaultButton != 0) | 
 |  5737                         this->nDefaultButton = nDefaultButton; | 
 |  5738         } | 
 |  5739  | 
 |  5740         void SetDefaultButton(int nDefaultButton) | 
 |  5741         { | 
 |  5742                 this->nDefaultButton = nDefaultButton; | 
 |  5743         } | 
 |  5744  | 
 |  5745         // radio buttons | 
 |  5746         void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadio
      Buttons, int nDefaultRadioButton = 0) | 
 |  5747         { | 
 |  5748                 this->pRadioButtons = pRadioButtons; | 
 |  5749                 this->cRadioButtons = cRadioButtons; | 
 |  5750                 if(nDefaultRadioButton != 0) | 
 |  5751                         this->nDefaultRadioButton = nDefaultRadioButton; | 
 |  5752         } | 
 |  5753  | 
 |  5754         void SetDefaultRadioButton(int nDefaultRadioButton) | 
 |  5755         { | 
 |  5756                 this->nDefaultRadioButton = nDefaultRadioButton; | 
 |  5757         } | 
 |  5758  | 
 |  5759         // verification text | 
 |  5760         void SetVerificationText(UINT nID) | 
 |  5761         { | 
 |  5762                 this->pszVerificationText = MAKEINTRESOURCEW(nID); | 
 |  5763         } | 
 |  5764  | 
 |  5765         void SetVerificationText(LPCWSTR lpstrVerificationText) | 
 |  5766         { | 
 |  5767                 this->pszVerificationText = lpstrVerificationText; | 
 |  5768         } | 
 |  5769  | 
 |  5770         // expanded information text | 
 |  5771         void SetExpandedInformationText(UINT nID) | 
 |  5772         { | 
 |  5773                 this->pszExpandedInformation = MAKEINTRESOURCEW(nID); | 
 |  5774         } | 
 |  5775  | 
 |  5776         void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) | 
 |  5777         { | 
 |  5778                 this->pszExpandedInformation = lpstrExpandedInformation; | 
 |  5779         } | 
 |  5780  | 
 |  5781         // expanded control text | 
 |  5782         void SetExpandedControlText(UINT nID) | 
 |  5783         { | 
 |  5784                 this->pszExpandedControlText = MAKEINTRESOURCEW(nID); | 
 |  5785         } | 
 |  5786  | 
 |  5787         void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) | 
 |  5788         { | 
 |  5789                 this->pszExpandedControlText = lpstrExpandedControlText; | 
 |  5790         } | 
 |  5791  | 
 |  5792         // collapsed control text | 
 |  5793         void SetCollapsedControlText(UINT nID) | 
 |  5794         { | 
 |  5795                 this->pszCollapsedControlText = MAKEINTRESOURCEW(nID); | 
 |  5796         } | 
 |  5797  | 
 |  5798         void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) | 
 |  5799         { | 
 |  5800                 this->pszCollapsedControlText = lpstrCollapsedControlText; | 
 |  5801         } | 
 |  5802  | 
 |  5803         // footer icon | 
 |  5804         void SetFooterIcon(HICON hIcon) | 
 |  5805         { | 
 |  5806                 this->dwFlags |= TDF_USE_HICON_FOOTER; | 
 |  5807                 this->hFooterIcon = hIcon; | 
 |  5808         } | 
 |  5809  | 
 |  5810         void SetFooterIcon(UINT nID) | 
 |  5811         { | 
 |  5812                 this->dwFlags &= ~TDF_USE_HICON_FOOTER; | 
 |  5813                 this->pszFooterIcon = MAKEINTRESOURCEW(nID); | 
 |  5814         } | 
 |  5815  | 
 |  5816         void SetFooterIcon(LPCWSTR lpstrFooterIcon) | 
 |  5817         { | 
 |  5818                 this->dwFlags &= ~TDF_USE_HICON_FOOTER; | 
 |  5819                 this->pszFooterIcon = lpstrFooterIcon; | 
 |  5820         } | 
 |  5821  | 
 |  5822         // footer text | 
 |  5823         void SetFooterText(UINT nID) | 
 |  5824         { | 
 |  5825                 this->pszFooter = MAKEINTRESOURCEW(nID); | 
 |  5826         } | 
 |  5827  | 
 |  5828         void SetFooterText(LPCWSTR lpstrFooterText) | 
 |  5829         { | 
 |  5830                 this->pszFooter = lpstrFooterText; | 
 |  5831         } | 
 |  5832  | 
 |  5833         // width (in DLUs) | 
 |  5834         void SetWidth(UINT cxWidth) | 
 |  5835         { | 
 |  5836                 this->cxWidth = cxWidth; | 
 |  5837         } | 
 |  5838  | 
 |  5839         // modify flags | 
 |  5840         void ModifyFlags(DWORD dwRemove, DWORD dwAdd) | 
 |  5841         { | 
 |  5842                 this->dwFlags = (this->dwFlags & ~dwRemove) | dwAdd; | 
 |  5843         } | 
 |  5844 }; | 
 |  5845  | 
 |  5846  | 
 |  5847 /////////////////////////////////////////////////////////////////////////////// | 
 |  5848 // CTaskDialogImpl - implements a Task Dialog | 
 |  5849  | 
 |  5850 template <class T> | 
 |  5851 class ATL_NO_VTABLE CTaskDialogImpl | 
 |  5852 { | 
 |  5853 public: | 
 |  5854         CTaskDialogConfig m_tdc; | 
 |  5855         HWND m_hWnd;   // used only in callback functions | 
 |  5856  | 
 |  5857 // Constructor | 
 |  5858         CTaskDialogImpl(HWND hWndParent = NULL) : m_hWnd(NULL) | 
 |  5859         { | 
 |  5860                 m_tdc.hwndParent = hWndParent; | 
 |  5861                 m_tdc.pfCallback = T::TaskDialogCallback; | 
 |  5862                 m_tdc.lpCallbackData = (LONG_PTR)static_cast<T*>(this); | 
 |  5863         } | 
 |  5864  | 
 |  5865 // Operations | 
 |  5866         HRESULT DoModal(HWND hWndParent = ::GetActiveWindow(), int* pnButton = N
      ULL, int* pnRadioButton = NULL, BOOL* pfVerificationFlagChecked = NULL) | 
 |  5867         { | 
 |  5868                 if(m_tdc.hwndParent == NULL) | 
 |  5869                         m_tdc.hwndParent = hWndParent; | 
 |  5870  | 
 |  5871 #ifdef _WTL_TASKDIALOG_DIRECT | 
 |  5872                 return ::TaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfV
      erificationFlagChecked); | 
 |  5873 #else | 
 |  5874  | 
 |  5875                 // This allows apps to run on older versions of Windows | 
 |  5876                 typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialogIndirect)(const T
      ASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerific
      ationFlagChecked); | 
 |  5877  | 
 |  5878                 HRESULT hRet = E_UNEXPECTED; | 
 |  5879                 HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll")); | 
 |  5880                 if(m_hCommCtrlDLL != NULL) | 
 |  5881                 { | 
 |  5882                         PFN_TaskDialogIndirect pfnTaskDialogIndirect = (PFN_Task
      DialogIndirect)::GetProcAddress(m_hCommCtrlDLL, "TaskDialogIndirect"); | 
 |  5883                         if(pfnTaskDialogIndirect != NULL) | 
 |  5884                                 hRet = pfnTaskDialogIndirect(&m_tdc, pnButton, p
      nRadioButton, pfVerificationFlagChecked); | 
 |  5885  | 
 |  5886                         ::FreeLibrary(m_hCommCtrlDLL); | 
 |  5887                 } | 
 |  5888  | 
 |  5889                 return hRet; | 
 |  5890 #endif | 
 |  5891         } | 
 |  5892  | 
 |  5893 // Operations - setting values of TASKDIALOGCONFIG | 
 |  5894         // common buttons | 
 |  5895         void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons) | 
 |  5896         {       m_tdc.SetCommonButtons(dwCommonButtons); } | 
 |  5897         // window title text | 
 |  5898         void SetWindowTitle(UINT nID) | 
 |  5899         {       m_tdc.SetWindowTitle(nID); } | 
 |  5900         void SetWindowTitle(LPCWSTR lpstrWindowTitle) | 
 |  5901         {       m_tdc.SetWindowTitle(lpstrWindowTitle); } | 
 |  5902         // main icon | 
 |  5903         void SetMainIcon(HICON hIcon) | 
 |  5904         {       m_tdc.SetMainIcon(hIcon); } | 
 |  5905         void SetMainIcon(UINT nID) | 
 |  5906         {       m_tdc.SetMainIcon(nID); } | 
 |  5907         void SetMainIcon(LPCWSTR lpstrMainIcon) | 
 |  5908         {       m_tdc.SetMainIcon(lpstrMainIcon); } | 
 |  5909         // main instruction text | 
 |  5910         void SetMainInstructionText(UINT nID) | 
 |  5911         {       m_tdc.SetMainInstructionText(nID); } | 
 |  5912         void SetMainInstructionText(LPCWSTR lpstrMainInstruction) | 
 |  5913         {       m_tdc.SetMainInstructionText(lpstrMainInstruction); } | 
 |  5914         // content text | 
 |  5915         void SetContentText(UINT nID) | 
 |  5916         {       m_tdc.SetContentText(nID); } | 
 |  5917         void SetContentText(LPCWSTR lpstrContent) | 
 |  5918         {       m_tdc.SetContentText(lpstrContent); } | 
 |  5919         // buttons | 
 |  5920         void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nD
      efaultButton = 0) | 
 |  5921         {       m_tdc.SetButtons(pButtons, cButtons, nDefaultButton); } | 
 |  5922         void SetDefaultButton(int nDefaultButton) | 
 |  5923         {       m_tdc.SetDefaultButton(nDefaultButton); } | 
 |  5924         // radio buttons | 
 |  5925         void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadio
      Buttons, int nDefaultRadioButton = 0) | 
 |  5926         {       m_tdc.SetRadioButtons(pRadioButtons, cRadioButtons, nDefaultRadi
      oButton); } | 
 |  5927         void SetDefaultRadioButton(int nDefaultRadioButton) | 
 |  5928         {       m_tdc.SetDefaultRadioButton(nDefaultRadioButton); } | 
 |  5929         // verification text | 
 |  5930         void SetVerificationText(UINT nID) | 
 |  5931         {       m_tdc.SetVerificationText(nID); } | 
 |  5932         void SetVerificationText(LPCWSTR lpstrVerificationText) | 
 |  5933         {       m_tdc.SetVerificationText(lpstrVerificationText); } | 
 |  5934         // expanded information text | 
 |  5935         void SetExpandedInformationText(UINT nID) | 
 |  5936         {       m_tdc.SetExpandedInformationText(nID); } | 
 |  5937         void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation) | 
 |  5938         {       m_tdc.SetExpandedInformationText(lpstrExpandedInformation); } | 
 |  5939         // expanded control text | 
 |  5940         void SetExpandedControlText(UINT nID) | 
 |  5941         {       m_tdc.SetExpandedControlText(nID); } | 
 |  5942         void SetExpandedControlText(LPCWSTR lpstrExpandedControlText) | 
 |  5943         {       m_tdc.SetExpandedControlText(lpstrExpandedControlText); } | 
 |  5944         // collapsed control text | 
 |  5945         void SetCollapsedControlText(UINT nID) | 
 |  5946         {       m_tdc.SetCollapsedControlText(nID); } | 
 |  5947         void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText) | 
 |  5948         {       m_tdc.SetCollapsedControlText(lpstrCollapsedControlText); } | 
 |  5949         // footer icon | 
 |  5950         void SetFooterIcon(HICON hIcon) | 
 |  5951         {       m_tdc.SetFooterIcon(hIcon); } | 
 |  5952         void SetFooterIcon(UINT nID) | 
 |  5953         {       m_tdc.SetFooterIcon(nID); } | 
 |  5954         void SetFooterIcon(LPCWSTR lpstrFooterIcon) | 
 |  5955         {       m_tdc.SetFooterIcon(lpstrFooterIcon); } | 
 |  5956         // footer text | 
 |  5957         void SetFooterText(UINT nID) | 
 |  5958         {       m_tdc.SetFooterText(nID); } | 
 |  5959         void SetFooterText(LPCWSTR lpstrFooterText) | 
 |  5960         {       m_tdc.SetFooterText(lpstrFooterText); } | 
 |  5961         // width (in DLUs) | 
 |  5962         void SetWidth(UINT cxWidth) | 
 |  5963         {       m_tdc.SetWidth(cxWidth); } | 
 |  5964         // modify flags | 
 |  5965         void ModifyFlags(DWORD dwRemove, DWORD dwAdd) | 
 |  5966         {       m_tdc.ModifyFlags(dwRemove, dwAdd); } | 
 |  5967  | 
 |  5968 // Implementation | 
 |  5969         static HRESULT CALLBACK TaskDialogCallback(HWND hWnd, UINT uMsg, WPARAM 
      wParam, LPARAM lParam, LONG_PTR lpRefData) | 
 |  5970         { | 
 |  5971                 T* pT = (T*)lpRefData; | 
 |  5972                 ATLASSERT(pT->m_hWnd == NULL || pT->m_hWnd == hWnd); | 
 |  5973  | 
 |  5974                 BOOL bRet = FALSE; | 
 |  5975                 switch(uMsg) | 
 |  5976                 { | 
 |  5977                 case TDN_DIALOG_CONSTRUCTED: | 
 |  5978                         pT->m_hWnd = hWnd; | 
 |  5979                         pT->OnDialogConstructed(); | 
 |  5980                         break; | 
 |  5981                 case TDN_CREATED: | 
 |  5982                         pT->OnCreated(); | 
 |  5983                         break; | 
 |  5984                 case TDN_BUTTON_CLICKED: | 
 |  5985                         bRet = pT->OnButtonClicked((int)wParam); | 
 |  5986                         break; | 
 |  5987                 case TDN_RADIO_BUTTON_CLICKED: | 
 |  5988                         pT->OnRadioButtonClicked((int)wParam); | 
 |  5989                         break; | 
 |  5990                 case TDN_HYPERLINK_CLICKED: | 
 |  5991                         pT->OnHyperlinkClicked((LPCWSTR)lParam); | 
 |  5992                         break; | 
 |  5993                 case TDN_EXPANDO_BUTTON_CLICKED: | 
 |  5994                         pT->OnExpandoButtonClicked((wParam != 0)); | 
 |  5995                         break; | 
 |  5996                 case TDN_VERIFICATION_CLICKED: | 
 |  5997                         pT->OnVerificationClicked((wParam != 0)); | 
 |  5998                         break; | 
 |  5999                 case TDN_HELP: | 
 |  6000                         pT->OnHelp(); | 
 |  6001                         break; | 
 |  6002                 case TDN_TIMER: | 
 |  6003                         bRet = pT->OnTimer((DWORD)wParam); | 
 |  6004                         break; | 
 |  6005                 case TDN_NAVIGATED: | 
 |  6006                         pT->OnNavigated(); | 
 |  6007                         break; | 
 |  6008                 case TDN_DESTROYED: | 
 |  6009                         pT->OnDestroyed(); | 
 |  6010                         pT->m_hWnd = NULL; | 
 |  6011                         break; | 
 |  6012                 default: | 
 |  6013                         ATLTRACE2(atlTraceUI, 0, _T("Unknown notification receiv
      ed in CTaskDialogImpl::TaskDialogCallback\n")); | 
 |  6014                         break; | 
 |  6015                 } | 
 |  6016  | 
 |  6017                 return (HRESULT)bRet; | 
 |  6018         } | 
 |  6019  | 
 |  6020 // Overrideables - notification handlers | 
 |  6021         void OnDialogConstructed() | 
 |  6022         { | 
 |  6023         } | 
 |  6024  | 
 |  6025         void OnCreated() | 
 |  6026         { | 
 |  6027         } | 
 |  6028  | 
 |  6029         BOOL OnButtonClicked(int /*nButton*/) | 
 |  6030         { | 
 |  6031                 return FALSE;   // don't prevent dialog to close | 
 |  6032         } | 
 |  6033  | 
 |  6034         void OnRadioButtonClicked(int /*nRadioButton*/) | 
 |  6035         { | 
 |  6036         } | 
 |  6037  | 
 |  6038         void OnHyperlinkClicked(LPCWSTR /*pszHREF*/) | 
 |  6039         { | 
 |  6040         } | 
 |  6041  | 
 |  6042         void OnExpandoButtonClicked(bool /*bExpanded*/) | 
 |  6043         { | 
 |  6044         } | 
 |  6045  | 
 |  6046         void OnVerificationClicked(bool /*bChecked*/) | 
 |  6047         { | 
 |  6048         } | 
 |  6049  | 
 |  6050         void OnHelp() | 
 |  6051         { | 
 |  6052         } | 
 |  6053  | 
 |  6054         BOOL OnTimer(DWORD /*dwTickCount*/) | 
 |  6055         { | 
 |  6056                 return FALSE;   // don't reset counter | 
 |  6057         } | 
 |  6058  | 
 |  6059         void OnNavigated() | 
 |  6060         { | 
 |  6061         } | 
 |  6062  | 
 |  6063         void OnDestroyed() | 
 |  6064         { | 
 |  6065         } | 
 |  6066  | 
 |  6067 // Commands - valid to call only from handlers | 
 |  6068         void NavigatePage(TASKDIALOGCONFIG& tdc) | 
 |  6069         { | 
 |  6070                 ATLASSERT(m_hWnd != NULL); | 
 |  6071  | 
 |  6072                 tdc.cbSize = sizeof(TASKDIALOGCONFIG); | 
 |  6073                 if(tdc.hwndParent == NULL) | 
 |  6074                         tdc.hwndParent = m_tdc.hwndParent; | 
 |  6075                 tdc.pfCallback = m_tdc.pfCallback; | 
 |  6076                 tdc.lpCallbackData = m_tdc.lpCallbackData; | 
 |  6077                 (TASKDIALOGCONFIG)m_tdc = tdc; | 
 |  6078  | 
 |  6079                 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&tdc); | 
 |  6080         } | 
 |  6081  | 
 |  6082         // modify TASKDIALOGCONFIG values, then call this to update task dialog | 
 |  6083         void NavigatePage() | 
 |  6084         { | 
 |  6085                 ATLASSERT(m_hWnd != NULL); | 
 |  6086                 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&m_tdc); | 
 |  6087         } | 
 |  6088  | 
 |  6089         void ClickButton(int nButton) | 
 |  6090         { | 
 |  6091                 ATLASSERT(m_hWnd != NULL); | 
 |  6092                 ::SendMessage(m_hWnd, TDM_CLICK_BUTTON, nButton, 0L); | 
 |  6093         } | 
 |  6094  | 
 |  6095         void SetMarqueeProgressBar(BOOL bMarquee) | 
 |  6096         { | 
 |  6097                 ATLASSERT(m_hWnd != NULL); | 
 |  6098                 ::SendMessage(m_hWnd, TDM_SET_MARQUEE_PROGRESS_BAR, bMarquee, 0L
      ); | 
 |  6099         } | 
 |  6100  | 
 |  6101         BOOL SetProgressBarState(int nNewState) | 
 |  6102         { | 
 |  6103                 ATLASSERT(m_hWnd != NULL); | 
 |  6104                 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_STATE, n
      NewState, 0L); | 
 |  6105         } | 
 |  6106  | 
 |  6107         DWORD SetProgressBarRange(int nMinRange, int nMaxRange) | 
 |  6108         { | 
 |  6109                 ATLASSERT(m_hWnd != NULL); | 
 |  6110                 return (DWORD)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_RANGE, 
      0, MAKELPARAM(nMinRange, nMaxRange)); | 
 |  6111         } | 
 |  6112  | 
 |  6113         int SetProgressBarPos(int nNewPos) | 
 |  6114         { | 
 |  6115                 ATLASSERT(m_hWnd != NULL); | 
 |  6116                 return (int)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_POS, nNew
      Pos, 0L); | 
 |  6117         } | 
 |  6118  | 
 |  6119         BOOL SetProgressBarMarquee(BOOL bMarquee, UINT uSpeed) | 
 |  6120         { | 
 |  6121                 ATLASSERT(m_hWnd != NULL); | 
 |  6122                 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_MARQUEE,
       bMarquee, uSpeed); | 
 |  6123         } | 
 |  6124  | 
 |  6125         void SetElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) | 
 |  6126         { | 
 |  6127                 ATLASSERT(m_hWnd != NULL); | 
 |  6128                 ::SendMessage(m_hWnd, TDM_SET_ELEMENT_TEXT, element, (LPARAM)lps
      trText); | 
 |  6129         } | 
 |  6130  | 
 |  6131         void ClickRadioButton(int nRadioButton) | 
 |  6132         { | 
 |  6133                 ATLASSERT(m_hWnd != NULL); | 
 |  6134                 ::SendMessage(m_hWnd, TDM_CLICK_RADIO_BUTTON, nRadioButton, 0L); | 
 |  6135         } | 
 |  6136  | 
 |  6137         void EnableButton(int nButton, BOOL bEnable) | 
 |  6138         { | 
 |  6139                 ATLASSERT(m_hWnd != NULL); | 
 |  6140                 ::SendMessage(m_hWnd, TDM_ENABLE_BUTTON, nButton, bEnable); | 
 |  6141         } | 
 |  6142  | 
 |  6143         void EnableRadioButton(int nButton, BOOL bEnable) | 
 |  6144         { | 
 |  6145                 ATLASSERT(m_hWnd != NULL); | 
 |  6146                 ::SendMessage(m_hWnd, TDM_ENABLE_RADIO_BUTTON, nButton, bEnable)
      ; | 
 |  6147         } | 
 |  6148  | 
 |  6149         void ClickVerification(BOOL bCheck, BOOL bFocus) | 
 |  6150         { | 
 |  6151                 ATLASSERT(m_hWnd != NULL); | 
 |  6152                 ::SendMessage(m_hWnd, TDM_CLICK_VERIFICATION, bCheck, bFocus); | 
 |  6153         } | 
 |  6154  | 
 |  6155         void UpdateElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText) | 
 |  6156         { | 
 |  6157                 ATLASSERT(m_hWnd != NULL); | 
 |  6158                 ::SendMessage(m_hWnd, TDM_UPDATE_ELEMENT_TEXT, element, (LPARAM)
      lpstrText); | 
 |  6159         } | 
 |  6160  | 
 |  6161         void SetButtonElevationRequiredState(int nButton, BOOL bElevation) | 
 |  6162         { | 
 |  6163                 ATLASSERT(m_hWnd != NULL); | 
 |  6164                 ::SendMessage(m_hWnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, n
      Button, bElevation); | 
 |  6165         } | 
 |  6166  | 
 |  6167         void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, HICON hIcon) | 
 |  6168         { | 
 |  6169                 ATLASSERT(m_hWnd != NULL); | 
 |  6170 #ifdef _DEBUG | 
 |  6171                 if(element == TDIE_ICON_MAIN) | 
 |  6172                         ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) != 0); | 
 |  6173                 else if(element == TDIE_ICON_FOOTER) | 
 |  6174                         ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) != 0); | 
 |  6175 #endif // _DEBUG | 
 |  6176                 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)hIcon); | 
 |  6177         } | 
 |  6178  | 
 |  6179         void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, LPCWSTR lpstrIcon) | 
 |  6180         { | 
 |  6181                 ATLASSERT(m_hWnd != NULL); | 
 |  6182 #ifdef _DEBUG | 
 |  6183                 if(element == TDIE_ICON_MAIN) | 
 |  6184                         ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) == 0); | 
 |  6185                 else if(element == TDIE_ICON_FOOTER) | 
 |  6186                         ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) == 0); | 
 |  6187 #endif // _DEBUG | 
 |  6188                 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)lpstrIco
      n); | 
 |  6189         } | 
 |  6190 }; | 
 |  6191  | 
 |  6192  | 
 |  6193 /////////////////////////////////////////////////////////////////////////////// | 
 |  6194 // CTaskDialog - for non-customized task dialogs | 
 |  6195  | 
 |  6196 class CTaskDialog : public CTaskDialogImpl<CTaskDialog> | 
 |  6197 { | 
 |  6198 public: | 
 |  6199         CTaskDialog(HWND hWndParent = NULL) : CTaskDialogImpl<CTaskDialog>(hWndP
      arent) | 
 |  6200         { | 
 |  6201                 m_tdc.pfCallback = NULL; | 
 |  6202         } | 
 |  6203 }; | 
 |  6204  | 
 |  6205 #endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WI
      N32_WCE) | 
 |  6206  | 
 |  6207 }; // namespace WTL | 
 |  6208  | 
 |  6209 #endif // __ATLDLGS_H__ | 
| OLD | NEW |