1 // Windows Template Library - WTL version 8.0
\r
2 // Copyright (C) Microsoft Corporation. All rights reserved.
\r
4 // This file is a part of the Windows Template Library.
\r
5 // The use and distribution terms for this software are covered by the
\r
6 // Common Public License 1.0 (http://opensource.org/osi3.0/licenses/cpl1.0.php)
\r
7 // which can be found in the file CPL.TXT at the root of this distribution.
\r
8 // By using this software in any fashion, you are agreeing to be bound by
\r
9 // the terms of this license. You must not remove this notice, or
\r
10 // any other, from this software.
\r
12 #ifndef __ATLDLGS_H__
\r
13 #define __ATLDLGS_H__
\r
18 #error ATL requires C++ compilation (use a .cpp suffix)
\r
21 #ifndef __ATLAPP_H__
\r
22 #error atldlgs.h requires atlapp.h to be included first
\r
25 #ifndef __ATLWIN_H__
\r
26 #error atldlgs.h requires atlwin.h to be included first
\r
29 #include <commdlg.h>
\r
32 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
33 #include <shobjidl.h>
\r
34 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
37 ///////////////////////////////////////////////////////////////////////////////
\r
38 // Classes in this file:
\r
40 // CFileDialogImpl<T>
\r
43 // CMultiFileDialogImpl<T>
\r
45 // CShellFileDialogImpl<T>
\r
46 // CShellFileOpenDialogImpl<T>
\r
47 // CShellFileOpenDialog
\r
48 // CShellFileSaveDialogImpl<T>
\r
49 // CShellFileSaveDialog
\r
50 // CFolderDialogImpl<T>
\r
52 // CFontDialogImpl<T>
\r
54 // CRichEditFontDialogImpl<T>
\r
55 // CRichEditFontDialog
\r
56 // CColorDialogImpl<T>
\r
58 // CPrintDialogImpl<T>
\r
60 // CPrintDialogExImpl<T>
\r
62 // CPageSetupDialogImpl<T>
\r
64 // CFindReplaceDialogImpl<T>
\r
65 // CFindReplaceDialog
\r
68 // CIndirectDialogImpl<T, TDlgTemplate, TBase>
\r
70 // CPropertySheetWindow
\r
71 // CPropertySheetImpl<T, TBase>
\r
73 // CPropertyPageWindow
\r
74 // CPropertyPageImpl<T, TBase>
\r
75 // CPropertyPage<t_wDlgTemplateID>
\r
76 // CAxPropertyPageImpl<T, TBase>
\r
77 // CAxPropertyPage<t_wDlgTemplateID>
\r
79 // CWizard97SheetWindow
\r
80 // CWizard97SheetImpl<T, TBase>
\r
82 // CWizard97PageWindow
\r
83 // CWizard97PageImpl<T, TBase>
\r
84 // CWizard97ExteriorPageImpl<T, TBase>
\r
85 // CWizard97InteriorPageImpl<T, TBase>
\r
87 // CAeroWizardFrameWindow
\r
88 // CAeroWizardFrameImpl<T, TBase>
\r
90 // CAeroWizardPageWindow
\r
91 // CAeroWizardPageImpl<T, TBase>
\r
92 // CAeroWizardPage<t_wDlgTemplateID>
\r
93 // CAeroWizardAxPageImpl<T, TBase>
\r
94 // CAeroWizardAxPage<t_wDlgTemplateID>
\r
96 // CTaskDialogConfig
\r
97 // CTaskDialogImpl<T>
\r
100 // Global functions:
\r
107 ///////////////////////////////////////////////////////////////////////////////
\r
108 // CFileDialogImpl - used for File Open or File Save As
\r
110 // compatibility with the old (vc6.0) headers
\r
111 #if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
\r
112 #ifndef CDSIZEOF_STRUCT
\r
113 #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
\r
115 #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName)
\r
116 #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName)
\r
118 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400W
\r
120 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400A
\r
122 #endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
\r
124 #if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM)
\r
125 #define CDN_INCLUDEITEM (CDN_FIRST - 0x0007)
\r
129 class ATL_NO_VTABLE CFileDialogImpl : public ATL::CDialogImplBase
\r
132 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
\r
133 OPENFILENAMEEX m_ofn;
\r
135 OPENFILENAME m_ofn;
\r
137 BOOL m_bOpenFileDialog; // TRUE for file open, FALSE for file save
\r
138 TCHAR m_szFileTitle[_MAX_FNAME]; // contains file title after return
\r
139 TCHAR m_szFileName[_MAX_PATH]; // contains full path name after return
\r
141 CFileDialogImpl(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
\r
142 LPCTSTR lpszDefExt = NULL,
\r
143 LPCTSTR lpszFileName = NULL,
\r
144 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
\r
145 LPCTSTR lpszFilter = NULL,
\r
146 HWND hWndParent = NULL)
\r
148 memset(&m_ofn, 0, sizeof(m_ofn)); // initialize structure to 0/NULL
\r
149 m_szFileName[0] = _T('\0');
\r
150 m_szFileTitle[0] = _T('\0');
\r
152 m_bOpenFileDialog = bOpenFileDialog;
\r
154 m_ofn.lStructSize = sizeof(m_ofn);
\r
155 #if (_WIN32_WINNT >= 0x0500)
\r
156 // adjust struct size if running on older version of Windows
\r
157 if(AtlIsOldWindows())
\r
159 ATLASSERT(sizeof(m_ofn) > OPENFILENAME_SIZE_VERSION_400); // must be
\r
160 m_ofn.lStructSize = OPENFILENAME_SIZE_VERSION_400;
\r
162 #endif // (_WIN32_WINNT >= 0x0500)
\r
163 m_ofn.lpstrFile = m_szFileName;
\r
164 m_ofn.nMaxFile = _MAX_PATH;
\r
165 m_ofn.lpstrDefExt = lpszDefExt;
\r
166 m_ofn.lpstrFileTitle = (LPTSTR)m_szFileTitle;
\r
167 m_ofn.nMaxFileTitle = _MAX_FNAME;
\r
169 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLESIZING;
\r
170 #else // CE specific
\r
171 m_ofn.Flags = dwFlags | OFN_EXPLORER | OFN_ENABLEHOOK;
\r
172 #endif // !_WIN32_WCE
\r
173 m_ofn.lpstrFilter = lpszFilter;
\r
174 m_ofn.hInstance = ModuleHelper::GetResourceInstance();
\r
175 m_ofn.lpfnHook = (LPOFNHOOKPROC)T::StartDialogProc;
\r
176 m_ofn.hwndOwner = hWndParent;
\r
178 // setup initial file name
\r
179 if(lpszFileName != NULL)
\r
180 SecureHelper::strncpy_x(m_szFileName, _countof(m_szFileName), lpszFileName, _TRUNCATE);
\r
183 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
185 ATLASSERT((m_ofn.Flags & OFN_ENABLEHOOK) != 0);
\r
186 ATLASSERT(m_ofn.lpfnHook != NULL); // can still be a user hook
\r
188 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
190 if(m_ofn.hwndOwner == NULL) // set only if not specified before
\r
191 m_ofn.hwndOwner = hWndParent;
\r
193 ATLASSERT(m_hWnd == NULL);
\r
194 ModuleHelper::AddCreateWndData(&m_thunk.cd, (ATL::CDialogImplBase*)this);
\r
197 if(m_bOpenFileDialog)
\r
198 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
\r
199 bRet = ::GetOpenFileNameEx(&m_ofn);
\r
201 bRet = ::GetSaveFileName((LPOPENFILENAME)&m_ofn);
\r
203 bRet = ::GetOpenFileName(&m_ofn);
\r
205 bRet = ::GetSaveFileName(&m_ofn);
\r
210 return bRet ? IDOK : IDCANCEL;
\r
214 ATL::CWindow GetFileDialogWindow() const
\r
216 ATLASSERT(::IsWindow(m_hWnd));
\r
217 return ATL::CWindow(GetParent());
\r
220 int GetFilePath(LPTSTR lpstrFilePath, int nLength) const
\r
222 ATLASSERT(::IsWindow(m_hWnd));
\r
223 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
225 return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH, nLength, (LPARAM)lpstrFilePath);
\r
228 int GetFolderIDList(LPVOID lpBuff, int nLength) const
\r
230 ATLASSERT(::IsWindow(m_hWnd));
\r
231 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
233 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIST, nLength, (LPARAM)lpBuff);
\r
236 int GetFolderPath(LPTSTR lpstrFolderPath, int nLength) const
\r
238 ATLASSERT(::IsWindow(m_hWnd));
\r
239 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
241 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH, nLength, (LPARAM)lpstrFolderPath);
\r
244 int GetSpec(LPTSTR lpstrSpec, int nLength) const
\r
246 ATLASSERT(::IsWindow(m_hWnd));
\r
247 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
249 return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC, nLength, (LPARAM)lpstrSpec);
\r
252 void SetControlText(int nCtrlID, LPCTSTR lpstrText)
\r
254 ATLASSERT(::IsWindow(m_hWnd));
\r
255 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
257 GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT, nCtrlID, (LPARAM)lpstrText);
\r
260 void SetDefExt(LPCTSTR lpstrExt)
\r
262 ATLASSERT(::IsWindow(m_hWnd));
\r
263 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
265 GetFileDialogWindow().SendMessage(CDM_SETDEFEXT, 0, (LPARAM)lpstrExt);
\r
268 BOOL GetReadOnlyPref() const // return TRUE if readonly checked
\r
270 return ((m_ofn.Flags & OFN_READONLY) != 0) ? TRUE : FALSE;
\r
274 void HideControl(int nCtrlID)
\r
276 ATLASSERT(::IsWindow(m_hWnd));
\r
277 ATLASSERT((m_ofn.Flags & OFN_EXPLORER) != 0);
\r
279 GetFileDialogWindow().SendMessage(CDM_HIDECONTROL, nCtrlID);
\r
282 // Special override for common dialogs
\r
283 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
\r
285 ATLASSERT(::IsWindow(m_hWnd));
\r
286 GetFileDialogWindow().SendMessage(WM_COMMAND, MAKEWPARAM(IDCANCEL, 0));
\r
290 // Message map and handlers
\r
291 BEGIN_MSG_MAP(CFileDialogImpl)
\r
292 NOTIFY_CODE_HANDLER(CDN_FILEOK, _OnFileOK)
\r
293 NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE, _OnFolderChange)
\r
294 NOTIFY_CODE_HANDLER(CDN_HELP, _OnHelp)
\r
295 NOTIFY_CODE_HANDLER(CDN_INITDONE, _OnInitDone)
\r
296 NOTIFY_CODE_HANDLER(CDN_SELCHANGE, _OnSelChange)
\r
297 NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION, _OnShareViolation)
\r
298 NOTIFY_CODE_HANDLER(CDN_TYPECHANGE, _OnTypeChange)
\r
300 NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM, _OnIncludeItem)
\r
301 #endif // !_WIN32_WCE
\r
304 LRESULT _OnFileOK(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
306 ATLASSERT(::IsWindow(m_hWnd));
\r
307 T* pT = static_cast<T*>(this);
\r
308 return !pT->OnFileOK((LPOFNOTIFY)pnmh);
\r
311 LRESULT _OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
313 ATLASSERT(::IsWindow(m_hWnd));
\r
314 T* pT = static_cast<T*>(this);
\r
315 pT->OnFolderChange((LPOFNOTIFY)pnmh);
\r
319 LRESULT _OnHelp(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
321 ATLASSERT(::IsWindow(m_hWnd));
\r
322 T* pT = static_cast<T*>(this);
\r
323 pT->OnHelp((LPOFNOTIFY)pnmh);
\r
327 LRESULT _OnInitDone(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
329 ATLASSERT(::IsWindow(m_hWnd));
\r
330 T* pT = static_cast<T*>(this);
\r
331 pT->OnInitDone((LPOFNOTIFY)pnmh);
\r
335 LRESULT _OnSelChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
337 ATLASSERT(::IsWindow(m_hWnd));
\r
338 T* pT = static_cast<T*>(this);
\r
339 pT->OnSelChange((LPOFNOTIFY)pnmh);
\r
343 LRESULT _OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
345 ATLASSERT(::IsWindow(m_hWnd));
\r
346 T* pT = static_cast<T*>(this);
\r
347 return pT->OnShareViolation((LPOFNOTIFY)pnmh);
\r
350 LRESULT _OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
352 ATLASSERT(::IsWindow(m_hWnd));
\r
353 T* pT = static_cast<T*>(this);
\r
354 pT->OnTypeChange((LPOFNOTIFY)pnmh);
\r
359 LRESULT _OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/)
\r
361 ATLASSERT(::IsWindow(m_hWnd));
\r
362 T* pT = static_cast<T*>(this);
\r
363 return pT->OnIncludeItem((LPOFNOTIFYEX)pnmh);
\r
365 #endif // !_WIN32_WCE
\r
368 BOOL OnFileOK(LPOFNOTIFY /*lpon*/)
\r
373 void OnFolderChange(LPOFNOTIFY /*lpon*/)
\r
377 void OnHelp(LPOFNOTIFY /*lpon*/)
\r
381 void OnInitDone(LPOFNOTIFY /*lpon*/)
\r
385 void OnSelChange(LPOFNOTIFY /*lpon*/)
\r
389 int OnShareViolation(LPOFNOTIFY /*lpon*/)
\r
394 void OnTypeChange(LPOFNOTIFY /*lpon*/)
\r
399 BOOL OnIncludeItem(LPOFNOTIFYEX /*lponex*/)
\r
401 return TRUE; // include item
\r
403 #endif // !_WIN32_WCE
\r
406 class CFileDialog : public CFileDialogImpl<CFileDialog>
\r
409 CFileDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
\r
410 LPCTSTR lpszDefExt = NULL,
\r
411 LPCTSTR lpszFileName = NULL,
\r
412 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
\r
413 LPCTSTR lpszFilter = NULL,
\r
414 HWND hWndParent = NULL)
\r
415 : CFileDialogImpl<CFileDialog>(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
\r
418 // override base class map and references to handlers
\r
419 DECLARE_EMPTY_MSG_MAP()
\r
422 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
\r
423 class CFileDialogEx : public CFileDialogImpl<CFileDialogEx>
\r
426 CFileDialogEx( // Supports only FileOpen
\r
427 LPCTSTR lpszDefExt = NULL,
\r
428 LPCTSTR lpszFileName = NULL,
\r
429 DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
\r
430 OFN_EXFLAG ExFlags = OFN_EXFLAG_THUMBNAILVIEW,
\r
431 OFN_SORTORDER dwSortOrder = OFN_SORTORDER_AUTO,
\r
432 LPCTSTR lpszFilter = NULL,
\r
433 HWND hWndParent = NULL)
\r
434 : CFileDialogImpl<CFileDialogEx>(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
\r
436 m_ofn.ExFlags = ExFlags;
\r
437 m_ofn.dwSortOrder = dwSortOrder;
\r
440 // override base class map and references to handlers
\r
441 DECLARE_EMPTY_MSG_MAP()
\r
443 #endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
\r
446 ///////////////////////////////////////////////////////////////////////////////
\r
447 // Multi File Dialog - Multi-select File Open dialog
\r
451 // The class dynamically resizes the buffer as the file selection changes
\r
452 // (as described in Knowledge Base article 131462). It also expands selected
\r
453 // shortcut files to take into account the full path of the target file.
\r
454 // Note that this doesn't work on Win9x for the old style dialogs, as well as
\r
455 // on NT for non-Unicode builds.
\r
457 #ifndef _WTL_FIXED_OFN_BUFFER_LENGTH
\r
458 #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000
\r
462 class ATL_NO_VTABLE CMultiFileDialogImpl : public CFileDialogImpl< T >
\r
465 mutable LPCTSTR m_pNextFile;
\r
470 CMultiFileDialogImpl(
\r
471 LPCTSTR lpszDefExt = NULL,
\r
472 LPCTSTR lpszFileName = NULL,
\r
473 DWORD dwFlags = OFN_HIDEREADONLY,
\r
474 LPCTSTR lpszFilter = NULL,
\r
475 HWND hWndParent = NULL)
\r
476 : CFileDialogImpl<T>(TRUE, lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent),
\r
479 m_ofn.Flags |= OFN_ALLOWMULTISELECT; // Force multiple selection mode
\r
482 OSVERSIONINFO ovi = { sizeof(ovi) };
\r
483 ::GetVersionEx(&ovi);
\r
484 m_bIsNT = (ovi.dwPlatformId == VER_PLATFORM_WIN32_NT);
\r
487 // On NT platforms, GetOpenFileNameA thunks to GetOpenFileNameW and there
\r
488 // is absolutely nothing we can do except to start off with a large buffer.
\r
489 ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LENGTH));
\r
494 ~CMultiFileDialogImpl()
\r
496 if (m_ofn.lpstrFile != m_szFileName) // Free the buffer if we allocated it
\r
497 delete[] m_ofn.lpstrFile;
\r
501 // Get the directory that the files were chosen from.
\r
502 // The function returns the number of characters copied, not including the terminating zero.
\r
503 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
\r
504 // If the function fails, the return value is zero.
\r
505 int GetDirectory(LPTSTR pBuffer, int nBufLen) const
\r
507 if (m_ofn.lpstrFile == NULL)
\r
510 LPCTSTR pStr = m_ofn.lpstrFile;
\r
511 int nLength = lstrlen(pStr);
\r
512 if (pStr[nLength + 1] == 0)
\r
514 // The OFN buffer contains a single item so extract its path.
\r
515 LPCTSTR pSep = _strrchr(pStr, _T('\\'));
\r
517 nLength = (int)(DWORD_PTR)(pSep - pStr);
\r
521 if (pBuffer == NULL) // If the buffer is NULL, return the required length
\r
523 nRet = nLength + 1;
\r
525 else if (nBufLen > nLength)
\r
527 SecureHelper::strncpy_x(pBuffer, nBufLen, pStr, nLength);
\r
534 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
535 bool GetDirectory(_CSTRING_NS::CString& strDir) const
\r
539 int nLength = GetDirectory(NULL, 0);
\r
542 bRet = (GetDirectory(strDir.GetBuffer(nLength), nLength) > 0);
\r
543 strDir.ReleaseBuffer(nLength - 1);
\r
548 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
550 // Get the first filename as a pointer into the buffer.
\r
551 LPCTSTR GetFirstFileName() const
\r
553 if (m_ofn.lpstrFile == NULL)
\r
556 m_pNextFile = NULL; // Reset internal buffer pointer
\r
558 LPCTSTR pStr = m_ofn.lpstrFile;
\r
559 int nLength = lstrlen(pStr);
\r
560 if (pStr[nLength + 1] != 0)
\r
562 // Multiple items were selected. The first string is the directory,
\r
563 // so skip forwards to the second string.
\r
564 pStr += nLength + 1;
\r
566 // Set up m_pNext so it points to the second item (or null).
\r
567 m_pNextFile = pStr;
\r
572 // A single item was selected. Skip forward past the path.
\r
573 LPCTSTR pSep = _strrchr(pStr, _T('\\'));
\r
581 // Get the next filename as a pointer into the buffer.
\r
582 LPCTSTR GetNextFileName() const
\r
584 if (m_pNextFile == NULL)
\r
587 LPCTSTR pStr = m_pNextFile;
\r
588 // Set "m_pNextFile" to point to the next file name, or null if we
\r
589 // have reached the last file in the list.
\r
590 int nLength = lstrlen(pStr);
\r
591 m_pNextFile = (pStr[nLength + 1] != 0) ? &pStr[nLength + 1] : NULL;
\r
596 // Get the first filename as a full path.
\r
597 // The function returns the number of characters copied, not including the terminating zero.
\r
598 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
\r
599 // If the function fails, the return value is zero.
\r
600 int GetFirstPathName(LPTSTR pBuffer, int nBufLen) const
\r
602 LPCTSTR pStr = GetFirstFileName();
\r
603 int nLengthDir = GetDirectory(NULL, 0);
\r
604 if((pStr == NULL) || (nLengthDir == 0))
\r
607 // Figure out the required length.
\r
608 int nLengthTotal = nLengthDir + lstrlen(pStr);
\r
611 if(pBuffer == NULL) // If the buffer is NULL, return the required length
\r
613 nRet = nLengthTotal + 1;
\r
615 else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path
\r
617 GetDirectory(pBuffer, nBufLen);
\r
618 SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\"));
\r
619 SecureHelper::strcat_x(pBuffer, nBufLen, pStr);
\r
620 nRet = nLengthTotal;
\r
626 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
627 bool GetFirstPathName(_CSTRING_NS::CString& strPath) const
\r
631 int nLength = GetFirstPathName(NULL, 0);
\r
634 bRet = (GetFirstPathName(strPath.GetBuffer(nLength), nLength) > 0);
\r
635 strPath.ReleaseBuffer(nLength - 1);
\r
640 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
642 // Get the next filename as a full path.
\r
643 // The function returns the number of characters copied, not including the terminating zero.
\r
644 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
\r
645 // If the function fails, the return value is zero.
\r
646 // The internal position marker is moved forward only if the function succeeds and the buffer was large enough.
\r
647 int GetNextPathName(LPTSTR pBuffer, int nBufLen) const
\r
649 if (m_pNextFile == NULL)
\r
653 LPCTSTR pStr = m_pNextFile;
\r
654 // Does the filename contain a backslash?
\r
655 if (_strrchr(pStr, _T('\\')) != NULL)
\r
657 // Yes, so we'll assume it's a full path.
\r
658 int nLength = lstrlen(pStr);
\r
660 if (pBuffer == NULL) // If the buffer is NULL, return the required length
\r
662 nRet = nLength + 1;
\r
664 else if (nBufLen > nLength) // The buffer is big enough, so go ahead and copy the filename
\r
666 SecureHelper::strcpy_x(pBuffer, nBufLen, GetNextFileName());
\r
672 // The filename is relative, so construct the full path.
\r
673 int nLengthDir = GetDirectory(NULL, 0);
\r
674 if (nLengthDir > 0)
\r
676 // Calculate the required space.
\r
677 int nLengthTotal = nLengthDir + lstrlen(pStr);
\r
679 if(pBuffer == NULL) // If the buffer is NULL, return the required length
\r
681 nRet = nLengthTotal + 1;
\r
683 else if (nBufLen > nLengthTotal) // If the buffer is big enough, go ahead and construct the path
\r
685 GetDirectory(pBuffer, nBufLen);
\r
686 SecureHelper::strcat_x(pBuffer, nBufLen, _T("\\"));
\r
687 SecureHelper::strcat_x(pBuffer, nBufLen, GetNextFileName());
\r
688 nRet = nLengthTotal;
\r
696 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
697 bool GetNextPathName(_CSTRING_NS::CString& strPath) const
\r
701 int nLength = GetNextPathName(NULL, 0);
\r
704 bRet = (GetNextPathName(strPath.GetBuffer(nLength), nLength) > 0);
\r
705 strPath.ReleaseBuffer(nLength - 1);
\r
710 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
713 bool ResizeFilenameBuffer(DWORD dwLength)
\r
715 if (dwLength > m_ofn.nMaxFile)
\r
717 // Free the old buffer.
\r
718 if (m_ofn.lpstrFile != m_szFileName)
\r
720 delete[] m_ofn.lpstrFile;
\r
721 m_ofn.lpstrFile = NULL;
\r
722 m_ofn.nMaxFile = 0;
\r
725 // Allocate the new buffer.
\r
726 LPTSTR lpstrBuff = NULL;
\r
727 ATLTRY(lpstrBuff = new TCHAR[dwLength]);
\r
728 if (lpstrBuff != NULL)
\r
730 m_ofn.lpstrFile = lpstrBuff;
\r
731 m_ofn.lpstrFile[0] = 0;
\r
732 m_ofn.nMaxFile = dwLength;
\r
736 return (m_ofn.lpstrFile != NULL);
\r
739 void OnSelChange(LPOFNOTIFY /*lpon*/)
\r
742 // There is no point resizing the buffer in ANSI builds running on NT.
\r
747 // Get the buffer length required to hold the spec.
\r
748 int nLength = GetSpec(NULL, 0);
\r
750 return; // no files are selected, presumably
\r
752 // Add room for the directory, and an extra terminating zero.
\r
753 nLength += GetFolderPath(NULL, 0) + 1;
\r
755 if (!ResizeFilenameBuffer(nLength))
\r
761 // If we are not following links then our work is done.
\r
762 if ((m_ofn.Flags & OFN_NODEREFERENCELINKS) != 0)
\r
765 // Get the file spec, which is the text in the edit control.
\r
766 if (GetSpec(m_ofn.lpstrFile, m_ofn.nMaxFile) <= 0)
\r
769 // Get the ID-list of the current folder.
\r
770 int nBytes = GetFolderIDList(NULL, 0);
\r
771 CTempBuffer<ITEMIDLIST> idlist;
\r
772 idlist.AllocateBytes(nBytes);
\r
773 if ((nBytes <= 0) || (GetFolderIDList(idlist, nBytes) <= 0))
\r
776 // First bind to the desktop folder, then to the current folder.
\r
777 ATL::CComPtr<IShellFolder> pDesktop, pFolder;
\r
778 if (FAILED(::SHGetDesktopFolder(&pDesktop)))
\r
780 if (FAILED(pDesktop->BindToObject(idlist, NULL, IID_IShellFolder, (void**)&pFolder)))
\r
783 // Work through the file spec, looking for quoted filenames. If we find a shortcut file, then
\r
784 // we need to add enough extra buffer space to hold its target path.
\r
785 DWORD nExtraChars = 0;
\r
786 bool bInsideQuotes = false;
\r
787 LPCTSTR pAnchor = m_ofn.lpstrFile;
\r
788 LPCTSTR pChar = m_ofn.lpstrFile;
\r
789 for ( ; *pChar; ++pChar)
\r
791 // Look for quotation marks.
\r
792 if (*pChar == _T('\"'))
\r
794 // We are either entering or leaving a passage of quoted text.
\r
795 bInsideQuotes = !bInsideQuotes;
\r
797 // Is it an opening or closing quote?
\r
800 // We found an opening quote, so set "pAnchor" to the following character.
\r
801 pAnchor = pChar + 1;
\r
803 else // closing quote
\r
805 // Each quoted entity should be shorter than MAX_PATH.
\r
806 if (pChar - pAnchor >= MAX_PATH)
\r
809 // Get the ID-list and attributes of the file.
\r
811 int nFileNameLength = (int)(DWORD_PTR)(pChar - pAnchor);
\r
812 TCHAR szFileName[MAX_PATH];
\r
813 SecureHelper::strncpy_x(szFileName, MAX_PATH, pAnchor, nFileNameLength);
\r
814 LPITEMIDLIST pidl = NULL;
\r
815 DWORD dwAttrib = SFGAO_LINK;
\r
816 if (SUCCEEDED(pFolder->ParseDisplayName(NULL, NULL, T2W(szFileName), NULL, &pidl, &dwAttrib)))
\r
818 // Is it a shortcut file?
\r
819 if (dwAttrib & SFGAO_LINK)
\r
821 // Bind to its IShellLink interface.
\r
822 ATL::CComPtr<IShellLink> pLink;
\r
823 if (SUCCEEDED(pFolder->BindToObject(pidl, NULL, IID_IShellLink, (void**)&pLink)))
\r
825 // Get the shortcut's target path.
\r
826 TCHAR szPath[MAX_PATH];
\r
827 if (SUCCEEDED(pLink->GetPath(szPath, MAX_PATH, NULL, 0)))
\r
829 // If the target path is longer than the shortcut name, then add on the number
\r
830 // of extra characters that are required.
\r
831 int nNewLength = lstrlen(szPath);
\r
832 if (nNewLength > nFileNameLength)
\r
833 nExtraChars += nNewLength - nFileNameLength;
\r
838 // Free the ID-list returned by ParseDisplayName.
\r
839 ::CoTaskMemFree(pidl);
\r
845 // If we need more space for shortcut targets, then reallocate.
\r
846 if (nExtraChars > 0)
\r
847 ATLVERIFY(ResizeFilenameBuffer(m_ofn.nMaxFile + nExtraChars));
\r
850 // Helper for _ATM_MIN_CRT
\r
851 static const TCHAR* _strrchr(const TCHAR* p, TCHAR ch)
\r
853 #ifndef _ATL_MIN_CRT
\r
854 return _tcsrchr(p, ch);
\r
855 #else // _ATL_MIN_CRT
\r
856 const TCHAR* lpsz = NULL;
\r
864 #endif // _ATL_MIN_CRT
\r
868 class CMultiFileDialog : public CMultiFileDialogImpl<CMultiFileDialog>
\r
872 LPCTSTR lpszDefExt = NULL,
\r
873 LPCTSTR lpszFileName = NULL,
\r
874 DWORD dwFlags = OFN_HIDEREADONLY,
\r
875 LPCTSTR lpszFilter = NULL,
\r
876 HWND hWndParent = NULL)
\r
877 : CMultiFileDialogImpl<CMultiFileDialog>(lpszDefExt, lpszFileName, dwFlags, lpszFilter, hWndParent)
\r
880 BEGIN_MSG_MAP(CMultiFileDialog)
\r
881 CHAIN_MSG_MAP(CMultiFileDialogImpl<CMultiFileDialog>)
\r
885 #endif // !_WIN32_WCE
\r
888 ///////////////////////////////////////////////////////////////////////////////
\r
889 // Shell File Dialog - new Shell File Open and Save dialogs in Vista
\r
891 // Note: Use GetPtr() to access dialog interface methods.
\r
893 // CShellFileOpenDialog dlg;
\r
894 // dlg.GetPtr()->SetTitle(L"MyFileOpenDialog");
\r
896 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
898 ///////////////////////////////////////////////////////////////////////////////
\r
899 // CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFileSaveDialogImpl
\r
902 class ATL_NO_VTABLE CShellFileDialogImpl : public IFileDialogEvents
\r
906 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
910 T* pT = static_cast<T*>(this);
\r
911 if(pT->m_spFileDlg == NULL)
\r
917 DWORD dwCookie = 0;
\r
918 pT->_Advise(dwCookie);
\r
920 HRESULT hRet = pT->m_spFileDlg->Show(hWndParent);
\r
921 if(SUCCEEDED(hRet))
\r
923 else if(hRet == HRESULT_FROM_WIN32(ERROR_CANCELLED))
\r
926 ATLASSERT(FALSE); // error
\r
928 pT->_Unadvise(dwCookie);
\r
933 bool IsNull() const
\r
935 const T* pT = static_cast<const T*>(this);
\r
936 return (pT->m_spFileDlg == NULL);
\r
939 // Operations - get file path after dialog returns
\r
940 HRESULT GetFilePath(LPWSTR lpstrFilePath, int cchLength)
\r
942 T* pT = static_cast<T*>(this);
\r
943 ATLASSERT(pT->m_spFileDlg != NULL);
\r
945 ATL::CComPtr<IShellItem> spItem;
\r
946 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
\r
948 if(SUCCEEDED(hRet))
\r
949 hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, lpstrFilePath, cchLength);
\r
954 HRESULT GetFileTitle(LPWSTR lpstrFileTitle, int cchLength)
\r
956 T* pT = static_cast<T*>(this);
\r
957 ATLASSERT(pT->m_spFileDlg != NULL);
\r
959 ATL::CComPtr<IShellItem> spItem;
\r
960 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
\r
962 if(SUCCEEDED(hRet))
\r
963 hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, lpstrFileTitle, cchLength);
\r
968 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
969 HRESULT GetFilePath(_CSTRING_NS::CString& strFilePath)
\r
971 T* pT = static_cast<T*>(this);
\r
972 ATLASSERT(pT->m_spFileDlg != NULL);
\r
974 ATL::CComPtr<IShellItem> spItem;
\r
975 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
\r
977 if(SUCCEEDED(hRet))
\r
978 hRet = GetFileNameFromShellItem(spItem, SIGDN_FILESYSPATH, strFilePath);
\r
983 HRESULT GetFileTitle(_CSTRING_NS::CString& strFileTitle)
\r
985 T* pT = static_cast<T*>(this);
\r
986 ATLASSERT(pT->m_spFileDlg != NULL);
\r
988 ATL::CComPtr<IShellItem> spItem;
\r
989 HRESULT hRet = pT->m_spFileDlg->GetResult(&spItem);
\r
991 if(SUCCEEDED(hRet))
\r
992 hRet = GetFileNameFromShellItem(spItem, SIGDN_NORMALDISPLAY, strFileTitle);
\r
996 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
998 // Helpers for IShellItem
\r
999 static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, LPWSTR lpstr, int cchLength)
\r
1001 ATLASSERT(pShellItem != NULL);
\r
1003 LPWSTR lpstrName = NULL;
\r
1004 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
\r
1006 if(SUCCEEDED(hRet))
\r
1008 if(lstrlenW(lpstrName) < cchLength)
\r
1010 SecureHelper::strcpyW_x(lpstr, cchLength, lpstrName);
\r
1015 hRet = DISP_E_BUFFERTOOSMALL;
\r
1018 ::CoTaskMemFree(lpstrName);
\r
1024 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
1025 static HRESULT GetFileNameFromShellItem(IShellItem* pShellItem, SIGDN type, _CSTRING_NS::CString& str)
\r
1027 ATLASSERT(pShellItem != NULL);
\r
1029 LPWSTR lpstrName = NULL;
\r
1030 HRESULT hRet = pShellItem->GetDisplayName(type, &lpstrName);
\r
1032 if(SUCCEEDED(hRet))
\r
1035 ::CoTaskMemFree(lpstrName);
\r
1040 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
\r
1043 void _Advise(DWORD& dwCookie)
\r
1045 T* pT = static_cast<T*>(this);
\r
1046 ATLASSERT(pT->m_spFileDlg != NULL);
\r
1047 HRESULT hRet = pT->m_spFileDlg->Advise((IFileDialogEvents*)this, &dwCookie);
\r
1048 ATLVERIFY(SUCCEEDED(hRet));
\r
1051 void _Unadvise(DWORD dwCookie)
\r
1053 T* pT = static_cast<T*>(this);
\r
1054 ATLASSERT(pT->m_spFileDlg != NULL);
\r
1055 HRESULT hRet = pT->m_spFileDlg->Unadvise(dwCookie);
\r
1056 ATLVERIFY(SUCCEEDED(hRet));
\r
1059 void _Init(LPCWSTR lpszFileName, DWORD dwOptions, LPCWSTR lpszDefExt, const COMDLG_FILTERSPEC* arrFilterSpec, UINT uFilterSpecCount)
\r
1061 T* pT = static_cast<T*>(this);
\r
1062 ATLASSERT(pT->m_spFileDlg != NULL);
\r
1064 HRESULT hRet = E_FAIL;
\r
1066 if(lpszFileName != NULL)
\r
1068 hRet = pT->m_spFileDlg->SetFileName(lpszFileName);
\r
1069 ATLASSERT(SUCCEEDED(hRet));
\r
1072 hRet = pT->m_spFileDlg->SetOptions(dwOptions);
\r
1073 ATLASSERT(SUCCEEDED(hRet));
\r
1075 if(lpszDefExt != NULL)
\r
1077 hRet = pT->m_spFileDlg->SetDefaultExtension(lpszDefExt);
\r
1078 ATLASSERT(SUCCEEDED(hRet));
\r
1081 if(arrFilterSpec != NULL && uFilterSpecCount != 0U)
\r
1083 hRet = pT->m_spFileDlg->SetFileTypes(uFilterSpecCount, arrFilterSpec);
\r
1084 ATLASSERT(SUCCEEDED(hRet));
\r
1088 // Implementation - IUnknown interface
\r
1089 STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
\r
1091 if(ppvObject == NULL)
\r
1094 T* pT = static_cast<T*>(this);
\r
1095 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IFileDialogEvents))
\r
1097 *ppvObject = (IFileDialogEvents*)pT;
\r
1098 // AddRef() not needed
\r
1102 return E_NOINTERFACE;
\r
1105 virtual ULONG STDMETHODCALLTYPE AddRef()
\r
1110 virtual ULONG STDMETHODCALLTYPE Release()
\r
1115 // Implementation - IFileDialogEvents interface
\r
1116 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFileOk(IFileDialog* pfd)
\r
1118 T* pT = static_cast<T*>(this);
\r
1119 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1120 pfd; // avoid level 4 warning
\r
1121 return pT->OnFileOk();
\r
1124 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChanging(IFileDialog* pfd, IShellItem* psiFolder)
\r
1126 T* pT = static_cast<T*>(this);
\r
1127 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1128 pfd; // avoid level 4 warning
\r
1129 return pT->OnFolderChanging(psiFolder);
\r
1132 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnFolderChange(IFileDialog* pfd)
\r
1134 T* pT = static_cast<T*>(this);
\r
1135 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1136 pfd; // avoid level 4 warning
\r
1137 return pT->OnFolderChange();
\r
1140 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnSelectionChange(IFileDialog* pfd)
\r
1142 T* pT = static_cast<T*>(this);
\r
1143 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1144 pfd; // avoid level 4 warning
\r
1145 return pT->OnSelectionChange();
\r
1148 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnShareViolation(IFileDialog* pfd, IShellItem* psi, FDE_SHAREVIOLATION_RESPONSE* pResponse)
\r
1150 T* pT = static_cast<T*>(this);
\r
1151 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1152 pfd; // avoid level 4 warning
\r
1153 return pT->OnShareViolation(psi, pResponse);
\r
1156 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnTypeChange(IFileDialog* pfd)
\r
1158 T* pT = static_cast<T*>(this);
\r
1159 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1160 pfd; // avoid level 4 warning
\r
1161 return pT->OnTypeChange();
\r
1164 virtual HRESULT STDMETHODCALLTYPE IFileDialogEvents::OnOverwrite(IFileDialog* pfd, IShellItem* psi, FDE_OVERWRITE_RESPONSE* pResponse)
\r
1166 T* pT = static_cast<T*>(this);
\r
1167 ATLASSERT(pT->m_spFileDlg.IsEqualObject(pfd));
\r
1168 pfd; // avoid level 4 warning
\r
1169 return pT->OnOverwrite(psi, pResponse);
\r
1172 // Overrideables - Event handlers
\r
1173 HRESULT OnFileOk()
\r
1178 HRESULT OnFolderChanging(IShellItem* /*psiFolder*/)
\r
1183 HRESULT OnFolderChange()
\r
1188 HRESULT OnSelectionChange()
\r
1193 HRESULT OnShareViolation(IShellItem* /*psi*/, FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/)
\r
1198 HRESULT OnTypeChange()
\r
1203 HRESULT OnOverwrite(IShellItem* /*psi*/, FDE_OVERWRITE_RESPONSE* /*pResponse*/)
\r
1210 ///////////////////////////////////////////////////////////////////////////////
\r
1211 // CShellFileOpenDialogImpl - implements new Shell File Open dialog
\r
1213 template <class T>
\r
1214 class ATL_NO_VTABLE CShellFileOpenDialogImpl : public CShellFileDialogImpl< T >
\r
1217 ATL::CComPtr<IFileOpenDialog> m_spFileDlg;
\r
1219 CShellFileOpenDialogImpl(LPCWSTR lpszFileName = NULL,
\r
1220 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
\r
1221 LPCWSTR lpszDefExt = NULL,
\r
1222 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
\r
1223 UINT uFilterSpecCount = 0U)
\r
1225 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileOpenDialog);
\r
1227 if(SUCCEEDED(hRet))
\r
1228 _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
\r
1231 IFileOpenDialog* GetPtr()
\r
1233 return m_spFileDlg;
\r
1238 ///////////////////////////////////////////////////////////////////////////////
\r
1239 // CShellFileOpenDialog - new Shell File Open dialog without events
\r
1241 class CShellFileOpenDialog : public CShellFileOpenDialogImpl<CShellFileOpenDialog>
\r
1244 CShellFileOpenDialog(LPCWSTR lpszFileName = NULL,
\r
1245 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_FILEMUSTEXIST,
\r
1246 LPCWSTR lpszDefExt = NULL,
\r
1247 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
\r
1248 UINT uFilterSpecCount = 0U) : CShellFileOpenDialogImpl<CShellFileOpenDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
\r
1251 // Implementation (remove _Advise/_Unadvise code using template magic)
\r
1252 void _Advise(DWORD& /*dwCookie*/)
\r
1255 void _Unadvise(DWORD /*dwCookie*/)
\r
1260 ///////////////////////////////////////////////////////////////////////////////
\r
1261 // CShellFileSaveDialogImpl - implements new Shell File Save dialog
\r
1263 template <class T>
\r
1264 class ATL_NO_VTABLE CShellFileSaveDialogImpl : public CShellFileDialogImpl< T >
\r
1267 ATL::CComPtr<IFileSaveDialog> m_spFileDlg;
\r
1269 CShellFileSaveDialogImpl(LPCWSTR lpszFileName = NULL,
\r
1270 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
\r
1271 LPCWSTR lpszDefExt = NULL,
\r
1272 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
\r
1273 UINT uFilterSpecCount = 0U)
\r
1275 HRESULT hRet = m_spFileDlg.CoCreateInstance(CLSID_FileSaveDialog);
\r
1277 if(SUCCEEDED(hRet))
\r
1278 _Init(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount);
\r
1281 IFileSaveDialog* GetPtr()
\r
1283 return m_spFileDlg;
\r
1288 ///////////////////////////////////////////////////////////////////////////////
\r
1289 // CShellFileSaveDialog - new Shell File Save dialog without events
\r
1291 class CShellFileSaveDialog : public CShellFileSaveDialogImpl<CShellFileSaveDialog>
\r
1294 CShellFileSaveDialog(LPCWSTR lpszFileName = NULL,
\r
1295 DWORD dwOptions = FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_OVERWRITEPROMPT,
\r
1296 LPCWSTR lpszDefExt = NULL,
\r
1297 const COMDLG_FILTERSPEC* arrFilterSpec = NULL,
\r
1298 UINT uFilterSpecCount = 0U) : CShellFileSaveDialogImpl<CShellFileSaveDialog>(lpszFileName, dwOptions, lpszDefExt, arrFilterSpec, uFilterSpecCount)
\r
1301 // Implementation (remove _Advise/_Unadvise code using template magic)
\r
1302 void _Advise(DWORD& /*dwCookie*/)
\r
1305 void _Unadvise(DWORD /*dwCookie*/)
\r
1309 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
1312 ///////////////////////////////////////////////////////////////////////////////
\r
1313 // CFolderDialogImpl - used for browsing for a folder
\r
1315 #ifndef _WIN32_WCE
\r
1317 template <class T>
\r
1318 class ATL_NO_VTABLE CFolderDialogImpl
\r
1322 LPCTSTR m_lpstrInitialFolder;
\r
1323 LPCITEMIDLIST m_pidlInitialSelection;
\r
1324 bool m_bExpandInitialSelection;
\r
1325 TCHAR m_szFolderDisplayName[MAX_PATH];
\r
1326 TCHAR m_szFolderPath[MAX_PATH];
\r
1327 LPITEMIDLIST m_pidlSelected;
\r
1328 HWND m_hWnd; // used only in the callback function
\r
1331 CFolderDialogImpl(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS) :
\r
1332 m_lpstrInitialFolder(NULL), m_pidlInitialSelection(NULL), m_bExpandInitialSelection(false), m_pidlSelected(NULL), m_hWnd(NULL)
\r
1334 memset(&m_bi, 0, sizeof(m_bi)); // initialize structure to 0/NULL
\r
1336 m_bi.hwndOwner = hWndParent;
\r
1337 m_bi.pidlRoot = NULL;
\r
1338 m_bi.pszDisplayName = m_szFolderDisplayName;
\r
1339 m_bi.lpszTitle = lpstrTitle;
\r
1340 m_bi.ulFlags = uFlags;
\r
1341 m_bi.lpfn = BrowseCallbackProc;
\r
1342 m_bi.lParam = (LPARAM)static_cast<T*>(this);
\r
1344 m_szFolderPath[0] = 0;
\r
1345 m_szFolderDisplayName[0] = 0;
\r
1348 ~CFolderDialogImpl()
\r
1350 ::CoTaskMemFree(m_pidlSelected);
\r
1354 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
1356 if(m_bi.hwndOwner == NULL) // set only if not specified before
\r
1357 m_bi.hwndOwner = hWndParent;
\r
1359 // Clear out any previous results
\r
1360 m_szFolderPath[0] = 0;
\r
1361 m_szFolderDisplayName[0] = 0;
\r
1362 ::CoTaskMemFree(m_pidlSelected);
\r
1364 INT_PTR nRet = IDCANCEL;
\r
1365 m_pidlSelected = ::SHBrowseForFolder(&m_bi);
\r
1367 if(m_pidlSelected != NULL)
\r
1371 // If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path.
\r
1372 // Otherwise, the caller must handle the ID-list directly.
\r
1373 if((m_bi.ulFlags & BIF_RETURNONLYFSDIRS) != 0)
\r
1375 if(::SHGetPathFromIDList(m_pidlSelected, m_szFolderPath) == FALSE)
\r
1383 // Methods to call before DoModal
\r
1384 void SetInitialFolder(LPCTSTR lpstrInitialFolder, bool bExpand = true)
\r
1386 // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified
\r
1387 m_lpstrInitialFolder = lpstrInitialFolder;
\r
1388 m_bExpandInitialSelection = bExpand;
\r
1391 void SetInitialSelection(LPCITEMIDLIST pidl, bool bExpand = true)
\r
1393 m_pidlInitialSelection = pidl;
\r
1394 m_bExpandInitialSelection = bExpand;
\r
1397 // Methods to call after DoModal
\r
1398 LPITEMIDLIST GetSelectedItem(bool bDetach = false)
\r
1400 LPITEMIDLIST pidl = m_pidlSelected;
\r
1402 m_pidlSelected = NULL;
\r
1407 LPCTSTR GetFolderPath() const
\r
1409 return m_szFolderPath;
\r
1412 LPCTSTR GetFolderDisplayName() const
\r
1414 return m_szFolderDisplayName;
\r
1417 int GetFolderImageIndex() const
\r
1419 return m_bi.iImage;
\r
1422 // Callback function and overrideables
\r
1423 static int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
\r
1425 #ifndef BFFM_VALIDATEFAILED
\r
1427 const int BFFM_VALIDATEFAILED = 4;
\r
1429 const int BFFM_VALIDATEFAILED = 3;
\r
1431 #endif // !BFFM_VALIDATEFAILED
\r
1432 #ifndef BFFM_IUNKNOWN
\r
1433 const int BFFM_IUNKNOWN = 5;
\r
1434 #endif // !BFFM_IUNKNOWN
\r
1435 #ifndef BIF_NEWDIALOGSTYLE
\r
1436 const UINT BIF_NEWDIALOGSTYLE = 0x0040;
\r
1437 #endif // !BIF_NEWDIALOGSTYLE
\r
1440 T* pT = (T*)lpData;
\r
1441 bool bClear = false;
\r
1442 if(pT->m_hWnd == NULL)
\r
1444 pT->m_hWnd = hWnd;
\r
1449 ATLASSERT(pT->m_hWnd == hWnd);
\r
1454 case BFFM_INITIALIZED:
\r
1455 // Set initial selection
\r
1456 // Note that m_pidlInitialSelection, if set, takes precedence over m_lpstrInitialFolder
\r
1457 if(pT->m_pidlInitialSelection != NULL)
\r
1458 pT->SetSelection(pT->m_pidlInitialSelection);
\r
1459 else if(pT->m_lpstrInitialFolder != NULL)
\r
1460 pT->SetSelection(pT->m_lpstrInitialFolder);
\r
1462 // Expand initial selection if appropriate
\r
1463 if(pT->m_bExpandInitialSelection && ((pT->m_bi.ulFlags & BIF_NEWDIALOGSTYLE) != 0))
\r
1465 if(pT->m_pidlInitialSelection != NULL)
\r
1466 pT->SetExpanded(pT->m_pidlInitialSelection);
\r
1467 else if(pT->m_lpstrInitialFolder != NULL)
\r
1468 pT->SetExpanded(pT->m_lpstrInitialFolder);
\r
1470 pT->OnInitialized();
\r
1472 case BFFM_SELCHANGED:
\r
1473 pT->OnSelChanged((LPITEMIDLIST)lParam);
\r
1475 case BFFM_VALIDATEFAILED:
\r
1476 nRet = pT->OnValidateFailed((LPCTSTR)lParam);
\r
1478 case BFFM_IUNKNOWN:
\r
1479 pT->OnIUnknown((IUnknown*)lParam);
\r
1482 ATLTRACE2(atlTraceUI, 0, _T("Unknown message received in CFolderDialogImpl::BrowseCallbackProc\n"));
\r
1487 pT->m_hWnd = NULL;
\r
1491 void OnInitialized()
\r
1495 void OnSelChanged(LPITEMIDLIST /*pItemIDList*/)
\r
1499 int OnValidateFailed(LPCTSTR /*lpstrFolderPath*/)
\r
1501 return 1; // 1=continue, 0=EndDialog
\r
1504 void OnIUnknown(IUnknown* /*pUnknown*/)
\r
1508 // Commands - valid to call only from handlers
\r
1509 void EnableOK(BOOL bEnable)
\r
1511 ATLASSERT(m_hWnd != NULL);
\r
1512 ::SendMessage(m_hWnd, BFFM_ENABLEOK, 0, bEnable);
\r
1515 void SetSelection(LPCITEMIDLIST pItemIDList)
\r
1517 ATLASSERT(m_hWnd != NULL);
\r
1518 ::SendMessage(m_hWnd, BFFM_SETSELECTION, FALSE, (LPARAM)pItemIDList);
\r
1521 void SetSelection(LPCTSTR lpstrFolderPath)
\r
1523 ATLASSERT(m_hWnd != NULL);
\r
1524 ::SendMessage(m_hWnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrFolderPath);
\r
1527 void SetStatusText(LPCTSTR lpstrText)
\r
1529 ATLASSERT(m_hWnd != NULL);
\r
1530 ::SendMessage(m_hWnd, BFFM_SETSTATUSTEXT, 0, (LPARAM)lpstrText);
\r
1533 void SetOKText(LPCTSTR lpstrOKText)
\r
1535 #ifndef BFFM_SETOKTEXT
\r
1536 const UINT BFFM_SETOKTEXT = WM_USER + 105;
\r
1538 ATLASSERT(m_hWnd != NULL);
\r
1540 LPCWSTR lpstr = T2CW(lpstrOKText);
\r
1541 ::SendMessage(m_hWnd, BFFM_SETOKTEXT, (WPARAM)lpstr, 0L);
\r
1544 void SetExpanded(LPCITEMIDLIST pItemIDList)
\r
1546 #ifndef BFFM_SETEXPANDED
\r
1547 const UINT BFFM_SETEXPANDED = WM_USER + 106;
\r
1549 ATLASSERT(m_hWnd != NULL);
\r
1550 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, FALSE, (LPARAM)pItemIDList);
\r
1553 void SetExpanded(LPCTSTR lpstrFolderPath)
\r
1555 #ifndef BFFM_SETEXPANDED
\r
1556 const UINT BFFM_SETEXPANDED = WM_USER + 106;
\r
1558 ATLASSERT(m_hWnd != NULL);
\r
1560 LPCWSTR lpstr = T2CW(lpstrFolderPath);
\r
1561 ::SendMessage(m_hWnd, BFFM_SETEXPANDED, TRUE, (LPARAM)lpstr);
\r
1565 class CFolderDialog : public CFolderDialogImpl<CFolderDialog>
\r
1568 CFolderDialog(HWND hWndParent = NULL, LPCTSTR lpstrTitle = NULL, UINT uFlags = BIF_RETURNONLYFSDIRS)
\r
1569 : CFolderDialogImpl<CFolderDialog>(hWndParent, lpstrTitle, uFlags)
\r
1573 #endif // !_WIN32_WCE
\r
1576 ///////////////////////////////////////////////////////////////////////////////
\r
1577 // CCommonDialogImplBase - base class for common dialog classes
\r
1579 class ATL_NO_VTABLE CCommonDialogImplBase : public ATL::CWindowImplBase
\r
1582 static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
1584 if(uMsg != WM_INITDIALOG)
\r
1586 CCommonDialogImplBase* pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData();
\r
1587 ATLASSERT(pT != NULL);
\r
1588 ATLASSERT(pT->m_hWnd == NULL);
\r
1589 ATLASSERT(::IsWindow(hWnd));
\r
1590 // subclass dialog's window
\r
1591 if(!pT->SubclassWindow(hWnd))
\r
1593 ATLTRACE2(atlTraceUI, 0, _T("Subclassing a common dialog failed\n"));
\r
1596 // check message map for WM_INITDIALOG handler
\r
1598 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE)
\r
1603 // Special override for common dialogs
\r
1604 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
\r
1606 ATLASSERT(::IsWindow(m_hWnd));
\r
1607 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0));
\r
1611 // Implementation - try to override these, to prevent errors
\r
1612 HWND Create(HWND, ATL::_U_RECT, LPCTSTR, DWORD, DWORD, ATL::_U_MENUorID, ATOM, LPVOID)
\r
1614 ATLASSERT(FALSE); // should not be called
\r
1618 static LRESULT CALLBACK StartWindowProc(HWND /*hWnd*/, UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/)
\r
1620 ATLASSERT(FALSE); // should not be called
\r
1626 ///////////////////////////////////////////////////////////////////////////////
\r
1627 // CFontDialogImpl - font selection dialog
\r
1629 #ifndef _WIN32_WCE
\r
1631 template <class T>
\r
1632 class ATL_NO_VTABLE CFontDialogImpl : public CCommonDialogImplBase
\r
1635 enum { _cchStyleName = 64 };
\r
1638 TCHAR m_szStyleName[_cchStyleName]; // contains style name after return
\r
1639 LOGFONT m_lf; // default LOGFONT to store the info
\r
1642 CFontDialogImpl(LPLOGFONT lplfInitial = NULL,
\r
1643 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
\r
1644 HDC hDCPrinter = NULL,
\r
1645 HWND hWndParent = NULL)
\r
1647 memset(&m_cf, 0, sizeof(m_cf));
\r
1648 memset(&m_lf, 0, sizeof(m_lf));
\r
1649 memset(&m_szStyleName, 0, sizeof(m_szStyleName));
\r
1651 m_cf.lStructSize = sizeof(m_cf);
\r
1652 m_cf.hwndOwner = hWndParent;
\r
1653 m_cf.rgbColors = RGB(0, 0, 0);
\r
1654 m_cf.lpszStyle = (LPTSTR)&m_szStyleName;
\r
1655 m_cf.Flags = dwFlags | CF_ENABLEHOOK;
\r
1656 m_cf.lpfnHook = (LPCFHOOKPROC)T::HookProc;
\r
1658 if(lplfInitial != NULL)
\r
1660 m_cf.lpLogFont = lplfInitial;
\r
1661 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
\r
1662 m_lf = *lplfInitial;
\r
1666 m_cf.lpLogFont = &m_lf;
\r
1669 if(hDCPrinter != NULL)
\r
1671 m_cf.hDC = hDCPrinter;
\r
1672 m_cf.Flags |= CF_PRINTERFONTS;
\r
1677 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
1679 ATLASSERT((m_cf.Flags & CF_ENABLEHOOK) != 0);
\r
1680 ATLASSERT(m_cf.lpfnHook != NULL); // can still be a user hook
\r
1682 if(m_cf.hwndOwner == NULL) // set only if not specified before
\r
1683 m_cf.hwndOwner = hWndParent;
\r
1685 ATLASSERT(m_hWnd == NULL);
\r
1686 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
\r
1688 BOOL bRet = ::ChooseFont(&m_cf);
\r
1692 if(bRet) // copy logical font from user's initialization buffer (if needed)
\r
1693 SecureHelper::memcpy_x(&m_lf, sizeof(m_lf), m_cf.lpLogFont, sizeof(m_lf));
\r
1695 return bRet ? IDOK : IDCANCEL;
\r
1698 // works only when the dialog is dislayed or after
\r
1699 void GetCurrentFont(LPLOGFONT lplf) const
\r
1701 ATLASSERT(lplf != NULL);
\r
1703 if(m_hWnd != NULL)
\r
1704 ::SendMessage(m_hWnd, WM_CHOOSEFONT_GETLOGFONT, 0, (LPARAM)lplf);
\r
1709 // works only when the dialog is dislayed or before
\r
1710 #ifndef _WIN32_WCE
\r
1711 void SetLogFont(LPLOGFONT lplf)
\r
1713 ATLASSERT(lplf != NULL);
\r
1714 #ifndef WM_CHOOSEFONT_SETLOGFONT
\r
1715 const UINT WM_CHOOSEFONT_SETLOGFONT = (WM_USER + 101);
\r
1717 if(m_hWnd != NULL)
\r
1719 ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETLOGFONT, 0, (LPARAM)lplf);
\r
1724 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
\r
1728 void SetFlags(DWORD dwFlags)
\r
1730 #ifndef WM_CHOOSEFONT_SETFLAGS
\r
1731 const UINT WM_CHOOSEFONT_SETFLAGS = (WM_USER + 102);
\r
1733 if(m_hWnd != NULL)
\r
1735 CHOOSEFONT cf = { sizeof(CHOOSEFONT) };
\r
1736 cf.Flags = dwFlags;
\r
1737 ::SendMessage(m_hWnd, WM_CHOOSEFONT_SETFLAGS, 0, (LPARAM)&cf);
\r
1741 m_cf.Flags = dwFlags;
\r
1744 #endif // !_WIN32_WCE
\r
1746 // Helpers for parsing information after successful return
\r
1747 LPCTSTR GetFaceName() const // return the face name of the font
\r
1749 return (LPCTSTR)m_cf.lpLogFont->lfFaceName;
\r
1752 LPCTSTR GetStyleName() const // return the style name of the font
\r
1754 return m_cf.lpszStyle;
\r
1757 int GetSize() const // return the pt size of the font
\r
1759 return m_cf.iPointSize;
\r
1762 COLORREF GetColor() const // return the color of the font
\r
1764 return m_cf.rgbColors;
\r
1767 int GetWeight() const // return the chosen font weight
\r
1769 return (int)m_cf.lpLogFont->lfWeight;
\r
1772 BOOL IsStrikeOut() const // return TRUE if strikeout
\r
1774 return (m_cf.lpLogFont->lfStrikeOut) ? TRUE : FALSE;
\r
1777 BOOL IsUnderline() const // return TRUE if underline
\r
1779 return (m_cf.lpLogFont->lfUnderline) ? TRUE : FALSE;
\r
1782 BOOL IsBold() const // return TRUE if bold font
\r
1784 return (m_cf.lpLogFont->lfWeight == FW_BOLD) ? TRUE : FALSE;
\r
1787 BOOL IsItalic() const // return TRUE if italic font
\r
1789 return m_cf.lpLogFont->lfItalic ? TRUE : FALSE;
\r
1793 class CFontDialog : public CFontDialogImpl<CFontDialog>
\r
1796 CFontDialog(LPLOGFONT lplfInitial = NULL,
\r
1797 DWORD dwFlags = CF_EFFECTS | CF_SCREENFONTS,
\r
1798 HDC hDCPrinter = NULL,
\r
1799 HWND hWndParent = NULL)
\r
1800 : CFontDialogImpl<CFontDialog>(lplfInitial, dwFlags, hDCPrinter, hWndParent)
\r
1803 DECLARE_EMPTY_MSG_MAP()
\r
1806 #endif // _WIN32_WCE
\r
1809 ///////////////////////////////////////////////////////////////////////////////
\r
1810 // CRichEditFontDialogImpl - font selection for the Rich Edit ctrl
\r
1812 #if defined(_RICHEDIT_) && !defined(_WIN32_WCE)
\r
1814 template <class T>
\r
1815 class ATL_NO_VTABLE CRichEditFontDialogImpl : public CFontDialogImpl< T >
\r
1818 CRichEditFontDialogImpl(const CHARFORMAT& charformat,
\r
1819 DWORD dwFlags = CF_SCREENFONTS,
\r
1820 HDC hDCPrinter = NULL,
\r
1821 HWND hWndParent = NULL)
\r
1822 : CFontDialogImpl< T >(NULL, dwFlags, hDCPrinter, hWndParent)
\r
1824 m_cf.Flags |= CF_INITTOLOGFONTSTRUCT;
\r
1825 m_cf.Flags |= FillInLogFont(charformat);
\r
1826 m_cf.lpLogFont = &m_lf;
\r
1828 if((charformat.dwMask & CFM_COLOR) != 0)
\r
1829 m_cf.rgbColors = charformat.crTextColor;
\r
1832 void GetCharFormat(CHARFORMAT& cf) const
\r
1837 if((m_cf.Flags & CF_NOSTYLESEL) == 0)
\r
1839 cf.dwMask |= CFM_BOLD | CFM_ITALIC;
\r
1840 cf.dwEffects |= IsBold() ? CFE_BOLD : 0;
\r
1841 cf.dwEffects |= IsItalic() ? CFE_ITALIC : 0;
\r
1843 if((m_cf.Flags & CF_NOSIZESEL) == 0)
\r
1845 cf.dwMask |= CFM_SIZE;
\r
1846 // GetSize() returns in tenths of points so mulitply by 2 to get twips
\r
1847 cf.yHeight = GetSize() * 2;
\r
1850 if((m_cf.Flags & CF_NOFACESEL) == 0)
\r
1852 cf.dwMask |= CFM_FACE;
\r
1853 cf.bPitchAndFamily = m_cf.lpLogFont->lfPitchAndFamily;
\r
1854 #if (_RICHEDIT_VER >= 0x0200)
\r
1855 SecureHelper::strcpy_x(cf.szFaceName, _countof(cf.szFaceName), GetFaceName());
\r
1856 #else // !(_RICHEDIT_VER >= 0x0200)
\r
1857 SecureHelper::strcpyA_x(cf.szFaceName, _countof(cf.szFaceName), T2A((LPTSTR)(LPCTSTR)GetFaceName()));
\r
1858 #endif // !(_RICHEDIT_VER >= 0x0200)
\r
1861 if((m_cf.Flags & CF_EFFECTS) != 0)
\r
1863 cf.dwMask |= CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR;
\r
1864 cf.dwEffects |= IsUnderline() ? CFE_UNDERLINE : 0;
\r
1865 cf.dwEffects |= IsStrikeOut() ? CFE_STRIKEOUT : 0;
\r
1866 cf.crTextColor = GetColor();
\r
1868 if((m_cf.Flags & CF_NOSCRIPTSEL) == 0)
\r
1870 cf.bCharSet = m_cf.lpLogFont->lfCharSet;
\r
1871 cf.dwMask |= CFM_CHARSET;
\r
1876 DWORD FillInLogFont(const CHARFORMAT& cf)
\r
1879 DWORD dwFlags = 0;
\r
1880 if((cf.dwMask & CFM_SIZE) != 0)
\r
1882 HDC hDC = ::CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
\r
1883 LONG yPerInch = ::GetDeviceCaps(hDC, LOGPIXELSY);
\r
1884 m_lf.lfHeight = -(int)((cf.yHeight * yPerInch) / 1440);
\r
1887 m_lf.lfHeight = 0;
\r
1890 m_lf.lfEscapement = 0;
\r
1891 m_lf.lfOrientation = 0;
\r
1893 if((cf.dwMask & (CFM_ITALIC | CFM_BOLD)) == (CFM_ITALIC | CFM_BOLD))
\r
1895 m_lf.lfWeight = ((cf.dwEffects & CFE_BOLD) != 0) ? FW_BOLD : FW_NORMAL;
\r
1896 m_lf.lfItalic = (BYTE)(((cf.dwEffects & CFE_ITALIC) != 0) ? TRUE : FALSE);
\r
1900 dwFlags |= CF_NOSTYLESEL;
\r
1901 m_lf.lfWeight = FW_DONTCARE;
\r
1902 m_lf.lfItalic = FALSE;
\r
1905 if((cf.dwMask & (CFM_UNDERLINE | CFM_STRIKEOUT | CFM_COLOR)) == (CFM_UNDERLINE|CFM_STRIKEOUT|CFM_COLOR))
\r
1907 dwFlags |= CF_EFFECTS;
\r
1908 m_lf.lfUnderline = (BYTE)(((cf.dwEffects & CFE_UNDERLINE) != 0) ? TRUE : FALSE);
\r
1909 m_lf.lfStrikeOut = (BYTE)(((cf.dwEffects & CFE_STRIKEOUT) != 0) ? TRUE : FALSE);
\r
1913 m_lf.lfUnderline = (BYTE)FALSE;
\r
1914 m_lf.lfStrikeOut = (BYTE)FALSE;
\r
1917 if((cf.dwMask & CFM_CHARSET) != 0)
\r
1918 m_lf.lfCharSet = cf.bCharSet;
\r
1920 dwFlags |= CF_NOSCRIPTSEL;
\r
1921 m_lf.lfOutPrecision = OUT_DEFAULT_PRECIS;
\r
1922 m_lf.lfClipPrecision = CLIP_DEFAULT_PRECIS;
\r
1923 m_lf.lfQuality = DEFAULT_QUALITY;
\r
1924 if((cf.dwMask & CFM_FACE) != 0)
\r
1926 m_lf.lfPitchAndFamily = cf.bPitchAndFamily;
\r
1927 #if (_RICHEDIT_VER >= 0x0200)
\r
1928 SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), cf.szFaceName);
\r
1929 #else // !(_RICHEDIT_VER >= 0x0200)
\r
1930 SecureHelper::strcpy_x(m_lf.lfFaceName, _countof(m_lf.lfFaceName), A2T((LPSTR)cf.szFaceName));
\r
1931 #endif // !(_RICHEDIT_VER >= 0x0200)
\r
1935 m_lf.lfPitchAndFamily = DEFAULT_PITCH|FF_DONTCARE;
\r
1936 m_lf.lfFaceName[0] = (TCHAR)0;
\r
1942 class CRichEditFontDialog : public CRichEditFontDialogImpl<CRichEditFontDialog>
\r
1945 CRichEditFontDialog(const CHARFORMAT& charformat,
\r
1946 DWORD dwFlags = CF_SCREENFONTS,
\r
1947 HDC hDCPrinter = NULL,
\r
1948 HWND hWndParent = NULL)
\r
1949 : CRichEditFontDialogImpl<CRichEditFontDialog>(charformat, dwFlags, hDCPrinter, hWndParent)
\r
1952 DECLARE_EMPTY_MSG_MAP()
\r
1955 #endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE)
\r
1958 ///////////////////////////////////////////////////////////////////////////////
\r
1959 // CColorDialogImpl - color selection
\r
1961 #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
\r
1964 #pragma comment(lib, "commdlg.lib")
\r
1966 #ifndef SETRGBSTRING
\r
1967 #define SETRGBSTRING _T("commdlg_SetRGBColor")
\r
1970 #ifndef COLOROKSTRING
\r
1971 #define COLOROKSTRING _T("commdlg_ColorOK")
\r
1975 template <class T>
\r
1976 class ATL_NO_VTABLE CColorDialogImpl : public CCommonDialogImplBase
\r
1982 CColorDialogImpl(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL)
\r
1984 memset(&m_cc, 0, sizeof(m_cc));
\r
1986 m_cc.lStructSize = sizeof(m_cc);
\r
1987 m_cc.lpCustColors = GetCustomColors();
\r
1988 m_cc.hwndOwner = hWndParent;
\r
1989 m_cc.Flags = dwFlags | CC_ENABLEHOOK;
\r
1990 m_cc.lpfnHook = (LPCCHOOKPROC)T::HookProc;
\r
1994 m_cc.rgbResult = clrInit;
\r
1995 m_cc.Flags |= CC_RGBINIT;
\r
2000 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
2002 ATLASSERT((m_cc.Flags & CC_ENABLEHOOK) != 0);
\r
2003 ATLASSERT(m_cc.lpfnHook != NULL); // can still be a user hook
\r
2005 if(m_cc.hwndOwner == NULL) // set only if not specified before
\r
2006 m_cc.hwndOwner = hWndParent;
\r
2008 ATLASSERT(m_hWnd == NULL);
\r
2009 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
\r
2011 BOOL bRet = ::ChooseColor(&m_cc);
\r
2015 return bRet ? IDOK : IDCANCEL;
\r
2018 // Set the current color while dialog is displayed
\r
2019 void SetCurrentColor(COLORREF clr)
\r
2021 ATLASSERT(::IsWindow(m_hWnd));
\r
2022 SendMessage(_GetSetRGBMessage(), 0, (LPARAM)clr);
\r
2025 // Get the selected color after DoModal returns, or in OnColorOK
\r
2026 COLORREF GetColor() const
\r
2028 return m_cc.rgbResult;
\r
2031 // Special override for the color dialog
\r
2032 static UINT_PTR APIENTRY HookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
2034 if(uMsg != WM_INITDIALOG && uMsg != _GetColorOKMessage())
\r
2037 LPCHOOSECOLOR lpCC = (LPCHOOSECOLOR)lParam;
\r
2038 CCommonDialogImplBase* pT = NULL;
\r
2040 if(uMsg == WM_INITDIALOG)
\r
2042 pT = (CCommonDialogImplBase*)ModuleHelper::ExtractCreateWndData();
\r
2043 lpCC->lCustData = (LPARAM)pT;
\r
2044 ATLASSERT(pT != NULL);
\r
2045 ATLASSERT(pT->m_hWnd == NULL);
\r
2046 ATLASSERT(::IsWindow(hWnd));
\r
2047 // subclass dialog's window
\r
2048 if(!pT->SubclassWindow(hWnd))
\r
2050 ATLTRACE2(atlTraceUI, 0, _T("Subclassing a Color common dialog failed\n"));
\r
2054 else if(uMsg == _GetColorOKMessage())
\r
2056 pT = (CCommonDialogImplBase*)lpCC->lCustData;
\r
2057 ATLASSERT(pT != NULL);
\r
2058 ATLASSERT(::IsWindow(pT->m_hWnd));
\r
2061 // pass to the message map
\r
2063 if(pT->ProcessWindowMessage(pT->m_hWnd, uMsg, wParam, lParam, lRes, 0) == FALSE)
\r
2069 static COLORREF* GetCustomColors()
\r
2071 static COLORREF rgbCustomColors[16] =
\r
2073 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2074 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2075 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2076 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2077 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2078 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2079 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2080 RGB(255, 255, 255), RGB(255, 255, 255),
\r
2083 return rgbCustomColors;
\r
2086 static UINT _GetSetRGBMessage()
\r
2088 static UINT uSetRGBMessage = 0;
\r
2089 if(uSetRGBMessage == 0)
\r
2091 CStaticDataInitCriticalSectionLock lock;
\r
2092 if(FAILED(lock.Lock()))
\r
2094 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetSetRGBMessage.\n"));
\r
2099 if(uSetRGBMessage == 0)
\r
2100 uSetRGBMessage = ::RegisterWindowMessage(SETRGBSTRING);
\r
2104 ATLASSERT(uSetRGBMessage != 0);
\r
2105 return uSetRGBMessage;
\r
2108 static UINT _GetColorOKMessage()
\r
2110 static UINT uColorOKMessage = 0;
\r
2111 if(uColorOKMessage == 0)
\r
2113 CStaticDataInitCriticalSectionLock lock;
\r
2114 if(FAILED(lock.Lock()))
\r
2116 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetColorOKMessage.\n"));
\r
2121 if(uColorOKMessage == 0)
\r
2122 uColorOKMessage = ::RegisterWindowMessage(COLOROKSTRING);
\r
2126 ATLASSERT(uColorOKMessage != 0);
\r
2127 return uColorOKMessage;
\r
2130 // Message map and handlers
\r
2131 BEGIN_MSG_MAP(CColorDialogImpl)
\r
2132 MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK)
\r
2135 LRESULT _OnColorOK(UINT, WPARAM, LPARAM, BOOL&)
\r
2137 T* pT = static_cast<T*>(this);
\r
2138 return pT->OnColorOK();
\r
2142 BOOL OnColorOK() // validate color
\r
2148 class CColorDialog : public CColorDialogImpl<CColorDialog>
\r
2151 CColorDialog(COLORREF clrInit = 0, DWORD dwFlags = 0, HWND hWndParent = NULL)
\r
2152 : CColorDialogImpl<CColorDialog>(clrInit, dwFlags, hWndParent)
\r
2155 // override base class map and references to handlers
\r
2156 DECLARE_EMPTY_MSG_MAP()
\r
2159 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
\r
2162 ///////////////////////////////////////////////////////////////////////////////
\r
2163 // CPrintDialogImpl - used for Print... and PrintSetup...
\r
2165 #ifndef _WIN32_WCE
\r
2168 static HDC _AtlCreateDC(HGLOBAL hDevNames, HGLOBAL hDevMode)
\r
2170 if(hDevNames == NULL)
\r
2173 LPDEVNAMES lpDevNames = (LPDEVNAMES)::GlobalLock(hDevNames);
\r
2174 LPDEVMODE lpDevMode = (hDevMode != NULL) ? (LPDEVMODE)::GlobalLock(hDevMode) : NULL;
\r
2176 if(lpDevNames == NULL)
\r
2179 HDC hDC = ::CreateDC((LPCTSTR)lpDevNames + lpDevNames->wDriverOffset,
\r
2180 (LPCTSTR)lpDevNames + lpDevNames->wDeviceOffset,
\r
2181 (LPCTSTR)lpDevNames + lpDevNames->wOutputOffset,
\r
2184 ::GlobalUnlock(hDevNames);
\r
2185 if(hDevMode != NULL)
\r
2186 ::GlobalUnlock(hDevMode);
\r
2190 template <class T>
\r
2191 class ATL_NO_VTABLE CPrintDialogImpl : public CCommonDialogImplBase
\r
2194 // print dialog parameter block (note this is a reference)
\r
2198 CPrintDialogImpl(BOOL bPrintSetupOnly = FALSE, // TRUE for Print Setup, FALSE for Print Dialog
\r
2199 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION,
\r
2200 HWND hWndParent = NULL)
\r
2201 : m_pd(m_pdActual)
\r
2203 memset(&m_pdActual, 0, sizeof(m_pdActual));
\r
2205 m_pd.lStructSize = sizeof(m_pdActual);
\r
2206 m_pd.hwndOwner = hWndParent;
\r
2207 m_pd.Flags = (dwFlags | PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK);
\r
2208 m_pd.lpfnPrintHook = (LPPRINTHOOKPROC)T::HookProc;
\r
2209 m_pd.lpfnSetupHook = (LPSETUPHOOKPROC)T::HookProc;
\r
2211 if(bPrintSetupOnly)
\r
2212 m_pd.Flags |= PD_PRINTSETUP;
\r
2214 m_pd.Flags |= PD_RETURNDC;
\r
2216 m_pd.Flags &= ~PD_RETURNIC; // do not support information context
\r
2220 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
2222 ATLASSERT((m_pd.Flags & PD_ENABLEPRINTHOOK) != 0);
\r
2223 ATLASSERT((m_pd.Flags & PD_ENABLESETUPHOOK) != 0);
\r
2224 ATLASSERT(m_pd.lpfnPrintHook != NULL); // can still be a user hook
\r
2225 ATLASSERT(m_pd.lpfnSetupHook != NULL); // can still be a user hook
\r
2226 ATLASSERT((m_pd.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this
\r
2228 if(m_pd.hwndOwner == NULL) // set only if not specified before
\r
2229 m_pd.hwndOwner = hWndParent;
\r
2231 ATLASSERT(m_hWnd == NULL);
\r
2232 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
\r
2234 BOOL bRet = ::PrintDlg(&m_pd);
\r
2238 return bRet ? IDOK : IDCANCEL;
\r
2241 // GetDefaults will not display a dialog but will get device defaults
\r
2242 BOOL GetDefaults()
\r
2244 m_pd.Flags |= PD_RETURNDEFAULT;
\r
2245 ATLASSERT(m_pd.hDevMode == NULL); // must be NULL
\r
2246 ATLASSERT(m_pd.hDevNames == NULL); // must be NULL
\r
2248 return ::PrintDlg(&m_pd);
\r
2251 // Helpers for parsing information after successful return num. copies requested
\r
2252 int GetCopies() const
\r
2254 if((m_pd.Flags & PD_USEDEVMODECOPIES) != 0)
\r
2256 LPDEVMODE lpDevMode = GetDevMode();
\r
2257 return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1;
\r
2260 return m_pd.nCopies;
\r
2263 BOOL PrintCollate() const // TRUE if collate checked
\r
2265 return ((m_pd.Flags & PD_COLLATE) != 0) ? TRUE : FALSE;
\r
2268 BOOL PrintSelection() const // TRUE if printing selection
\r
2270 return ((m_pd.Flags & PD_SELECTION) != 0) ? TRUE : FALSE;
\r
2273 BOOL PrintAll() const // TRUE if printing all pages
\r
2275 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE;
\r
2278 BOOL PrintRange() const // TRUE if printing page range
\r
2280 return ((m_pd.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE;
\r
2283 BOOL PrintToFile() const // TRUE if printing to a file
\r
2285 return ((m_pd.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE;
\r
2288 int GetFromPage() const // starting page if valid
\r
2290 return PrintRange() ? m_pd.nFromPage : -1;
\r
2293 int GetToPage() const // ending page if valid
\r
2295 return PrintRange() ? m_pd.nToPage : -1;
\r
2298 LPDEVMODE GetDevMode() const // return DEVMODE
\r
2300 if(m_pd.hDevMode == NULL)
\r
2303 return (LPDEVMODE)::GlobalLock(m_pd.hDevMode);
\r
2306 LPCTSTR GetDriverName() const // return driver name
\r
2308 if(m_pd.hDevNames == NULL)
\r
2311 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
\r
2315 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
\r
2318 LPCTSTR GetDeviceName() const // return device name
\r
2320 if(m_pd.hDevNames == NULL)
\r
2323 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
\r
2327 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
\r
2330 LPCTSTR GetPortName() const // return output port name
\r
2332 if(m_pd.hDevNames == NULL)
\r
2335 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pd.hDevNames);
\r
2339 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
\r
2342 HDC GetPrinterDC() const // return HDC (caller must delete)
\r
2344 ATLASSERT((m_pd.Flags & PD_RETURNDC) != 0);
\r
2348 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
\r
2349 // This DC is returned, but also stored in m_pd.hDC as though it had been
\r
2350 // returned by CommDlg. It is assumed that any previously obtained DC
\r
2351 // has been/will be deleted by the user. This may be
\r
2352 // used without ever invoking the print/print setup dialogs.
\r
2353 HDC CreatePrinterDC()
\r
2355 m_pd.hDC = _AtlCreateDC(m_pd.hDevNames, m_pd.hDevMode);
\r
2360 PRINTDLG m_pdActual; // the Print/Print Setup need to share this
\r
2362 // The following handle the case of print setup... from the print dialog
\r
2363 CPrintDialogImpl(PRINTDLG& pdInit) : m_pd(pdInit)
\r
2366 BEGIN_MSG_MAP(CPrintDialogImpl)
\r
2368 COMMAND_ID_HANDLER(psh1, OnPrintSetup) // print setup button when print is displayed
\r
2370 COMMAND_ID_HANDLER(0x0400, OnPrintSetup) // value from dlgs.h
\r
2374 LRESULT OnPrintSetup(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/)
\r
2377 ModuleHelper::AddCreateWndData(&dlgSetup.m_thunk.cd, (CCommonDialogImplBase*)&dlgSetup);
\r
2378 return DefWindowProc(WM_COMMAND, MAKEWPARAM(wID, wNotifyCode), (LPARAM)hWndCtl);
\r
2382 class CPrintDialog : public CPrintDialogImpl<CPrintDialog>
\r
2385 CPrintDialog(BOOL bPrintSetupOnly = FALSE,
\r
2386 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION,
\r
2387 HWND hWndParent = NULL)
\r
2388 : CPrintDialogImpl<CPrintDialog>(bPrintSetupOnly, dwFlags, hWndParent)
\r
2391 CPrintDialog(PRINTDLG& pdInit) : CPrintDialogImpl<CPrintDialog>(pdInit)
\r
2395 #endif // _WIN32_WCE
\r
2398 ///////////////////////////////////////////////////////////////////////////////
\r
2399 // CPrintDialogExImpl - new print dialog for Windows 2000
\r
2401 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
\r
2403 }; // namespace WTL
\r
2405 #include <atlcom.h>
\r
2407 extern "C" const __declspec(selectany) IID IID_IPrintDialogCallback = {0x5852a2c3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
\r
2408 extern "C" const __declspec(selectany) IID IID_IPrintDialogServices = {0x509aaeda, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
\r
2413 template <class T>
\r
2414 class ATL_NO_VTABLE CPrintDialogExImpl :
\r
2415 public ATL::CWindow,
\r
2416 public ATL::CMessageMap,
\r
2417 public IPrintDialogCallback,
\r
2418 public ATL::IObjectWithSiteImpl< T >
\r
2421 PRINTDLGEX m_pdex;
\r
2424 CPrintDialogExImpl(DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE,
\r
2425 HWND hWndParent = NULL)
\r
2427 memset(&m_pdex, 0, sizeof(m_pdex));
\r
2429 m_pdex.lStructSize = sizeof(PRINTDLGEX);
\r
2430 m_pdex.hwndOwner = hWndParent;
\r
2431 m_pdex.Flags = dwFlags;
\r
2432 m_pdex.nStartPage = START_PAGE_GENERAL;
\r
2433 // callback object will be set in DoModal
\r
2435 m_pdex.Flags &= ~PD_RETURNIC; // do not support information context
\r
2439 HRESULT DoModal(HWND hWndParent = ::GetActiveWindow())
\r
2441 ATLASSERT(m_hWnd == NULL);
\r
2442 ATLASSERT((m_pdex.Flags & PD_RETURNDEFAULT) == 0); // use GetDefaults for this
\r
2444 if(m_pdex.hwndOwner == NULL) // set only if not specified before
\r
2445 m_pdex.hwndOwner = hWndParent;
\r
2447 T* pT = static_cast<T*>(this);
\r
2448 m_pdex.lpCallback = (IUnknown*)(IPrintDialogCallback*)pT;
\r
2450 HRESULT hResult = ::PrintDlgEx(&m_pdex);
\r
2457 BOOL EndDialog(INT_PTR /*nRetCode*/ = 0)
\r
2459 ATLASSERT(::IsWindow(m_hWnd));
\r
2460 SendMessage(WM_COMMAND, MAKEWPARAM(IDABORT, 0));
\r
2464 // GetDefaults will not display a dialog but will get device defaults
\r
2465 HRESULT GetDefaults()
\r
2467 m_pdex.Flags |= PD_RETURNDEFAULT;
\r
2468 ATLASSERT(m_pdex.hDevMode == NULL); // must be NULL
\r
2469 ATLASSERT(m_pdex.hDevNames == NULL); // must be NULL
\r
2471 return ::PrintDlgEx(&m_pdex);
\r
2474 // Helpers for parsing information after successful return num. copies requested
\r
2475 int GetCopies() const
\r
2477 if((m_pdex.Flags & PD_USEDEVMODECOPIES) != 0)
\r
2479 LPDEVMODE lpDevMode = GetDevMode();
\r
2480 return (lpDevMode != NULL) ? lpDevMode->dmCopies : -1;
\r
2483 return m_pdex.nCopies;
\r
2486 BOOL PrintCollate() const // TRUE if collate checked
\r
2488 return ((m_pdex.Flags & PD_COLLATE) != 0) ? TRUE : FALSE;
\r
2491 BOOL PrintSelection() const // TRUE if printing selection
\r
2493 return ((m_pdex.Flags & PD_SELECTION) != 0) ? TRUE : FALSE;
\r
2496 BOOL PrintAll() const // TRUE if printing all pages
\r
2498 return (!PrintRange() && !PrintSelection()) ? TRUE : FALSE;
\r
2501 BOOL PrintRange() const // TRUE if printing page range
\r
2503 return ((m_pdex.Flags & PD_PAGENUMS) != 0) ? TRUE : FALSE;
\r
2506 BOOL PrintToFile() const // TRUE if printing to a file
\r
2508 return ((m_pdex.Flags & PD_PRINTTOFILE) != 0) ? TRUE : FALSE;
\r
2511 LPDEVMODE GetDevMode() const // return DEVMODE
\r
2513 if(m_pdex.hDevMode == NULL)
\r
2516 return (LPDEVMODE)::GlobalLock(m_pdex.hDevMode);
\r
2519 LPCTSTR GetDriverName() const // return driver name
\r
2521 if(m_pdex.hDevNames == NULL)
\r
2524 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
\r
2528 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
\r
2531 LPCTSTR GetDeviceName() const // return device name
\r
2533 if(m_pdex.hDevNames == NULL)
\r
2536 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
\r
2540 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
\r
2543 LPCTSTR GetPortName() const // return output port name
\r
2545 if(m_pdex.hDevNames == NULL)
\r
2548 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_pdex.hDevNames);
\r
2552 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
\r
2555 HDC GetPrinterDC() const // return HDC (caller must delete)
\r
2557 ATLASSERT((m_pdex.Flags & PD_RETURNDC) != 0);
\r
2558 return m_pdex.hDC;
\r
2561 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
\r
2562 // This DC is returned, but also stored in m_pdex.hDC as though it had been
\r
2563 // returned by CommDlg. It is assumed that any previously obtained DC
\r
2564 // has been/will be deleted by the user. This may be
\r
2565 // used without ever invoking the print/print setup dialogs.
\r
2566 HDC CreatePrinterDC()
\r
2568 m_pdex.hDC = _AtlCreateDC(m_pdex.hDevNames, m_pdex.hDevMode);
\r
2569 return m_pdex.hDC;
\r
2572 // Implementation - interfaces
\r
2575 STDMETHOD(QueryInterface)(REFIID riid, void** ppvObject)
\r
2577 if(ppvObject == NULL)
\r
2580 T* pT = static_cast<T*>(this);
\r
2581 if(IsEqualGUID(riid, IID_IUnknown) || IsEqualGUID(riid, IID_IPrintDialogCallback))
\r
2583 *ppvObject = (IPrintDialogCallback*)pT;
\r
2584 // AddRef() not needed
\r
2587 else if(IsEqualGUID(riid, IID_IObjectWithSite))
\r
2589 *ppvObject = (IObjectWithSite*)pT;
\r
2590 // AddRef() not needed
\r
2594 return E_NOINTERFACE;
\r
2597 virtual ULONG STDMETHODCALLTYPE AddRef()
\r
2602 virtual ULONG STDMETHODCALLTYPE Release()
\r
2607 // IPrintDialogCallback
\r
2608 STDMETHOD(InitDone)()
\r
2613 STDMETHOD(SelectionChange)()
\r
2618 STDMETHOD(HandleMessage)(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT* plResult)
\r
2620 // set up m_hWnd the first time
\r
2621 if(m_hWnd == NULL)
\r
2624 // call message map
\r
2625 HRESULT hRet = ProcessWindowMessage(hWnd, uMsg, wParam, lParam, *plResult, 0) ? S_OK : S_FALSE;
\r
2626 if(hRet == S_OK && uMsg == WM_NOTIFY) // return in DWLP_MSGRESULT
\r
2627 ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT, (LONG_PTR)*plResult);
\r
2629 if(uMsg == WM_INITDIALOG && hRet == S_OK && (BOOL)*plResult != FALSE)
\r
2636 class CPrintDialogEx : public CPrintDialogExImpl<CPrintDialogEx>
\r
2640 DWORD dwFlags = PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_NOSELECTION | PD_NOCURRENTPAGE,
\r
2641 HWND hWndParent = NULL)
\r
2642 : CPrintDialogExImpl<CPrintDialogEx>(dwFlags, hWndParent)
\r
2645 DECLARE_EMPTY_MSG_MAP()
\r
2648 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
\r
2651 ///////////////////////////////////////////////////////////////////////////////
\r
2652 // CPageSetupDialogImpl - Page Setup dialog
\r
2654 #ifndef _WIN32_WCE
\r
2656 template <class T>
\r
2657 class ATL_NO_VTABLE CPageSetupDialogImpl : public CCommonDialogImplBase
\r
2660 PAGESETUPDLG m_psd;
\r
2661 ATL::CWndProcThunk m_thunkPaint;
\r
2664 CPageSetupDialogImpl(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL)
\r
2666 memset(&m_psd, 0, sizeof(m_psd));
\r
2668 m_psd.lStructSize = sizeof(m_psd);
\r
2669 m_psd.hwndOwner = hWndParent;
\r
2670 m_psd.Flags = (dwFlags | PSD_ENABLEPAGESETUPHOOK | PSD_ENABLEPAGEPAINTHOOK);
\r
2671 m_psd.lpfnPageSetupHook = (LPPAGESETUPHOOK)T::HookProc;
\r
2672 m_thunkPaint.Init((WNDPROC)T::PaintHookProc, this);
\r
2673 #if (_ATL_VER >= 0x0700)
\r
2674 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)m_thunkPaint.GetWNDPROC();
\r
2676 m_psd.lpfnPagePaintHook = (LPPAGEPAINTHOOK)&(m_thunkPaint.thunk);
\r
2680 DECLARE_EMPTY_MSG_MAP()
\r
2683 LPDEVMODE GetDevMode() const // return DEVMODE
\r
2685 if(m_psd.hDevMode == NULL)
\r
2688 return (LPDEVMODE)::GlobalLock(m_psd.hDevMode);
\r
2691 LPCTSTR GetDriverName() const // return driver name
\r
2693 if(m_psd.hDevNames == NULL)
\r
2696 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
\r
2697 return (LPCTSTR)lpDev + lpDev->wDriverOffset;
\r
2700 LPCTSTR GetDeviceName() const // return device name
\r
2702 if(m_psd.hDevNames == NULL)
\r
2705 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
\r
2706 return (LPCTSTR)lpDev + lpDev->wDeviceOffset;
\r
2709 LPCTSTR GetPortName() const // return output port name
\r
2711 if(m_psd.hDevNames == NULL)
\r
2714 LPDEVNAMES lpDev = (LPDEVNAMES)::GlobalLock(m_psd.hDevNames);
\r
2715 return (LPCTSTR)lpDev + lpDev->wOutputOffset;
\r
2718 HDC CreatePrinterDC()
\r
2720 return _AtlCreateDC(m_psd.hDevNames, m_psd.hDevMode);
\r
2723 SIZE GetPaperSize() const
\r
2726 size.cx = m_psd.ptPaperSize.x;
\r
2727 size.cy = m_psd.ptPaperSize.y;
\r
2731 void GetMargins(LPRECT lpRectMargins, LPRECT lpRectMinMargins) const
\r
2733 if(lpRectMargins != NULL)
\r
2734 *lpRectMargins = m_psd.rtMargin;
\r
2735 if(lpRectMinMargins != NULL)
\r
2736 *lpRectMinMargins = m_psd.rtMinMargin;
\r
2740 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
2742 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGESETUPHOOK) != 0);
\r
2743 ATLASSERT((m_psd.Flags & PSD_ENABLEPAGEPAINTHOOK) != 0);
\r
2744 ATLASSERT(m_psd.lpfnPageSetupHook != NULL); // can still be a user hook
\r
2745 ATLASSERT(m_psd.lpfnPagePaintHook != NULL); // can still be a user hook
\r
2747 if(m_psd.hwndOwner == NULL) // set only if not specified before
\r
2748 m_psd.hwndOwner = hWndParent;
\r
2750 ATLASSERT(m_hWnd == NULL);
\r
2751 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
\r
2753 BOOL bRet = ::PageSetupDlg(&m_psd);
\r
2757 return bRet ? IDOK : IDCANCEL;
\r
2761 static UINT_PTR CALLBACK PaintHookProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
2764 UINT_PTR uRet = 0;
\r
2767 case WM_PSD_PAGESETUPDLG:
\r
2768 uRet = pT->PreDrawPage(LOWORD(wParam), HIWORD(wParam), (LPPAGESETUPDLG)lParam);
\r
2770 case WM_PSD_FULLPAGERECT:
\r
2771 case WM_PSD_MINMARGINRECT:
\r
2772 case WM_PSD_MARGINRECT:
\r
2773 case WM_PSD_GREEKTEXTRECT:
\r
2774 case WM_PSD_ENVSTAMPRECT:
\r
2775 case WM_PSD_YAFULLPAGERECT:
\r
2776 uRet = pT->OnDrawPage(uMsg, (HDC)wParam, (LPRECT)lParam);
\r
2779 ATLTRACE2(atlTraceUI, 0, _T("CPageSetupDialogImpl::PaintHookProc - unknown message received\n"));
\r
2786 UINT_PTR PreDrawPage(WORD /*wPaper*/, WORD /*wFlags*/, LPPAGESETUPDLG /*pPSD*/)
\r
2788 // return 1 to prevent any more drawing
\r
2792 UINT_PTR OnDrawPage(UINT /*uMsg*/, HDC /*hDC*/, LPRECT /*lpRect*/)
\r
2794 return 0; // do the default
\r
2798 class CPageSetupDialog : public CPageSetupDialogImpl<CPageSetupDialog>
\r
2801 CPageSetupDialog(DWORD dwFlags = PSD_MARGINS | PSD_INWININIINTLMEASURE, HWND hWndParent = NULL)
\r
2802 : CPageSetupDialogImpl<CPageSetupDialog>(dwFlags, hWndParent)
\r
2805 // override PaintHookProc and references to handlers
\r
2806 static UINT_PTR CALLBACK PaintHookProc(HWND, UINT, WPARAM, LPARAM)
\r
2812 #endif // _WIN32_WCE
\r
2815 ///////////////////////////////////////////////////////////////////////////////
\r
2816 // CFindReplaceDialogImpl - Find/FindReplace modeless dialogs
\r
2818 #ifndef _WIN32_WCE
\r
2820 template <class T>
\r
2821 class ATL_NO_VTABLE CFindReplaceDialogImpl : public CCommonDialogImplBase
\r
2824 enum { _cchFindReplaceBuffer = 128 };
\r
2827 TCHAR m_szFindWhat[_cchFindReplaceBuffer];
\r
2828 TCHAR m_szReplaceWith[_cchFindReplaceBuffer];
\r
2831 CFindReplaceDialogImpl()
\r
2833 memset(&m_fr, 0, sizeof(m_fr));
\r
2834 m_szFindWhat[0] = _T('\0');
\r
2835 m_szReplaceWith[0] = _T('\0');
\r
2837 m_fr.lStructSize = sizeof(m_fr);
\r
2838 m_fr.Flags = FR_ENABLEHOOK;
\r
2839 m_fr.lpfnHook = (LPFRHOOKPROC)T::HookProc;
\r
2840 m_fr.lpstrFindWhat = (LPTSTR)m_szFindWhat;
\r
2841 m_fr.wFindWhatLen = _cchFindReplaceBuffer;
\r
2842 m_fr.lpstrReplaceWith = (LPTSTR)m_szReplaceWith;
\r
2843 m_fr.wReplaceWithLen = _cchFindReplaceBuffer;
\r
2846 // Note: You must allocate the object on the heap.
\r
2847 // If you do not, you must override OnFinalMessage()
\r
2848 virtual void OnFinalMessage(HWND /*hWnd*/)
\r
2853 HWND Create(BOOL bFindDialogOnly, // TRUE for Find, FALSE for FindReplace
\r
2854 LPCTSTR lpszFindWhat,
\r
2855 LPCTSTR lpszReplaceWith = NULL,
\r
2856 DWORD dwFlags = FR_DOWN,
\r
2857 HWND hWndParent = NULL)
\r
2859 ATLASSERT((m_fr.Flags & FR_ENABLEHOOK) != 0);
\r
2860 ATLASSERT(m_fr.lpfnHook != NULL);
\r
2862 m_fr.Flags |= dwFlags;
\r
2864 if(hWndParent == NULL)
\r
2865 m_fr.hwndOwner = ::GetActiveWindow();
\r
2867 m_fr.hwndOwner = hWndParent;
\r
2868 ATLASSERT(m_fr.hwndOwner != NULL); // must have an owner for modeless dialog
\r
2870 if(lpszFindWhat != NULL)
\r
2871 SecureHelper::strncpy_x(m_szFindWhat, _countof(m_szFindWhat), lpszFindWhat, _TRUNCATE);
\r
2873 if(lpszReplaceWith != NULL)
\r
2874 SecureHelper::strncpy_x(m_szReplaceWith, _countof(m_szReplaceWith), lpszReplaceWith, _TRUNCATE);
\r
2876 ATLASSERT(m_hWnd == NULL);
\r
2877 ModuleHelper::AddCreateWndData(&m_thunk.cd, (CCommonDialogImplBase*)this);
\r
2880 if(bFindDialogOnly)
\r
2881 hWnd = ::FindText(&m_fr);
\r
2883 hWnd = ::ReplaceText(&m_fr);
\r
2885 ATLASSERT(m_hWnd == hWnd);
\r
2889 static const UINT GetFindReplaceMsg()
\r
2891 static const UINT nMsgFindReplace = ::RegisterWindowMessage(FINDMSGSTRING);
\r
2892 return nMsgFindReplace;
\r
2894 // call while handling FINDMSGSTRING registered message
\r
2895 // to retreive the object
\r
2896 static T* PASCAL GetNotifier(LPARAM lParam)
\r
2898 ATLASSERT(lParam != NULL);
\r
2899 T* pDlg = (T*)(lParam - offsetof(T, m_fr));
\r
2904 // Helpers for parsing information after successful return
\r
2905 LPCTSTR GetFindString() const // get find string
\r
2907 return (LPCTSTR)m_fr.lpstrFindWhat;
\r
2910 LPCTSTR GetReplaceString() const // get replacement string
\r
2912 return (LPCTSTR)m_fr.lpstrReplaceWith;
\r
2915 BOOL SearchDown() const // TRUE if search down, FALSE is up
\r
2917 return ((m_fr.Flags & FR_DOWN) != 0) ? TRUE : FALSE;
\r
2920 BOOL FindNext() const // TRUE if command is find next
\r
2922 return ((m_fr.Flags & FR_FINDNEXT) != 0) ? TRUE : FALSE;
\r
2925 BOOL MatchCase() const // TRUE if matching case
\r
2927 return ((m_fr.Flags & FR_MATCHCASE) != 0) ? TRUE : FALSE;
\r
2930 BOOL MatchWholeWord() const // TRUE if matching whole words only
\r
2932 return ((m_fr.Flags & FR_WHOLEWORD) != 0) ? TRUE : FALSE;
\r
2935 BOOL ReplaceCurrent() const // TRUE if replacing current string
\r
2937 return ((m_fr. Flags & FR_REPLACE) != 0) ? TRUE : FALSE;
\r
2940 BOOL ReplaceAll() const // TRUE if replacing all occurrences
\r
2942 return ((m_fr.Flags & FR_REPLACEALL) != 0) ? TRUE : FALSE;
\r
2945 BOOL IsTerminating() const // TRUE if terminating dialog
\r
2947 return ((m_fr.Flags & FR_DIALOGTERM) != 0) ? TRUE : FALSE ;
\r
2951 class CFindReplaceDialog : public CFindReplaceDialogImpl<CFindReplaceDialog>
\r
2954 DECLARE_EMPTY_MSG_MAP()
\r
2957 #endif // !_WIN32_WCE
\r
2960 #if (_ATL_VER >= 0x800)
\r
2961 typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX;
\r
2962 typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX;
\r
2963 #else // (_ATL_VER >= 0x800)
\r
2964 typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX;
\r
2965 #pragma pack(push, 4)
\r
2966 struct DLGITEMTEMPLATEEX
\r
2978 #endif // (_ATL_VER >= 0x800)
\r
2981 ///////////////////////////////////////////////////////////////////////////////
\r
2982 // CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX
\r
2984 class CMemDlgTemplate
\r
2989 CTRL_BUTTON = 0x0080,
\r
2990 CTRL_EDIT = 0x0081,
\r
2991 CTRL_STATIC = 0x0082,
\r
2992 CTRL_LISTBOX = 0x0083,
\r
2993 CTRL_SCROLLBAR = 0x0084,
\r
2994 CTRL_COMBOBOX = 0x0085
\r
2997 CMemDlgTemplate() : m_pData(NULL), m_pPtr(NULL), m_cAllocated(0)
\r
3000 ~CMemDlgTemplate()
\r
3005 bool IsValid() const
\r
3007 return (m_pData != NULL);
\r
3010 bool IsTemplateEx() const
\r
3012 return (IsValid() && ((DLGTEMPLATEEX*)m_pData)->signature == 0xFFFF);
\r
3015 LPDLGTEMPLATE GetTemplatePtr()
\r
3017 return reinterpret_cast<LPDLGTEMPLATE>(m_pData);
\r
3020 DLGTEMPLATEEX* GetTemplateExPtr()
\r
3022 return reinterpret_cast<DLGTEMPLATEEX*>(m_pData);
\r
3028 ATLVERIFY(::GlobalFree(m_pData) == NULL);
\r
3035 void Create(bool bDlgEx, LPCTSTR lpszCaption, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle = 0, DWORD dwExStyle = 0,
\r
3036 LPCTSTR lpstrFontName = NULL, WORD wFontSize = 0, WORD wWeight = 0, BYTE bItalic = 0, BYTE bCharset = 0, DWORD dwHelpID = 0,
\r
3037 ATL::_U_STRINGorID ClassName = 0U, ATL::_U_STRINGorID Menu = 0U)
\r
3039 // Should have DS_SETFONT style to set the dialog font name and size
\r
3040 if (lpstrFontName != NULL)
\r
3042 dwStyle |= DS_SETFONT;
\r
3046 dwStyle &= ~DS_SETFONT;
\r
3051 DLGTEMPLATEEX dlg = {1, 0xFFFF, dwHelpID, dwExStyle, dwStyle, 0, nX, nY, nWidth, nHeight};
\r
3052 AddData(&dlg, sizeof(dlg));
\r
3056 DLGTEMPLATE dlg = {dwStyle, dwExStyle, 0, nX, nY, nWidth, nHeight};
\r
3057 AddData(&dlg, sizeof(dlg));
\r
3060 #ifndef _WIN32_WCE
\r
3061 if (Menu.m_lpstr == NULL)
\r
3063 WORD menuData = 0;
\r
3064 AddData(&menuData, sizeof(WORD));
\r
3066 else if (IS_INTRESOURCE(Menu.m_lpstr))
\r
3068 WORD menuData[] = {0xFFFF, (WORD)Menu.m_lpstr};
\r
3069 AddData(menuData, sizeof(menuData));
\r
3073 AddString(Menu.m_lpstr);
\r
3075 #else // _WIN32_WCE
\r
3076 // Windows CE doesn't support the addition of menus to a dialog box
\r
3077 ATLASSERT(Menu.m_lpstr == NULL);
\r
3078 Menu.m_lpstr; // avoid level 4 warning
\r
3079 WORD menuData = 0;
\r
3080 AddData(&menuData, sizeof(WORD));
\r
3081 #endif // _WIN32_WCE
\r
3083 if (ClassName.m_lpstr == NULL)
\r
3085 WORD classData = 0;
\r
3086 AddData(&classData, sizeof(WORD));
\r
3088 else if (IS_INTRESOURCE(ClassName.m_lpstr))
\r
3090 WORD classData[] = {0xFFFF, (WORD)ClassName.m_lpstr};
\r
3091 AddData(classData, sizeof(classData));
\r
3095 AddString(ClassName.m_lpstr);
\r
3098 // Set dialog caption
\r
3099 AddString(lpszCaption);
\r
3101 if (lpstrFontName != NULL)
\r
3103 AddData(&wFontSize, sizeof(wFontSize));
\r
3107 AddData(&wWeight, sizeof(wWeight));
\r
3108 AddData(&bItalic, sizeof(bItalic));
\r
3109 AddData(&bCharset, sizeof(bCharset));
\r
3112 AddString(lpstrFontName);
\r
3116 void AddControl(ATL::_U_STRINGorID ClassName, WORD wId, short nX, short nY, short nWidth, short nHeight, DWORD dwStyle, DWORD dwExStyle,
\r
3117 ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
\r
3119 ATLASSERT(IsValid());
\r
3121 // DWORD align data
\r
3122 m_pPtr = (LPBYTE)(DWORD_PTR)((DWORD)(DWORD_PTR)(m_pPtr + 3) & (~3));
\r
3124 if (IsTemplateEx())
\r
3126 DLGTEMPLATEEX* dlg = (DLGTEMPLATEEX*)m_pData;
\r
3129 DLGITEMTEMPLATEEX item = {dwHelpID, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, nX, nY, nWidth, nHeight, wId};
\r
3130 AddData(&item, sizeof(item));
\r
3134 LPDLGTEMPLATE dlg = (LPDLGTEMPLATE)m_pData;
\r
3137 DLGITEMTEMPLATE item = {ATL::CControlWinTraits::GetWndStyle(0) | dwStyle, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle, nX, nY, nWidth, nHeight, wId};
\r
3138 AddData(&item, sizeof(item));
\r
3141 ATLASSERT(ClassName.m_lpstr != NULL);
\r
3142 if (IS_INTRESOURCE(ClassName.m_lpstr))
\r
3144 WORD wData[] = {0xFFFF, (WORD)ClassName.m_lpstr};
\r
3145 AddData(wData, sizeof(wData));
\r
3149 AddString(ClassName.m_lpstr);
\r
3152 if (Text.m_lpstr == NULL)
\r
3154 WORD classData = 0;
\r
3155 AddData(&classData, sizeof(WORD));
\r
3157 else if (IS_INTRESOURCE(Text.m_lpstr))
\r
3159 WORD wData[] = {0xFFFF, (WORD)Text.m_lpstr};
\r
3160 AddData(wData, sizeof(wData));
\r
3164 AddString(Text.m_lpstr);
\r
3167 AddData(&nCreationData, sizeof(nCreationData));
\r
3169 if ((nCreationData != 0))
\r
3171 ATLASSERT(pCreationData != NULL);
\r
3172 AddData(pCreationData, nCreationData * sizeof(WORD));
\r
3176 void AddStdControl(StdCtrlType CtrlType, WORD wId, short nX, short nY, short nWidth, short nHeight,
\r
3177 DWORD dwStyle, DWORD dwExStyle, ATL::_U_STRINGorID Text, const WORD* pCreationData = NULL, WORD nCreationData = 0, DWORD dwHelpID = 0)
\r
3179 AddControl(CtrlType, wId, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, Text, pCreationData, nCreationData, dwHelpID);
\r
3183 void AddData(LPCVOID pData, size_t nData)
\r
3185 ATLASSERT(pData != NULL);
\r
3187 const size_t ALLOCATION_INCREMENT = 1024;
\r
3189 if (m_pData == NULL)
\r
3191 m_cAllocated = ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
\r
3192 m_pPtr = m_pData = static_cast<LPBYTE>(::GlobalAlloc(GPTR, m_cAllocated));
\r
3193 ATLASSERT(m_pData != NULL);
\r
3195 else if (((m_pPtr - m_pData) + nData) > m_cAllocated)
\r
3197 size_t ptrPos = (m_pPtr - m_pData);
\r
3198 m_cAllocated += ((nData / ALLOCATION_INCREMENT) + 1) * ALLOCATION_INCREMENT;
\r
3199 m_pData = static_cast<LPBYTE>(::GlobalReAlloc(m_pData, m_cAllocated, 0));
\r
3200 ATLASSERT(m_pData != NULL);
\r
3201 m_pPtr = m_pData + ptrPos;
\r
3204 SecureHelper::memcpy_x(m_pPtr, m_cAllocated - (m_pPtr - m_pData), pData, nData);
\r
3209 void AddString(LPCTSTR lpszStr)
\r
3211 if (lpszStr == NULL)
\r
3213 WCHAR szEmpty = 0;
\r
3214 AddData(&szEmpty, sizeof(szEmpty));
\r
3219 LPCWSTR lpstr = T2CW(lpszStr);
\r
3220 int nSize = lstrlenW(lpstr) + 1;
\r
3221 AddData(lpstr, nSize * sizeof(WCHAR));
\r
3227 SIZE_T m_cAllocated;
\r
3231 ///////////////////////////////////////////////////////////////////////////////
\r
3232 // Dialog and control macros for indirect dialogs
\r
3234 // for DLGTEMPLATE
\r
3235 #define BEGIN_DIALOG(x, y, width, height) \
\r
3236 void DoInitTemplate() \
\r
3238 bool bExTemplate = false; \
\r
3239 short nX = x, nY = y, nWidth = width, nHeight = height; \
\r
3240 LPCTSTR szCaption = NULL; \
\r
3241 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
\r
3242 DWORD dwExStyle = 0; \
\r
3243 LPCTSTR szFontName = NULL; \
\r
3244 WORD wFontSize = 0; \
\r
3245 WORD wWeight = 0; \
\r
3246 BYTE bItalic = 0; \
\r
3247 BYTE bCharset = 0; \
\r
3248 DWORD dwHelpID = 0; \
\r
3249 ATL::_U_STRINGorID Menu = 0U; \
\r
3250 ATL::_U_STRINGorID ClassName = 0U;
\r
3252 // for DLGTEMPLATEEX
\r
3253 #define BEGIN_DIALOG_EX(x, y, width, height, helpID) \
\r
3254 void DoInitTemplate() \
\r
3256 bool bExTemplate = true; \
\r
3257 short nX = x, nY = y, nWidth = width, nHeight = height; \
\r
3258 LPCTSTR szCaption = NULL; \
\r
3259 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
\r
3260 DWORD dwExStyle = 0; \
\r
3261 LPCTSTR szFontName = NULL; \
\r
3262 WORD wFontSize = 0; \
\r
3263 WORD wWeight = 0; \
\r
3264 BYTE bItalic = 0; \
\r
3265 BYTE bCharset = 0; \
\r
3266 DWORD dwHelpID = helpID; \
\r
3267 ATL::_U_STRINGorID Menu = 0U; \
\r
3268 ATL::_U_STRINGorID ClassName = 0U;
\r
3270 #define END_DIALOG() \
\r
3271 m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName, Menu); \
\r
3274 #define DIALOG_CAPTION(caption) \
\r
3275 szCaption = caption;
\r
3276 #define DIALOG_STYLE(style) \
\r
3278 #define DIALOG_EXSTYLE(exStyle) \
\r
3279 dwExStyle = exStyle;
\r
3280 #define DIALOG_FONT(pointSize, typeFace) \
\r
3281 wFontSize = pointSize; \
\r
3282 szFontName = typeFace;
\r
3283 #define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \
\r
3284 ATLASSERT(bExTemplate); \
\r
3285 wFontSize = pointsize; \
\r
3286 szFontName = typeface; \
\r
3287 wWeight = weight; \
\r
3288 bItalic = italic; \
\r
3289 bCharset = charset;
\r
3290 #define DIALOG_MENU(menuName) \
\r
3292 #define DIALOG_CLASS(className) \
\r
3293 ClassName = className;
\r
3295 #define BEGIN_CONTROLS_MAP() \
\r
3296 void DoInitControls() \
\r
3299 #define END_CONTROLS_MAP() \
\r
3303 #define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \
\r
3304 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0);
\r
3305 #define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \
\r
3306 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0);
\r
3307 #define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \
\r
3308 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0);
\r
3309 #define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
\r
3310 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3311 #define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
\r
3312 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3313 #ifndef _WIN32_WCE
\r
3314 #define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \
\r
3315 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3316 #endif // !_WIN32_WCE
\r
3317 #define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \
\r
3318 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3319 #define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \
\r
3320 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3321 #define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \
\r
3322 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3323 #define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \
\r
3324 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3325 #define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
\r
3326 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3327 #define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
\r
3328 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
\r
3329 #define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \
\r
3330 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_COMBOBOX, (WORD)id, x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
\r
3331 #define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \
\r
3332 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_EDIT, (WORD)id, x, y, width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
\r
3333 #define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \
\r
3334 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0);
\r
3335 #define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \
\r
3336 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_LISTBOX, (WORD)id, x, y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL, 0);
\r
3337 #define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \
\r
3338 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_SCROLLBAR, (WORD)id, x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0);
\r
3339 #define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \
\r
3340 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_ICON, exStyle, text, NULL, 0);
\r
3341 #define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle) \
\r
3342 m_Template.AddControl(className, (WORD)id, x, y, width, height, style, exStyle, text, NULL, 0);
\r
3345 ///////////////////////////////////////////////////////////////////////////////
\r
3346 // CIndirectDialogImpl - dialogs with template in memory
\r
3348 template <class T, class TDlgTemplate = CMemDlgTemplate, class TBase = ATL::CDialogImpl<T, ATL::CWindow> >
\r
3349 class ATL_NO_VTABLE CIndirectDialogImpl : public TBase
\r
3352 enum { IDD = 0 }; // no dialog template resource
\r
3354 TDlgTemplate m_Template;
\r
3356 void CreateTemplate()
\r
3358 T* pT = static_cast<T*>(this);
\r
3359 pT->DoInitTemplate();
\r
3360 pT->DoInitControls();
\r
3363 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow(), LPARAM dwInitParam = NULL)
\r
3365 T* pT = static_cast<T*>(this);
\r
3366 ATLASSERT(pT->m_hWnd == NULL);
\r
3368 if (!m_Template.IsValid())
\r
3371 #if (_ATL_VER >= 0x0800)
\r
3372 // Allocate the thunk structure here, where we can fail gracefully.
\r
3373 BOOL result = m_thunk.Init(NULL, NULL);
\r
3374 if (result == FALSE)
\r
3376 SetLastError(ERROR_OUTOFMEMORY);
\r
3379 #endif // (_ATL_VER >= 0x0800)
\r
3381 ModuleHelper::AddCreateWndData(&m_thunk.cd, pT);
\r
3387 return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstance(), m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
\r
3390 HWND Create(HWND hWndParent, LPARAM dwInitParam = NULL)
\r
3392 T* pT = static_cast<T*>(this);
\r
3393 ATLASSERT(pT->m_hWnd == NULL);
\r
3395 if (!m_Template.IsValid())
\r
3398 #if (_ATL_VER >= 0x0800)
\r
3399 // Allocate the thunk structure here, where we can fail gracefully.
\r
3400 BOOL result = m_thunk.Init(NULL, NULL);
\r
3401 if (result == FALSE)
\r
3403 SetLastError(ERROR_OUTOFMEMORY);
\r
3406 #endif // (_ATL_VER >= 0x0800)
\r
3408 ModuleHelper::AddCreateWndData(&m_thunk.cd, pT);
\r
3414 HWND hWnd = ::CreateDialogIndirectParam(ModuleHelper::GetResourceInstance(), (LPCDLGTEMPLATE)m_Template.GetTemplatePtr(), hWndParent, (DLGPROC)T::StartDialogProc, dwInitParam);
\r
3415 ATLASSERT(m_hWnd == hWnd);
\r
3420 // for CComControl
\r
3421 HWND Create(HWND hWndParent, RECT&, LPARAM dwInitParam = NULL)
\r
3423 return Create(hWndParent, dwInitParam);
\r
3426 void DoInitTemplate()
\r
3428 ATLASSERT(FALSE); // MUST be defined in derived class
\r
3431 void DoInitControls()
\r
3433 ATLASSERT(FALSE); // MUST be defined in derived class
\r
3437 ///////////////////////////////////////////////////////////////////////////////
\r
3438 // CPropertySheetWindow - client side for a property sheet
\r
3440 class CPropertySheetWindow : public ATL::CWindow
\r
3444 CPropertySheetWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd)
\r
3447 CPropertySheetWindow& operator =(HWND hWnd)
\r
3454 int GetPageCount() const
\r
3456 ATLASSERT(::IsWindow(m_hWnd));
\r
3457 HWND hWndTabCtrl = GetTabControl();
\r
3458 ATLASSERT(hWndTabCtrl != NULL);
\r
3459 return (int)::SendMessage(hWndTabCtrl, TCM_GETITEMCOUNT, 0, 0L);
\r
3462 HWND GetActivePage() const
\r
3464 ATLASSERT(::IsWindow(m_hWnd));
\r
3465 return (HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0L);
\r
3468 int GetActiveIndex() const
\r
3470 ATLASSERT(::IsWindow(m_hWnd));
\r
3471 HWND hWndTabCtrl = GetTabControl();
\r
3472 ATLASSERT(hWndTabCtrl != NULL);
\r
3473 return (int)::SendMessage(hWndTabCtrl, TCM_GETCURSEL, 0, 0L);
\r
3476 BOOL SetActivePage(int nPageIndex)
\r
3478 ATLASSERT(::IsWindow(m_hWnd));
\r
3479 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, nPageIndex, 0L);
\r
3482 BOOL SetActivePage(HPROPSHEETPAGE hPage)
\r
3484 ATLASSERT(::IsWindow(m_hWnd));
\r
3485 ATLASSERT(hPage != NULL);
\r
3486 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSEL, 0, (LPARAM)hPage);
\r
3489 BOOL SetActivePageByID(int nPageID)
\r
3491 ATLASSERT(::IsWindow(m_hWnd));
\r
3492 return (BOOL)::SendMessage(m_hWnd, PSM_SETCURSELID, 0, nPageID);
\r
3495 void SetTitle(LPCTSTR lpszText, UINT nStyle = 0)
\r
3497 ATLASSERT(::IsWindow(m_hWnd));
\r
3498 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
\r
3499 ATLASSERT(lpszText != NULL);
\r
3500 ::SendMessage(m_hWnd, PSM_SETTITLE, nStyle, (LPARAM)lpszText);
\r
3503 HWND GetTabControl() const
\r
3505 ATLASSERT(::IsWindow(m_hWnd));
\r
3506 return (HWND)::SendMessage(m_hWnd, PSM_GETTABCONTROL, 0, 0L);
\r
3509 void SetFinishText(LPCTSTR lpszText)
\r
3511 ATLASSERT(::IsWindow(m_hWnd));
\r
3512 ::SendMessage(m_hWnd, PSM_SETFINISHTEXT, 0, (LPARAM)lpszText);
\r
3515 void SetWizardButtons(DWORD dwFlags)
\r
3517 ATLASSERT(::IsWindow(m_hWnd));
\r
3518 ::PostMessage(m_hWnd, PSM_SETWIZBUTTONS, 0, dwFlags);
\r
3522 BOOL AddPage(HPROPSHEETPAGE hPage)
\r
3524 ATLASSERT(::IsWindow(m_hWnd));
\r
3525 ATLASSERT(hPage != NULL);
\r
3526 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage);
\r
3529 BOOL AddPage(LPCPROPSHEETPAGE pPage)
\r
3531 ATLASSERT(::IsWindow(m_hWnd));
\r
3532 ATLASSERT(pPage != NULL);
\r
3533 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
\r
3536 return (BOOL)::SendMessage(m_hWnd, PSM_ADDPAGE, 0, (LPARAM)hPage);
\r
3539 #ifndef _WIN32_WCE
\r
3540 BOOL InsertPage(int nNewPageIndex, HPROPSHEETPAGE hPage)
\r
3542 ATLASSERT(::IsWindow(m_hWnd));
\r
3543 ATLASSERT(hPage != NULL);
\r
3544 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage);
\r
3547 BOOL InsertPage(int nNewPageIndex, LPCPROPSHEETPAGE pPage)
\r
3549 ATLASSERT(::IsWindow(m_hWnd));
\r
3550 ATLASSERT(pPage != NULL);
\r
3551 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
\r
3554 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, nNewPageIndex, (LPARAM)hPage);
\r
3557 BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, HPROPSHEETPAGE hPage)
\r
3559 ATLASSERT(::IsWindow(m_hWnd));
\r
3560 ATLASSERT(hPage != NULL);
\r
3561 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage);
\r
3564 BOOL InsertPage(HPROPSHEETPAGE hPageInsertAfter, LPCPROPSHEETPAGE pPage)
\r
3566 ATLASSERT(::IsWindow(m_hWnd));
\r
3567 ATLASSERT(pPage != NULL);
\r
3568 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
\r
3571 return (BOOL)::SendMessage(m_hWnd, PSM_INSERTPAGE, (WPARAM)hPageInsertAfter, (LPARAM)hPage);
\r
3573 #endif // !_WIN32_WCE
\r
3575 void RemovePage(int nPageIndex)
\r
3577 ATLASSERT(::IsWindow(m_hWnd));
\r
3578 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, nPageIndex, 0L);
\r
3581 void RemovePage(HPROPSHEETPAGE hPage)
\r
3583 ATLASSERT(::IsWindow(m_hWnd));
\r
3584 ATLASSERT(hPage != NULL);
\r
3585 ::SendMessage(m_hWnd, PSM_REMOVEPAGE, 0, (LPARAM)hPage);
\r
3588 BOOL PressButton(int nButton)
\r
3590 ATLASSERT(::IsWindow(m_hWnd));
\r
3591 return (BOOL)::SendMessage(m_hWnd, PSM_PRESSBUTTON, nButton, 0L);
\r
3596 ATLASSERT(::IsWindow(m_hWnd));
\r
3597 return (BOOL)::SendMessage(m_hWnd, PSM_APPLY, 0, 0L);
\r
3600 void CancelToClose()
\r
3602 ATLASSERT(::IsWindow(m_hWnd));
\r
3603 ::SendMessage(m_hWnd, PSM_CANCELTOCLOSE, 0, 0L);
\r
3606 void SetModified(HWND hWndPage, BOOL bChanged = TRUE)
\r
3608 ATLASSERT(::IsWindow(m_hWnd));
\r
3609 ATLASSERT(::IsWindow(hWndPage));
\r
3610 UINT uMsg = bChanged ? PSM_CHANGED : PSM_UNCHANGED;
\r
3611 ::SendMessage(m_hWnd, uMsg, (WPARAM)hWndPage, 0L);
\r
3614 LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
\r
3616 ATLASSERT(::IsWindow(m_hWnd));
\r
3617 return ::SendMessage(m_hWnd, PSM_QUERYSIBLINGS, wParam, lParam);
\r
3620 void RebootSystem()
\r
3622 ATLASSERT(::IsWindow(m_hWnd));
\r
3623 ::SendMessage(m_hWnd, PSM_REBOOTSYSTEM, 0, 0L);
\r
3626 void RestartWindows()
\r
3628 ATLASSERT(::IsWindow(m_hWnd));
\r
3629 ::SendMessage(m_hWnd, PSM_RESTARTWINDOWS, 0, 0L);
\r
3632 BOOL IsDialogMessage(LPMSG lpMsg)
\r
3634 ATLASSERT(::IsWindow(m_hWnd));
\r
3635 return (BOOL)::SendMessage(m_hWnd, PSM_ISDIALOGMESSAGE, 0, (LPARAM)lpMsg);
\r
3638 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
3639 int HwndToIndex(HWND hWnd) const
\r
3641 ATLASSERT(::IsWindow(m_hWnd));
\r
3642 return (int)::SendMessage(m_hWnd, PSM_HWNDTOINDEX, (WPARAM)hWnd, 0L);
\r
3645 HWND IndexToHwnd(int nIndex) const
\r
3647 ATLASSERT(::IsWindow(m_hWnd));
\r
3648 return (HWND)::SendMessage(m_hWnd, PSM_INDEXTOHWND, nIndex, 0L);
\r
3651 int PageToIndex(HPROPSHEETPAGE hPage) const
\r
3653 ATLASSERT(::IsWindow(m_hWnd));
\r
3654 return (int)::SendMessage(m_hWnd, PSM_PAGETOINDEX, 0, (LPARAM)hPage);
\r
3657 HPROPSHEETPAGE IndexToPage(int nIndex) const
\r
3659 ATLASSERT(::IsWindow(m_hWnd));
\r
3660 return (HPROPSHEETPAGE)::SendMessage(m_hWnd, PSM_INDEXTOPAGE, nIndex, 0L);
\r
3663 int IdToIndex(int nID) const
\r
3665 ATLASSERT(::IsWindow(m_hWnd));
\r
3666 return (int)::SendMessage(m_hWnd, PSM_IDTOINDEX, 0, nID);
\r
3669 int IndexToId(int nIndex) const
\r
3671 ATLASSERT(::IsWindow(m_hWnd));
\r
3672 return (int)::SendMessage(m_hWnd, PSM_INDEXTOID, nIndex, 0L);
\r
3675 int GetResult() const
\r
3677 ATLASSERT(::IsWindow(m_hWnd));
\r
3678 return (int)::SendMessage(m_hWnd, PSM_GETRESULT, 0, 0L);
\r
3681 BOOL RecalcPageSizes()
\r
3683 ATLASSERT(::IsWindow(m_hWnd));
\r
3684 return (BOOL)::SendMessage(m_hWnd, PSM_RECALCPAGESIZES, 0, 0L);
\r
3687 void SetHeaderTitle(int nIndex, LPCTSTR lpstrHeaderTitle)
\r
3689 ATLASSERT(::IsWindow(m_hWnd));
\r
3690 ::SendMessage(m_hWnd, PSM_SETHEADERTITLE, nIndex, (LPARAM)lpstrHeaderTitle);
\r
3693 void SetHeaderSubTitle(int nIndex, LPCTSTR lpstrHeaderSubTitle)
\r
3695 ATLASSERT(::IsWindow(m_hWnd));
\r
3696 ::SendMessage(m_hWnd, PSM_SETHEADERSUBTITLE, nIndex, (LPARAM)lpstrHeaderSubTitle);
\r
3698 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
3700 // Implementation - override to prevent usage
\r
3701 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
\r
3708 ///////////////////////////////////////////////////////////////////////////////
\r
3709 // CPropertySheetImpl - implements a property sheet
\r
3711 template <class T, class TBase = CPropertySheetWindow>
\r
3712 class ATL_NO_VTABLE CPropertySheetImpl : public ATL::CWindowImplBaseT< TBase >
\r
3715 PROPSHEETHEADER m_psh;
\r
3716 ATL::CSimpleArray<HPROPSHEETPAGE> m_arrPages;
\r
3718 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
\r
3719 #ifndef PROPSHEET_LINK_SIZE
\r
3720 #define PROPSHEET_LINK_SIZE 128
\r
3721 #endif // PROPSHEET_LINK_SIZE
\r
3722 TCHAR m_szLink[PROPSHEET_LINK_SIZE];
\r
3723 static LPCTSTR m_pszTitle;
\r
3724 static LPCTSTR m_pszLink;
\r
3725 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
\r
3727 // Construction/Destruction
\r
3728 CPropertySheetImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
\r
3730 memset(&m_psh, 0, sizeof(PROPSHEETHEADER));
\r
3731 m_psh.dwSize = sizeof(PROPSHEETHEADER);
\r
3732 m_psh.dwFlags = PSH_USECALLBACK;
\r
3733 m_psh.hInstance = ModuleHelper::GetResourceInstance();
\r
3734 m_psh.phpage = NULL; // will be set later
\r
3735 m_psh.nPages = 0; // will be set later
\r
3736 m_psh.pszCaption = title.m_lpstr;
\r
3737 m_psh.nStartPage = uStartPage;
\r
3738 m_psh.hwndParent = hWndParent; // if NULL, will be set in DoModal/Create
\r
3739 m_psh.pfnCallback = T::PropSheetCallback;
\r
3741 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
\r
3742 m_psh.dwFlags |= PSH_MAXIMIZE;
\r
3744 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
\r
3747 ~CPropertySheetImpl()
\r
3749 if(m_arrPages.GetSize() > 0) // sheet never created, destroy all pages
\r
3751 for(int i = 0; i < m_arrPages.GetSize(); i++)
\r
3752 ::DestroyPropertySheetPage((HPROPSHEETPAGE)m_arrPages[i]);
\r
3756 // Callback function and overrideables
\r
3757 static int CALLBACK PropSheetCallback(HWND hWnd, UINT uMsg, LPARAM lParam)
\r
3759 lParam; // avoid level 4 warning
\r
3762 if(uMsg == PSCB_INITIALIZED)
\r
3764 ATLASSERT(hWnd != NULL);
\r
3765 T* pT = (T*)ModuleHelper::ExtractCreateWndData();
\r
3766 // subclass the sheet window
\r
3767 pT->SubclassWindow(hWnd);
\r
3768 // remove page handles array
\r
3769 pT->_CleanUpPages();
\r
3771 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
\r
3772 m_pszTitle = pT->m_psh.pszCaption;
\r
3773 if(*pT->m_szLink != 0)
\r
3774 m_pszLink = pT->m_szLink;
\r
3775 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
\r
3777 pT->OnSheetInitialized();
\r
3779 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg
\r
3784 case PSCB_GETVERSION :
\r
3785 nRet = COMCTL32_VERSION;
\r
3787 case PSCB_GETTITLE :
\r
3788 if(m_pszTitle != NULL)
\r
3790 lstrcpy((LPTSTR)lParam, m_pszTitle);
\r
3791 m_pszTitle = NULL;
\r
3794 case PSCB_GETLINKTEXT:
\r
3795 if(m_pszLink != NULL)
\r
3797 lstrcpy((LPTSTR)lParam, m_pszLink);
\r
3805 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
\r
3810 void OnSheetInitialized()
\r
3815 HWND Create(HWND hWndParent = NULL)
\r
3817 ATLASSERT(m_hWnd == NULL);
\r
3819 m_psh.dwFlags |= PSH_MODELESS;
\r
3820 if(m_psh.hwndParent == NULL)
\r
3821 m_psh.hwndParent = hWndParent;
\r
3822 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData();
\r
3823 m_psh.nPages = m_arrPages.GetSize();
\r
3825 T* pT = static_cast<T*>(this);
\r
3826 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT);
\r
3828 HWND hWnd = (HWND)::PropertySheet(&m_psh);
\r
3829 _CleanUpPages(); // ensure clean-up, required if call failed
\r
3831 ATLASSERT(m_hWnd == hWnd);
\r
3836 INT_PTR DoModal(HWND hWndParent = ::GetActiveWindow())
\r
3838 ATLASSERT(m_hWnd == NULL);
\r
3840 m_psh.dwFlags &= ~PSH_MODELESS;
\r
3841 if(m_psh.hwndParent == NULL)
\r
3842 m_psh.hwndParent = hWndParent;
\r
3843 m_psh.phpage = (HPROPSHEETPAGE*)m_arrPages.GetData();
\r
3844 m_psh.nPages = m_arrPages.GetSize();
\r
3846 T* pT = static_cast<T*>(this);
\r
3847 ModuleHelper::AddCreateWndData(&pT->m_thunk.cd, pT);
\r
3849 INT_PTR nRet = ::PropertySheet(&m_psh);
\r
3850 _CleanUpPages(); // ensure clean-up, required if call failed
\r
3855 // implementation helper - clean up pages array
\r
3856 void _CleanUpPages()
\r
3859 m_psh.phpage = NULL;
\r
3860 m_arrPages.RemoveAll();
\r
3863 // Attributes (extended overrides of client class methods)
\r
3864 // These now can be called before the sheet is created
\r
3865 // Note: Calling these after the sheet is created gives unpredictable results
\r
3866 int GetPageCount() const
\r
3868 if(m_hWnd == NULL) // not created yet
\r
3869 return m_arrPages.GetSize();
\r
3870 return TBase::GetPageCount();
\r
3873 int GetActiveIndex() const
\r
3875 if(m_hWnd == NULL) // not created yet
\r
3876 return m_psh.nStartPage;
\r
3877 return TBase::GetActiveIndex();
\r
3880 HPROPSHEETPAGE GetPage(int nPageIndex) const
\r
3882 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
3883 return (HPROPSHEETPAGE)m_arrPages[nPageIndex];
\r
3886 int GetPageIndex(HPROPSHEETPAGE hPage) const
\r
3888 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
3889 return m_arrPages.Find((HPROPSHEETPAGE&)hPage);
\r
3892 BOOL SetActivePage(int nPageIndex)
\r
3894 if(m_hWnd == NULL) // not created yet
\r
3896 ATLASSERT(nPageIndex >= 0 && nPageIndex < m_arrPages.GetSize());
\r
3897 m_psh.nStartPage = nPageIndex;
\r
3900 return TBase::SetActivePage(nPageIndex);
\r
3903 BOOL SetActivePage(HPROPSHEETPAGE hPage)
\r
3905 ATLASSERT(hPage != NULL);
\r
3906 if (m_hWnd == NULL) // not created yet
\r
3908 int nPageIndex = GetPageIndex(hPage);
\r
3909 if(nPageIndex == -1)
\r
3912 return SetActivePage(nPageIndex);
\r
3914 return TBase::SetActivePage(hPage);
\r
3918 void SetTitle(LPCTSTR lpszText, UINT nStyle = 0)
\r
3920 ATLASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
\r
3921 ATLASSERT(lpszText != NULL);
\r
3923 if(m_hWnd == NULL)
\r
3925 // set internal state
\r
3926 m_psh.pszCaption = lpszText; // must exist until sheet is created
\r
3927 m_psh.dwFlags &= ~PSH_PROPTITLE;
\r
3928 m_psh.dwFlags |= nStyle;
\r
3932 // set external state
\r
3933 TBase::SetTitle(lpszText, nStyle);
\r
3937 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field
\r
3938 void SetLinkText(LPCTSTR lpszText)
\r
3940 ATLASSERT(lpszText != NULL);
\r
3941 ATLASSERT(lstrlen(lpszText) < PROPSHEET_LINK_SIZE);
\r
3942 lstrcpy(m_szLink, lpszText);
\r
3944 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
\r
3946 void SetWizardMode()
\r
3948 m_psh.dwFlags |= PSH_WIZARD;
\r
3953 m_psh.dwFlags |= PSH_HASHELP;
\r
3957 BOOL AddPage(HPROPSHEETPAGE hPage)
\r
3959 ATLASSERT(hPage != NULL);
\r
3960 BOOL bRet = FALSE;
\r
3961 if(m_hWnd != NULL)
\r
3962 bRet = TBase::AddPage(hPage);
\r
3963 else // sheet not created yet, use internal data
\r
3964 bRet = m_arrPages.Add((HPROPSHEETPAGE&)hPage);
\r
3968 BOOL AddPage(LPCPROPSHEETPAGE pPage)
\r
3970 ATLASSERT(pPage != NULL);
\r
3971 HPROPSHEETPAGE hPage = ::CreatePropertySheetPage(pPage);
\r
3974 BOOL bRet = AddPage(hPage);
\r
3976 ::DestroyPropertySheetPage(hPage);
\r
3980 BOOL RemovePage(HPROPSHEETPAGE hPage)
\r
3982 ATLASSERT(hPage != NULL);
\r
3983 if (m_hWnd == NULL) // not created yet
\r
3985 int nPage = GetPageIndex(hPage);
\r
3988 return RemovePage(nPage);
\r
3990 TBase::RemovePage(hPage);
\r
3995 BOOL RemovePage(int nPageIndex)
\r
3998 if(m_hWnd != NULL)
\r
3999 TBase::RemovePage(nPageIndex);
\r
4000 else // sheet not created yet, use internal data
\r
4001 bRet = m_arrPages.RemoveAt(nPageIndex);
\r
4005 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
\r
4006 void SetHeader(LPCTSTR szbmHeader)
\r
4008 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4010 m_psh.dwFlags &= ~PSH_WIZARD;
\r
4011 m_psh.dwFlags |= (PSH_HEADER | PSH_WIZARD97);
\r
4012 m_psh.pszbmHeader = szbmHeader;
\r
4015 void SetHeader(HBITMAP hbmHeader)
\r
4017 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4019 m_psh.dwFlags &= ~PSH_WIZARD;
\r
4020 m_psh.dwFlags |= (PSH_HEADER | PSH_USEHBMHEADER | PSH_WIZARD97);
\r
4021 m_psh.hbmHeader = hbmHeader;
\r
4024 void SetWatermark(LPCTSTR szbmWatermark, HPALETTE hplWatermark = NULL)
\r
4026 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4028 m_psh.dwFlags &= ~PSH_WIZARD;
\r
4029 m_psh.dwFlags |= PSH_WATERMARK | PSH_WIZARD97;
\r
4030 m_psh.pszbmWatermark = szbmWatermark;
\r
4032 if (hplWatermark != NULL)
\r
4034 m_psh.dwFlags |= PSH_USEHPLWATERMARK;
\r
4035 m_psh.hplWatermark = hplWatermark;
\r
4039 void SetWatermark(HBITMAP hbmWatermark, HPALETTE hplWatermark = NULL)
\r
4041 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4043 m_psh.dwFlags &= ~PSH_WIZARD;
\r
4044 m_psh.dwFlags |= (PSH_WATERMARK | PSH_USEHBMWATERMARK | PSH_WIZARD97);
\r
4045 m_psh.hbmWatermark = hbmWatermark;
\r
4047 if (hplWatermark != NULL)
\r
4049 m_psh.dwFlags |= PSH_USEHPLWATERMARK;
\r
4050 m_psh.hplWatermark = hplWatermark;
\r
4054 void StretchWatermark(bool bStretchWatermark)
\r
4056 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4057 if (bStretchWatermark)
\r
4058 m_psh.dwFlags |= PSH_STRETCHWATERMARK;
\r
4060 m_psh.dwFlags &= ~PSH_STRETCHWATERMARK;
\r
4062 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
\r
4064 // Message map and handlers
\r
4065 BEGIN_MSG_MAP(CPropertySheetImpl)
\r
4066 MESSAGE_HANDLER(WM_COMMAND, OnCommand)
\r
4067 MESSAGE_HANDLER(WM_SYSCOMMAND, OnSysCommand)
\r
4070 LRESULT OnCommand(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& /*bHandled*/)
\r
4072 LRESULT lRet = DefWindowProc(uMsg, wParam, lParam);
\r
4073 if(HIWORD(wParam) == BN_CLICKED && (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) &&
\r
4074 ((m_psh.dwFlags & PSH_MODELESS) != 0) && (GetActivePage() == NULL))
\r
4079 LRESULT OnSysCommand(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
\r
4081 if(((m_psh.dwFlags & PSH_MODELESS) == PSH_MODELESS) && ((wParam & 0xFFF0) == SC_CLOSE))
\r
4082 SendMessage(WM_CLOSE);
\r
4089 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers
\r
4090 template < class T, class TBase >
\r
4091 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszTitle = NULL;
\r
4092 template < class T, class TBase>
\r
4093 LPCWSTR CPropertySheetImpl<T,TBase>::m_pszLink = NULL;
\r
4094 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
\r
4096 // for non-customized sheets
\r
4097 class CPropertySheet : public CPropertySheetImpl<CPropertySheet>
\r
4100 CPropertySheet(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
\r
4101 : CPropertySheetImpl<CPropertySheet>(title, uStartPage, hWndParent)
\r
4106 ///////////////////////////////////////////////////////////////////////////////
\r
4107 // CPropertyPageWindow - client side for a property page
\r
4109 class CPropertyPageWindow : public ATL::CWindow
\r
4113 CPropertyPageWindow(HWND hWnd = NULL) : ATL::CWindow(hWnd)
\r
4116 CPropertyPageWindow& operator =(HWND hWnd)
\r
4123 CPropertySheetWindow GetPropertySheet() const
\r
4125 ATLASSERT(::IsWindow(m_hWnd));
\r
4126 return CPropertySheetWindow(GetParent());
\r
4132 ATLASSERT(::IsWindow(m_hWnd));
\r
4133 ATLASSERT(GetParent() != NULL);
\r
4134 return GetPropertySheet().Apply();
\r
4137 void CancelToClose()
\r
4139 ATLASSERT(::IsWindow(m_hWnd));
\r
4140 ATLASSERT(GetParent() != NULL);
\r
4141 GetPropertySheet().CancelToClose();
\r
4144 void SetModified(BOOL bChanged = TRUE)
\r
4146 ATLASSERT(::IsWindow(m_hWnd));
\r
4147 ATLASSERT(GetParent() != NULL);
\r
4148 GetPropertySheet().SetModified(m_hWnd, bChanged);
\r
4151 LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam)
\r
4153 ATLASSERT(::IsWindow(m_hWnd));
\r
4154 ATLASSERT(GetParent() != NULL);
\r
4155 return GetPropertySheet().QuerySiblings(wParam, lParam);
\r
4158 void RebootSystem()
\r
4160 ATLASSERT(::IsWindow(m_hWnd));
\r
4161 ATLASSERT(GetParent() != NULL);
\r
4162 GetPropertySheet().RebootSystem();
\r
4165 void RestartWindows()
\r
4167 ATLASSERT(::IsWindow(m_hWnd));
\r
4168 ATLASSERT(GetParent() != NULL);
\r
4169 GetPropertySheet().RestartWindows();
\r
4172 void SetWizardButtons(DWORD dwFlags)
\r
4174 ATLASSERT(::IsWindow(m_hWnd));
\r
4175 ATLASSERT(GetParent() != NULL);
\r
4176 GetPropertySheet().SetWizardButtons(dwFlags);
\r
4179 // Implementation - overrides to prevent usage
\r
4180 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
\r
4187 ///////////////////////////////////////////////////////////////////////////////
\r
4188 // CPropertyPageImpl - implements a property page
\r
4190 template <class T, class TBase = CPropertyPageWindow>
\r
4191 class ATL_NO_VTABLE CPropertyPageImpl : public ATL::CDialogImplBaseT< TBase >
\r
4194 PROPSHEETPAGE m_psp;
\r
4196 operator PROPSHEETPAGE*() { return &m_psp; }
\r
4199 CPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL)
\r
4201 // initialize PROPSHEETPAGE struct
\r
4202 memset(&m_psp, 0, sizeof(PROPSHEETPAGE));
\r
4203 m_psp.dwSize = sizeof(PROPSHEETPAGE);
\r
4204 m_psp.dwFlags = PSP_USECALLBACK;
\r
4205 m_psp.hInstance = ModuleHelper::GetResourceInstance();
\r
4206 T* pT = static_cast<T*>(this);
\r
4207 m_psp.pszTemplate = MAKEINTRESOURCE(pT->IDD);
\r
4208 m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc;
\r
4209 m_psp.pfnCallback = T::PropPageCallback;
\r
4210 m_psp.lParam = (LPARAM)pT;
\r
4212 if(title.m_lpstr != NULL)
\r
4216 // Callback function and overrideables
\r
4217 static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
\r
4219 hWnd; // avoid level 4 warning
\r
4220 ATLASSERT(hWnd == NULL);
\r
4221 T* pT = (T*)ppsp->lParam;
\r
4226 case PSPCB_CREATE:
\r
4228 ATL::CDialogImplBaseT< TBase >* pPage = (ATL::CDialogImplBaseT< TBase >*)pT;
\r
4229 ModuleHelper::AddCreateWndData(&pPage->m_thunk.cd, pPage);
\r
4230 uRet = pT->OnPageCreate() ? 1 : 0;
\r
4233 #if (_WIN32_IE >= 0x0500)
\r
4234 case PSPCB_ADDREF:
\r
4235 pT->OnPageAddRef();
\r
4237 #endif // (_WIN32_IE >= 0x0500)
\r
4238 case PSPCB_RELEASE:
\r
4239 pT->OnPageRelease();
\r
4248 bool OnPageCreate()
\r
4250 return true; // true - allow page to be created, false - prevent creation
\r
4253 #if (_WIN32_IE >= 0x0500)
\r
4254 void OnPageAddRef()
\r
4257 #endif // (_WIN32_IE >= 0x0500)
\r
4259 void OnPageRelease()
\r
4264 HPROPSHEETPAGE Create()
\r
4266 return ::CreatePropertySheetPage(&m_psp);
\r
4270 void SetTitle(ATL::_U_STRINGorID title)
\r
4272 m_psp.pszTitle = title.m_lpstr;
\r
4273 m_psp.dwFlags |= PSP_USETITLE;
\r
4276 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
4277 void SetHeaderTitle(LPCTSTR lpstrHeaderTitle)
\r
4279 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4280 m_psp.dwFlags |= PSP_USEHEADERTITLE;
\r
4281 m_psp.pszHeaderTitle = lpstrHeaderTitle;
\r
4284 void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle)
\r
4286 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
4287 m_psp.dwFlags |= PSP_USEHEADERSUBTITLE;
\r
4288 m_psp.pszHeaderSubTitle = lpstrHeaderSubTitle;
\r
4290 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
4295 m_psp.dwFlags |= PSP_HASHELP;
\r
4298 // Message map and handlers
\r
4299 BEGIN_MSG_MAP(CPropertyPageImpl)
\r
4300 MESSAGE_HANDLER(WM_NOTIFY, OnNotify)
\r
4303 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
\r
4304 // handlers that return direct values without any restrictions
\r
4305 LRESULT OnNotify(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM lParam, BOOL& bHandled)
\r
4307 #ifndef _WIN32_WCE
\r
4308 // This notification is sometimes received on Windows CE after the window is already destroyed
\r
4309 ATLASSERT(::IsWindow(m_hWnd));
\r
4311 NMHDR* pNMHDR = (NMHDR*)lParam;
\r
4313 // don't handle messages not from the page/sheet itself
\r
4314 if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd))
\r
4320 ATLASSERT(::IsWindow(m_hWnd));
\r
4323 T* pT = static_cast<T*>(this);
\r
4324 LRESULT lResult = 0;
\r
4325 switch(pNMHDR->code)
\r
4327 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4328 case PSN_SETACTIVE:
\r
4329 lResult = pT->OnSetActive();
\r
4331 case PSN_KILLACTIVE:
\r
4332 lResult = pT->OnKillActive();
\r
4335 lResult = pT->OnApply();
\r
4340 case PSN_QUERYCANCEL:
\r
4341 lResult = pT->OnQueryCancel();
\r
4344 lResult = pT->OnWizardNext();
\r
4347 lResult = pT->OnWizardBack();
\r
4349 case PSN_WIZFINISH:
\r
4350 lResult = pT->OnWizardFinish();
\r
4355 #ifndef _WIN32_WCE
\r
4356 #if (_WIN32_IE >= 0x0400)
\r
4357 case PSN_GETOBJECT:
\r
4358 if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam))
\r
4361 #endif // (_WIN32_IE >= 0x0400)
\r
4362 #if (_WIN32_IE >= 0x0500)
\r
4363 case PSN_TRANSLATEACCELERATOR:
\r
4365 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
\r
4366 lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam);
\r
4369 case PSN_QUERYINITIALFOCUS:
\r
4371 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
\r
4372 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam);
\r
4375 #endif // (_WIN32_IE >= 0x0500)
\r
4376 #endif // !_WIN32_WCE
\r
4378 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4379 case PSN_SETACTIVE:
\r
4380 lResult = pT->OnSetActive() ? 0 : -1;
\r
4382 case PSN_KILLACTIVE:
\r
4383 lResult = !pT->OnKillActive();
\r
4386 lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE;
\r
4391 case PSN_QUERYCANCEL:
\r
4392 lResult = !pT->OnQueryCancel();
\r
4395 lResult = pT->OnWizardNext();
\r
4398 lResult = pT->OnWizardBack();
\r
4400 case PSN_WIZFINISH:
\r
4401 lResult = !pT->OnWizardFinish();
\r
4406 #ifndef _WIN32_WCE
\r
4407 #if (_WIN32_IE >= 0x0400)
\r
4408 case PSN_GETOBJECT:
\r
4409 if(!pT->OnGetObject((LPNMOBJECTNOTIFY)lParam))
\r
4412 #endif // (_WIN32_IE >= 0x0400)
\r
4413 #if (_WIN32_IE >= 0x0500)
\r
4414 case PSN_TRANSLATEACCELERATOR:
\r
4416 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
\r
4417 lResult = pT->OnTranslateAccelerator((LPMSG)lpPSHNotify->lParam) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR;
\r
4420 case PSN_QUERYINITIALFOCUS:
\r
4422 LPPSHNOTIFY lpPSHNotify = (LPPSHNOTIFY)lParam;
\r
4423 lResult = (LRESULT)pT->OnQueryInitialFocus((HWND)lpPSHNotify->lParam);
\r
4426 #endif // (_WIN32_IE >= 0x0500)
\r
4427 #endif // !_WIN32_WCE
\r
4429 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4431 bHandled = FALSE; // not handled
\r
4438 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
\r
4439 // handlers that return direct values without any restrictions
\r
4440 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4443 // 0 = allow activate
\r
4444 // -1 = go back that was active
\r
4445 // page ID = jump to page
\r
4449 BOOL OnKillActive()
\r
4451 // FALSE = allow deactivate
\r
4452 // TRUE = prevent deactivation
\r
4458 // PSNRET_NOERROR = apply OK
\r
4459 // PSNRET_INVALID = apply not OK, return to this page
\r
4460 // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focus
\r
4461 return PSNRET_NOERROR;
\r
4468 BOOL OnQueryCancel()
\r
4470 // FALSE = allow cancel
\r
4471 // TRUE = prevent cancel
\r
4475 int OnWizardBack()
\r
4477 // 0 = goto previous page
\r
4478 // -1 = prevent page change
\r
4479 // >0 = jump to page by dlg ID
\r
4483 int OnWizardNext()
\r
4485 // 0 = goto next page
\r
4486 // -1 = prevent page change
\r
4487 // >0 = jump to page by dlg ID
\r
4491 INT_PTR OnWizardFinish()
\r
4493 // FALSE = allow finish
\r
4494 // TRUE = prevent finish
\r
4495 // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 only)
\r
4503 #ifndef _WIN32_WCE
\r
4504 #if (_WIN32_IE >= 0x0400)
\r
4505 BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/)
\r
4507 return FALSE; // not processed
\r
4509 #endif // (_WIN32_IE >= 0x0400)
\r
4511 #if (_WIN32_IE >= 0x0500)
\r
4512 int OnTranslateAccelerator(LPMSG /*lpMsg*/)
\r
4514 // PSNRET_NOERROR - message not handled
\r
4515 // PSNRET_MESSAGEHANDLED - message handled
\r
4516 return PSNRET_NOERROR;
\r
4519 HWND OnQueryInitialFocus(HWND /*hWndFocus*/)
\r
4521 // NULL = set focus to default control
\r
4522 // HWND = set focus to HWND
\r
4525 #endif // (_WIN32_IE >= 0x0500)
\r
4526 #endif // !_WIN32_WCE
\r
4528 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4529 BOOL OnSetActive()
\r
4534 BOOL OnKillActive()
\r
4548 BOOL OnQueryCancel()
\r
4550 return TRUE; // ok to cancel
\r
4553 int OnWizardBack()
\r
4555 // 0 = goto previous page
\r
4556 // -1 = prevent page change
\r
4557 // >0 = jump to page by dlg ID
\r
4561 int OnWizardNext()
\r
4563 // 0 = goto next page
\r
4564 // -1 = prevent page change
\r
4565 // >0 = jump to page by dlg ID
\r
4569 BOOL OnWizardFinish()
\r
4578 #ifndef _WIN32_WCE
\r
4579 #if (_WIN32_IE >= 0x0400)
\r
4580 BOOL OnGetObject(LPNMOBJECTNOTIFY /*lpObjectNotify*/)
\r
4582 return FALSE; // not processed
\r
4584 #endif // (_WIN32_IE >= 0x0400)
\r
4586 #if (_WIN32_IE >= 0x0500)
\r
4587 BOOL OnTranslateAccelerator(LPMSG /*lpMsg*/)
\r
4589 return FALSE; // not translated
\r
4592 HWND OnQueryInitialFocus(HWND /*hWndFocus*/)
\r
4594 return NULL; // default
\r
4596 #endif // (_WIN32_IE >= 0x0500)
\r
4597 #endif // !_WIN32_WCE
\r
4599 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4602 // for non-customized pages
\r
4603 template <WORD t_wDlgTemplateID>
\r
4604 class CPropertyPage : public CPropertyPageImpl<CPropertyPage<t_wDlgTemplateID> >
\r
4607 enum { IDD = t_wDlgTemplateID };
\r
4609 CPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl<CPropertyPage>(title)
\r
4612 DECLARE_EMPTY_MSG_MAP()
\r
4615 ///////////////////////////////////////////////////////////////////////////////
\r
4616 // CAxPropertyPageImpl - property page that hosts ActiveX controls
\r
4618 #ifndef _ATL_NO_HOSTING
\r
4620 // Note: You must #include <atlhost.h> to use these classes
\r
4622 template <class T, class TBase = CPropertyPageWindow>
\r
4623 class ATL_NO_VTABLE CAxPropertyPageImpl : public CPropertyPageImpl< T, TBase >
\r
4627 HGLOBAL m_hInitData;
\r
4628 HGLOBAL m_hDlgRes;
\r
4629 HGLOBAL m_hDlgResSplit;
\r
4631 // Constructor/destructor
\r
4632 CAxPropertyPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) :
\r
4633 CPropertyPageImpl< T, TBase >(title),
\r
4634 m_hInitData(NULL), m_hDlgRes(NULL), m_hDlgResSplit(NULL)
\r
4636 T* pT = static_cast<T*>(this);
\r
4637 pT; // avoid level 4 warning
\r
4639 // initialize ActiveX hosting and modify dialog template
\r
4640 ATL::AtlAxWinInit();
\r
4642 HINSTANCE hInstance = ModuleHelper::GetResourceInstance();
\r
4643 LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD);
\r
4644 HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG);
\r
4647 HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT);
\r
4649 BYTE* pInitData = NULL;
\r
4650 if(hDlgInit != NULL)
\r
4652 m_hInitData = ::LoadResource(hInstance, hDlgInit);
\r
4653 pInitData = (BYTE*)::LockResource(m_hInitData);
\r
4656 m_hDlgRes = ::LoadResource(hInstance, hDlg);
\r
4657 DLGTEMPLATE* pDlg = (DLGTEMPLATE*)::LockResource(m_hDlgRes);
\r
4658 LPCDLGTEMPLATE lpDialogTemplate = ATL::_DialogSplitHelper::SplitDialogTemplate(pDlg, pInitData);
\r
4659 if(lpDialogTemplate != pDlg)
\r
4660 m_hDlgResSplit = GlobalHandle(lpDialogTemplate);
\r
4662 // set up property page to use in-memory dialog template
\r
4663 if(lpDialogTemplate != NULL)
\r
4665 m_psp.dwFlags |= PSP_DLGINDIRECT;
\r
4666 m_psp.pResource = lpDialogTemplate;
\r
4670 ATLASSERT(FALSE && _T("CAxPropertyPageImpl - ActiveX initializtion failed!"));
\r
4675 ATLASSERT(FALSE && _T("CAxPropertyPageImpl - Cannot find dialog template!"));
\r
4679 ~CAxPropertyPageImpl()
\r
4681 if(m_hInitData != NULL)
\r
4683 UnlockResource(m_hInitData);
\r
4684 FreeResource(m_hInitData);
\r
4686 if(m_hDlgRes != NULL)
\r
4688 UnlockResource(m_hDlgRes);
\r
4689 FreeResource(m_hDlgRes);
\r
4691 if(m_hDlgResSplit != NULL)
\r
4693 ::GlobalFree(m_hDlgResSplit);
\r
4698 // call this one to handle keyboard message for ActiveX controls
\r
4699 BOOL PreTranslateMessage(LPMSG pMsg)
\r
4701 if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) &&
\r
4702 (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST))
\r
4704 // find a direct child of the dialog from the window that has focus
\r
4705 HWND hWndCtl = ::GetFocus();
\r
4706 if (IsChild(hWndCtl) && ::GetParent(hWndCtl) != m_hWnd)
\r
4710 hWndCtl = ::GetParent(hWndCtl);
\r
4712 while (::GetParent(hWndCtl) != m_hWnd);
\r
4714 // give controls a chance to translate this message
\r
4715 return (BOOL)::SendMessage(hWndCtl, WM_FORWARDMSG, 0, (LPARAM)pMsg);
\r
4719 #if (_WIN32_IE >= 0x0500)
\r
4720 // new default implementation for ActiveX hosting pages
\r
4721 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4722 int OnTranslateAccelerator(LPMSG lpMsg)
\r
4724 T* pT = static_cast<T*>(this);
\r
4725 return (pT->PreTranslateMessage(lpMsg) != FALSE) ? PSNRET_MESSAGEHANDLED : PSNRET_NOERROR;
\r
4727 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4728 BOOL OnTranslateAccelerator(LPMSG lpMsg)
\r
4730 T* pT = static_cast<T*>(this);
\r
4731 return pT->PreTranslateMessage(lpMsg);
\r
4733 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
\r
4734 #endif // (_WIN32_IE >= 0x0500)
\r
4736 // Support for new stuff in ATL7
\r
4737 #if (_ATL_VER >= 0x0700)
\r
4740 return( static_cast<T*>(this)->IDD );
\r
4743 virtual DLGPROC GetDialogProc()
\r
4745 return DialogProc;
\r
4748 static INT_PTR CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
\r
4750 CAxPropertyPageImpl< T, TBase >* pThis = (CAxPropertyPageImpl< T, TBase >*)hWnd;
\r
4751 if (uMsg == WM_INITDIALOG)
\r
4754 if (FAILED(hr = pThis->CreateActiveXControls(pThis->GetIDD())))
\r
4760 return CPropertyPageImpl< T, TBase >::DialogProc(hWnd, uMsg, wParam, lParam);
\r
4763 // ActiveX controls creation
\r
4764 virtual HRESULT CreateActiveXControls(UINT nID)
\r
4766 // Load dialog template and InitData
\r
4767 HRSRC hDlgInit = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)_ATL_RT_DLGINIT);
\r
4768 BYTE* pInitData = NULL;
\r
4769 HGLOBAL hData = NULL;
\r
4770 HRESULT hr = S_OK;
\r
4771 if (hDlgInit != NULL)
\r
4773 hData = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlgInit);
\r
4774 if (hData != NULL)
\r
4775 pInitData = (BYTE*) ::LockResource(hData);
\r
4778 HRSRC hDlg = ::FindResource(ATL::_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCE(nID), (LPTSTR)RT_DIALOG);
\r
4781 HGLOBAL hResource = ::LoadResource(ATL::_AtlBaseModule.GetResourceInstance(), hDlg);
\r
4782 DLGTEMPLATE* pDlg = NULL;
\r
4783 if (hResource != NULL)
\r
4785 pDlg = (DLGTEMPLATE*) ::LockResource(hResource);
\r
4788 // Get first control on the template
\r
4789 BOOL bDialogEx = ATL::_DialogSplitHelper::IsDialogEx(pDlg);
\r
4790 WORD nItems = ATL::_DialogSplitHelper::DlgTemplateItemCount(pDlg);
\r
4792 // Get first control on the dialog
\r
4793 DLGITEMTEMPLATE* pItem = ATL::_DialogSplitHelper::FindFirstDlgItem(pDlg);
\r
4794 HWND hWndPrev = GetWindow(GW_CHILD);
\r
4796 // Create all ActiveX cotnrols in the dialog template and place them in the correct tab order (z-order)
\r
4797 for (WORD nItem = 0; nItem < nItems; nItem++)
\r
4799 DWORD wID = bDialogEx ? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id : pItem->id;
\r
4800 if (ATL::_DialogSplitHelper::IsActiveXControl(pItem, bDialogEx))
\r
4802 BYTE* pData = NULL;
\r
4803 DWORD dwLen = ATL::_DialogSplitHelper::FindCreateData(wID, pInitData, &pData);
\r
4804 ATL::CComPtr<IStream> spStream;
\r
4807 HGLOBAL h = GlobalAlloc(GHND, dwLen);
\r
4810 BYTE* pBytes = (BYTE*) GlobalLock(h);
\r
4811 BYTE* pSource = pData;
\r
4812 SecureHelper::memcpy_x(pBytes, dwLen, pSource, dwLen);
\r
4814 CreateStreamOnHGlobal(h, TRUE, &spStream);
\r
4818 hr = E_OUTOFMEMORY;
\r
4823 ATL::CComBSTR bstrLicKey;
\r
4824 hr = ATL::_DialogSplitHelper::ParseInitData(spStream, &bstrLicKey.m_str);
\r
4825 if (SUCCEEDED(hr))
\r
4827 ATL::CAxWindow2 wnd;
\r
4828 // Get control caption.
\r
4829 LPWSTR pszClassName =
\r
4831 (LPWSTR)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem) + 1) :
\r
4832 (LPWSTR)(pItem + 1);
\r
4833 // Get control rect.
\r
4837 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->x :
\r
4841 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->y :
\r
4843 rect.right = rect.left +
\r
4845 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cx :
\r
4847 rect.bottom = rect.top +
\r
4849 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->cy :
\r
4852 // Convert from dialog units to screen units
\r
4853 MapDialogRect(&rect);
\r
4855 // Create AxWindow with a NULL caption.
\r
4856 wnd.Create(m_hWnd,
\r
4860 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->style :
\r
4861 pItem->style) | WS_TABSTOP,
\r
4863 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->exStyle :
\r
4866 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->id :
\r
4872 #ifndef _WIN32_WCE
\r
4873 // Set the Help ID
\r
4874 if (bDialogEx && ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID != 0)
\r
4875 wnd.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX*)pItem)->helpID);
\r
4876 #endif // !_WIN32_WCE
\r
4877 // Try to create the ActiveX control.
\r
4878 hr = wnd.CreateControlLic(pszClassName, spStream, NULL, bstrLicKey);
\r
4881 // Set the correct tab position.
\r
4883 hWndPrev = HWND_TOP;
\r
4884 wnd.SetWindowPos(hWndPrev, 0,0,0,0,SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
\r
4889 hr = ATL::AtlHresultFromLastError();
\r
4896 hWndPrev = ::GetWindow(hWndPrev, GW_HWNDNEXT);
\r
4898 pItem = ATL::_DialogSplitHelper::FindNextDlgItem(pItem, bDialogEx);
\r
4902 hr = ATL::AtlHresultFromLastError();
\r
4905 hr = ATL::AtlHresultFromLastError();
\r
4910 // Event handling support
\r
4911 HRESULT AdviseSinkMap(bool bAdvise)
\r
4913 if(!bAdvise && m_hWnd == NULL)
\r
4915 // window is gone, controls are already unadvised
\r
4916 ATLTRACE2(atlTraceUI, 0, _T("CAxPropertyPageImpl::AdviseSinkMap called after the window was destroyed\n"));
\r
4919 HRESULT hRet = E_NOTIMPL;
\r
4920 __if_exists(T::_GetSinkMapFinder)
\r
4922 T* pT = static_cast<T*>(this);
\r
4923 hRet = AtlAdviseSinkMap(pT, bAdvise);
\r
4928 // Message map and handlers
\r
4929 typedef CPropertyPageImpl< T, TBase> _baseClass;
\r
4930 BEGIN_MSG_MAP(CAxPropertyPageImpl)
\r
4931 MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
\r
4932 MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
\r
4933 CHAIN_MSG_MAP(_baseClass)
\r
4936 LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
\r
4938 // initialize controls in dialog with DLGINIT resource section
\r
4939 ExecuteDlgInit(static_cast<T*>(this)->IDD);
\r
4940 AdviseSinkMap(true);
\r
4945 LRESULT OnDestroy(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
\r
4947 AdviseSinkMap(false);
\r
4951 #endif // (_ATL_VER >= 0x0700)
\r
4954 // for non-customized pages
\r
4955 template <WORD t_wDlgTemplateID>
\r
4956 class CAxPropertyPage : public CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplateID> >
\r
4959 enum { IDD = t_wDlgTemplateID };
\r
4961 CAxPropertyPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl<CAxPropertyPage>(title)
\r
4964 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
\r
4965 // not empty so we handle accelerators/create controls
\r
4966 BEGIN_MSG_MAP(CAxPropertyPage)
\r
4967 CHAIN_MSG_MAP(CAxPropertyPageImpl<CAxPropertyPage<t_wDlgTemplateID> >)
\r
4969 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
\r
4970 DECLARE_EMPTY_MSG_MAP()
\r
4971 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
\r
4974 #endif // _ATL_NO_HOSTING
\r
4977 ///////////////////////////////////////////////////////////////////////////////
\r
4978 // Wizard97 Support
\r
4980 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
4982 // Sample wizard dialog resources:
\r
4984 // IDD_WIZ97_INTERIOR_BLANK DIALOG 0, 0, 317, 143
\r
4985 // STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
\r
4986 // CAPTION "Wizard97 Property Page - Interior"
\r
4987 // FONT 8, "MS Shell Dlg"
\r
4991 // IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193
\r
4992 // STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
\r
4993 // CAPTION "Wizard97 Property Page - Welcome/Complete"
\r
4994 // FONT 8, "MS Shell Dlg", 0, 0, 0x0
\r
4996 // LTEXT "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8,
\r
4998 // LTEXT "Wizard Explanation\r\n(The height of the static text should be in multiples of 8 dlus)",
\r
4999 // IDC_STATIC,115,40,195,16
\r
5000 // LTEXT "h",IDC_WIZ97_BULLET1,118,64,8,8
\r
5001 // LTEXT "List Item 1 (the h is turned into a bullet)",IDC_STATIC,
\r
5003 // LTEXT "h",IDC_WIZ97_BULLET2,118,79,8,8
\r
5004 // LTEXT "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC,
\r
5006 // CONTROL "&Do not show this Welcome page again",
\r
5007 // IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX |
\r
5008 // WS_TABSTOP,115,169,138,10
\r
5011 // GUIDELINES DESIGNINFO
\r
5013 // IDD_WIZ97_INTERIOR_BLANK, DIALOG
\r
5016 // RIGHTMARGIN, 310
\r
5022 // BOTTOMMARGIN, 136
\r
5026 // IDD_WIZ97_EXTERIOR_BLANK, DIALOG
\r
5028 // RIGHTMARGIN, 310
\r
5033 // BOTTOMMARGIN, 186
\r
5041 ///////////////////////////////////////////////////////////////////////////////
\r
5042 // CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet
\r
5044 class CWizard97SheetWindow : public CPropertySheetWindow
\r
5048 CWizard97SheetWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd)
\r
5051 CWizard97SheetWindow& operator =(HWND hWnd)
\r
5058 HFONT GetExteriorPageTitleFont(void)
\r
5060 ATLASSERT(::IsWindow(m_hWnd));
\r
5061 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetExteriorPageTitleFont(), 0, 0L);
\r
5064 HFONT GetBulletFont(void)
\r
5066 ATLASSERT(::IsWindow(m_hWnd));
\r
5067 return (HFONT)::SendMessage(m_hWnd, GetMessage_GetBulletFont(), 0, 0L);
\r
5071 static UINT GetMessage_GetExteriorPageTitleFont()
\r
5073 static UINT uGetExteriorPageTitleFont = 0;
\r
5074 if(uGetExteriorPageTitleFont == 0)
\r
5076 CStaticDataInitCriticalSectionLock lock;
\r
5077 if(FAILED(lock.Lock()))
\r
5079 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont().\n"));
\r
5084 if(uGetExteriorPageTitleFont == 0)
\r
5085 uGetExteriorPageTitleFont = ::RegisterWindowMessage(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12"));
\r
5089 ATLASSERT(uGetExteriorPageTitleFont != 0);
\r
5090 return uGetExteriorPageTitleFont;
\r
5093 static UINT GetMessage_GetBulletFont()
\r
5095 static UINT uGetBulletFont = 0;
\r
5096 if(uGetBulletFont == 0)
\r
5098 CStaticDataInitCriticalSectionLock lock;
\r
5099 if(FAILED(lock.Lock()))
\r
5101 ATLTRACE2(atlTraceUI, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n"));
\r
5106 if(uGetBulletFont == 0)
\r
5107 uGetBulletFont = ::RegisterWindowMessage(_T("GetBulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5"));
\r
5111 ATLASSERT(uGetBulletFont != 0);
\r
5112 return uGetBulletFont;
\r
5115 // Implementation - override to prevent usage
\r
5116 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
\r
5124 ///////////////////////////////////////////////////////////////////////////////
\r
5125 // CWizard97SheetImpl - implements a Wizard 97 style wizard sheet
\r
5127 template <class T, class TBase = CWizard97SheetWindow>
\r
5128 class ATL_NO_VTABLE CWizard97SheetImpl : public CPropertySheetImpl< T, TBase >
\r
5132 typedef CWizard97SheetImpl< T, TBase > thisClass;
\r
5133 typedef CPropertySheetImpl< T, TBase > baseClass;
\r
5135 // Member variables
\r
5136 CFont m_fontExteriorPageTitle; // Welcome and Completion page title font
\r
5137 CFont m_fontBullet; // Bullet font (used on static text 'h' to produce a small bullet)
\r
5138 bool m_bReceivedFirstSizeMessage;
\r
5141 CWizard97SheetImpl(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) :
\r
5142 baseClass(title, uStartPage, hWndParent),
\r
5143 m_bReceivedFirstSizeMessage(false)
\r
5145 m_psh.dwFlags &= ~(PSH_NOCONTEXTHELP);
\r
5146 m_psh.dwFlags &= ~(PSH_WIZARD | PSH_WIZARD_LITE);
\r
5148 m_psh.dwFlags |= (PSH_HASHELP | PSH_WIZARDCONTEXTHELP);
\r
5149 m_psh.dwFlags |= PSH_WIZARD97;
\r
5151 baseClass::SetHeader(headerBitmap.m_lpstr);
\r
5152 baseClass::SetWatermark(watermarkBitmap.m_lpstr);
\r
5155 // Overrides from base class
\r
5156 void OnSheetInitialized()
\r
5158 T* pT = static_cast<T*>(this);
\r
5159 pT->_InitializeFonts();
\r
5161 // We'd like to center the wizard here, but its too early.
\r
5162 // Instead, we'll do CenterWindow upon our first WM_SIZE message
\r
5166 void _InitializeFonts()
\r
5168 // Setup the Title and Bullet Font
\r
5169 // (Property pages can send the "get external page title font" and "get bullet font" messages)
\r
5170 // The derived class needs to do the actual SetFont for the dialog items)
\r
5172 CFontHandle fontThisDialog = this->GetFont();
\r
5173 CClientDC dcScreen(NULL);
\r
5175 LOGFONT titleLogFont = {0};
\r
5176 LOGFONT bulletLogFont = {0};
\r
5177 fontThisDialog.GetLogFont(&titleLogFont);
\r
5178 fontThisDialog.GetLogFont(&bulletLogFont);
\r
5180 // The Wizard 97 Spec recommends to do the Title Font
\r
5181 // as Verdana Bold, 12pt.
\r
5182 titleLogFont.lfCharSet = DEFAULT_CHARSET;
\r
5183 titleLogFont.lfWeight = FW_BOLD;
\r
5184 SecureHelper::strcpy_x(titleLogFont.lfFaceName, _countof(titleLogFont.lfFaceName), _T("Verdana Bold"));
\r
5185 INT titleFontPointSize = 12;
\r
5186 titleLogFont.lfHeight = -::MulDiv(titleFontPointSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72);
\r
5187 m_fontExteriorPageTitle.CreateFontIndirect(&titleLogFont);
\r
5189 // The Wizard 97 Spec recommends to do Bullets by having
\r
5190 // static text of "h" in the Marlett font.
\r
5191 bulletLogFont.lfCharSet = DEFAULT_CHARSET;
\r
5192 bulletLogFont.lfWeight = FW_NORMAL;
\r
5193 SecureHelper::strcpy_x(bulletLogFont.lfFaceName, _countof(bulletLogFont.lfFaceName), _T("Marlett"));
\r
5194 INT bulletFontSize = 8;
\r
5195 bulletLogFont.lfHeight = -::MulDiv(bulletFontSize, dcScreen.GetDeviceCaps(LOGPIXELSY), 72);
\r
5196 m_fontBullet.CreateFontIndirect(&bulletLogFont);
\r
5199 // Message Handling
\r
5200 BEGIN_MSG_MAP(thisClass)
\r
5201 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont(), OnGetExteriorPageTitleFont)
\r
5202 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont(), OnGetBulletFont)
\r
5203 MESSAGE_HANDLER(WM_SIZE, OnSize)
\r
5204 CHAIN_MSG_MAP(baseClass)
\r
5207 LRESULT OnGetExteriorPageTitleFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
\r
5209 return (LRESULT)(HFONT)m_fontExteriorPageTitle;
\r
5212 LRESULT OnGetBulletFont(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
\r
5214 return (LRESULT)(HFONT)m_fontBullet;
\r
5217 LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
\r
5219 if(!m_bReceivedFirstSizeMessage)
\r
5221 m_bReceivedFirstSizeMessage = true;
\r
5222 this->CenterWindow();
\r
5230 // for non-customized sheets
\r
5231 class CWizard97Sheet : public CWizard97SheetImpl<CWizard97Sheet>
\r
5235 typedef CWizard97Sheet thisClass;
\r
5236 typedef CWizard97SheetImpl<CWizard97Sheet> baseClass;
\r
5239 CWizard97Sheet(ATL::_U_STRINGorID title, ATL::_U_STRINGorID headerBitmap, ATL::_U_STRINGorID watermarkBitmap, UINT uStartPage = 0, HWND hWndParent = NULL) :
\r
5240 baseClass(title, headerBitmap, watermarkBitmap, uStartPage, hWndParent)
\r
5243 BEGIN_MSG_MAP(thisClass)
\r
5244 CHAIN_MSG_MAP(baseClass)
\r
5249 ///////////////////////////////////////////////////////////////////////////////
\r
5250 // CWizard97PageWindow - client side for a Wizard 97 style wizard page
\r
5252 #define WIZARD97_EXTERIOR_CXDLG 317
\r
5253 #define WIZARD97_EXTERIOR_CYDLG 193
\r
5255 #define WIZARD97_INTERIOR_CXDLG 317
\r
5256 #define WIZARD97_INTERIOR_CYDLG 143
\r
5258 class CWizard97PageWindow : public CPropertyPageWindow
\r
5262 CWizard97PageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd)
\r
5265 CWizard97PageWindow& operator =(HWND hWnd)
\r
5272 CWizard97SheetWindow GetPropertySheet() const
\r
5274 ATLASSERT(::IsWindow(m_hWnd));
\r
5275 return CWizard97SheetWindow(GetParent());
\r
5279 HFONT GetExteriorPageTitleFont(void)
\r
5281 ATLASSERT(::IsWindow(m_hWnd));
\r
5282 return GetPropertySheet().GetExteriorPageTitleFont();
\r
5285 HFONT GetBulletFont(void)
\r
5287 ATLASSERT(::IsWindow(m_hWnd));
\r
5288 return GetPropertySheet().GetBulletFont();
\r
5291 // Implementation - overrides to prevent usage
\r
5292 HWND Create(LPCTSTR, HWND, ATL::_U_RECT = NULL, LPCTSTR = NULL, DWORD = 0, DWORD = 0, ATL::_U_MENUorID = 0U, LPVOID = NULL)
\r
5301 ///////////////////////////////////////////////////////////////////////////////
\r
5302 // CWizard97PageImpl - implements a Wizard 97 style wizard page
\r
5304 template <class T, class TBase = CWizard97PageWindow>
\r
5305 class ATL_NO_VTABLE CWizard97PageImpl : public CPropertyPageImpl< T, TBase >
\r
5309 typedef CWizard97PageImpl< T, TBase > thisClass;
\r
5310 typedef CPropertyPageImpl< T, TBase > baseClass;
\r
5313 CWizard97PageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
\r
5316 // Message Handling
\r
5317 BEGIN_MSG_MAP(thisClass)
\r
5318 CHAIN_MSG_MAP(baseClass)
\r
5323 ///////////////////////////////////////////////////////////////////////////////
\r
5324 // CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page
\r
5326 template <class T, class TBase = CWizard97PageWindow>
\r
5327 class ATL_NO_VTABLE CWizard97ExteriorPageImpl : public CPropertyPageImpl< T, TBase >
\r
5331 typedef CWizard97ExteriorPageImpl< T, TBase > thisClass;
\r
5332 typedef CPropertyPageImpl< T, TBase > baseClass;
\r
5336 CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
\r
5338 m_psp.dwFlags |= PSP_HASHELP;
\r
5339 m_psp.dwFlags |= PSP_HIDEHEADER;
\r
5342 // Message Handling
\r
5343 BEGIN_MSG_MAP(thisClass)
\r
5344 CHAIN_MSG_MAP(baseClass)
\r
5349 ///////////////////////////////////////////////////////////////////////////////
\r
5350 // CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page
\r
5352 template <class T, class TBase = CWizard97PageWindow>
\r
5353 class ATL_NO_VTABLE CWizard97InteriorPageImpl : public CPropertyPageImpl< T, TBase >
\r
5357 typedef CWizard97InteriorPageImpl< T, TBase > thisClass;
\r
5358 typedef CPropertyPageImpl< T, TBase > baseClass;
\r
5362 CWizard97InteriorPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : baseClass(title)
\r
5364 m_psp.dwFlags |= PSP_HASHELP;
\r
5365 m_psp.dwFlags &= ~PSP_HIDEHEADER;
\r
5366 m_psp.dwFlags |= PSP_USEHEADERTITLE | PSP_USEHEADERSUBTITLE;
\r
5368 // Be sure to have the derived class define this in the constructor.
\r
5369 // We'll default it to something obvious in case its forgotten.
\r
5370 baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Class"));
\r
5371 baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the constructor of the Derived Class."));
\r
5374 // Message Handling
\r
5375 BEGIN_MSG_MAP(thisClass)
\r
5376 CHAIN_MSG_MAP(baseClass)
\r
5380 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
\r
5383 ///////////////////////////////////////////////////////////////////////////////
\r
5384 // Aero Wizard support
\r
5386 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
5388 ///////////////////////////////////////////////////////////////////////////////
\r
5389 // CAeroWizardFrameWindow - client side for an Aero Wizard frame window
\r
5391 class CAeroWizardFrameWindow : public CPropertySheetWindow
\r
5395 CAeroWizardFrameWindow(HWND hWnd = NULL) : CPropertySheetWindow(hWnd)
\r
5398 CAeroWizardFrameWindow& operator =(HWND hWnd)
\r
5404 // Operations - new, Aero Wizard only
\r
5405 void SetNextText(LPCWSTR lpszText)
\r
5407 ATLASSERT(::IsWindow(m_hWnd));
\r
5408 ::SendMessage(m_hWnd, PSM_SETNEXTTEXT, 0, (LPARAM)lpszText);
\r
5411 void ShowWizardButtons(DWORD dwButtons, DWORD dwStates)
\r
5413 ATLASSERT(::IsWindow(m_hWnd));
\r
5414 ::PostMessage(m_hWnd, PSM_SHOWWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons);
\r
5417 void EnableWizardButtons(DWORD dwButtons, DWORD dwStates)
\r
5419 ATLASSERT(::IsWindow(m_hWnd));
\r
5420 ::PostMessage(m_hWnd, PSM_ENABLEWIZBUTTONS, (WPARAM)dwStates, (LPARAM)dwButtons);
\r
5423 void SetButtonText(DWORD dwButton, LPCWSTR lpszText)
\r
5425 ATLASSERT(::IsWindow(m_hWnd));
\r
5426 ::SendMessage(m_hWnd, PSM_SETBUTTONTEXT, (WPARAM)dwButton, (LPARAM)lpszText);
\r
5431 ///////////////////////////////////////////////////////////////////////////////
\r
5432 // CAeroWizardFrameImpl - implements an Aero Wizard frame
\r
5434 template <class T, class TBase = CAeroWizardFrameWindow>
\r
5435 class ATL_NO_VTABLE CAeroWizardFrameImpl : public CPropertySheetImpl<T, TBase >
\r
5439 CAeroWizardFrameImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL) :
\r
5440 CPropertySheetImpl<T, TBase >(title, uStartPage, hWndParent)
\r
5442 m_psh.dwFlags |= PSH_WIZARD | PSH_AEROWIZARD;
\r
5446 void EnableResizing()
\r
5448 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
5449 m_psh.dwFlags |= PSH_RESIZABLE;
\r
5452 void UseHeaderBitmap()
\r
5454 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
5455 m_psh.dwFlags |= PSH_HEADERBITMAP;
\r
5458 void SetNoMargin()
\r
5460 ATLASSERT(m_hWnd == NULL); // can't do this after it's created
\r
5461 m_psh.dwFlags |= PSH_NOMARGIN;
\r
5464 // Override to prevent use
\r
5465 HWND Create(HWND /*hWndParent*/ = NULL)
\r
5467 ATLASSERT(FALSE); // not supported for Aero Wizard
\r
5473 ///////////////////////////////////////////////////////////////////////////////
\r
5474 // CAeroWizardFrame - for non-customized frames
\r
5476 class CAeroWizardFrame : public CAeroWizardFrameImpl<CAeroWizardFrame>
\r
5479 CAeroWizardFrame(ATL::_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
\r
5480 : CAeroWizardFrameImpl<CAeroWizardFrame>(title, uStartPage, hWndParent)
\r
5483 BEGIN_MSG_MAP(CAeroWizardFrame)
\r
5484 MESSAGE_HANDLER(WM_COMMAND, CAeroWizardFrameImpl<CAeroWizardFrame>::OnCommand)
\r
5489 ///////////////////////////////////////////////////////////////////////////////
\r
5490 // CAeroWizardPageWindow - client side for an Aero Wizard page
\r
5492 class CAeroWizardPageWindow : public CPropertyPageWindow
\r
5496 CAeroWizardPageWindow(HWND hWnd = NULL) : CPropertyPageWindow(hWnd)
\r
5499 CAeroWizardPageWindow& operator =(HWND hWnd)
\r
5506 CAeroWizardFrameWindow GetAeroWizardFrame() const
\r
5508 ATLASSERT(::IsWindow(m_hWnd));
\r
5509 // This is not really top-level frame window, but it processes all frame messages
\r
5510 return CAeroWizardFrameWindow(GetParent());
\r
5513 // Operations - new, Aero Wizard only
\r
5514 void SetNextText(LPCWSTR lpszText)
\r
5516 ATLASSERT(::IsWindow(m_hWnd));
\r
5517 ATLASSERT(GetParent() != NULL);
\r
5518 GetAeroWizardFrame().SetNextText(lpszText);
\r
5521 void ShowWizardButtons(DWORD dwButtons, DWORD dwStates)
\r
5523 ATLASSERT(::IsWindow(m_hWnd));
\r
5524 ATLASSERT(GetParent() != NULL);
\r
5525 GetAeroWizardFrame().ShowWizardButtons(dwButtons, dwStates);
\r
5528 void EnableWizardButtons(DWORD dwButtons, DWORD dwStates)
\r
5530 ATLASSERT(::IsWindow(m_hWnd));
\r
5531 ATLASSERT(GetParent() != NULL);
\r
5532 GetAeroWizardFrame().EnableWizardButtons(dwButtons, dwStates);
\r
5535 void SetButtonText(DWORD dwButton, LPCWSTR lpszText)
\r
5537 ATLASSERT(::IsWindow(m_hWnd));
\r
5538 ATLASSERT(GetParent() != NULL);
\r
5539 GetAeroWizardFrame().SetButtonText(dwButton, lpszText);
\r
5544 ///////////////////////////////////////////////////////////////////////////////
\r
5545 // CAeroWizardPageImpl - implements an Aero Wizard page
\r
5547 template <class T, class TBase = CAeroWizardPageWindow>
\r
5548 class ATL_NO_VTABLE CAeroWizardPageImpl : public CPropertyPageImpl<T, TBase >
\r
5551 CAeroWizardPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CPropertyPageImpl<T, TBase >(title)
\r
5556 ///////////////////////////////////////////////////////////////////////////////
\r
5557 // CAeroWizardPage - for non-customized pages
\r
5559 template <WORD t_wDlgTemplateID>
\r
5560 class CAeroWizardPage : public CAeroWizardPageImpl<CAeroWizardPage<t_wDlgTemplateID> >
\r
5563 enum { IDD = t_wDlgTemplateID };
\r
5565 CAeroWizardPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardPageImpl<CAeroWizardPage>(title)
\r
5568 DECLARE_EMPTY_MSG_MAP()
\r
5572 #ifndef _ATL_NO_HOSTING
\r
5574 // Note: You must #include <atlhost.h> to use these classes
\r
5576 ///////////////////////////////////////////////////////////////////////////////
\r
5577 // CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls
\r
5579 template <class T, class TBase = CAeroWizardPageWindow>
\r
5580 class ATL_NO_VTABLE CAeroWizardAxPageImpl : public CAxPropertyPageImpl< T, TBase >
\r
5583 CAeroWizardAxPageImpl(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAxPropertyPageImpl< T, TBase >(title)
\r
5588 ///////////////////////////////////////////////////////////////////////////////
\r
5589 // CAeroWizardAxPage - for non-customized pages
\r
5591 template <WORD t_wDlgTemplateID>
\r
5592 class CAeroWizardAxPage : public CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgTemplateID> >
\r
5595 enum { IDD = t_wDlgTemplateID };
\r
5597 CAeroWizardAxPage(ATL::_U_STRINGorID title = (LPCTSTR)NULL) : CAeroWizardAxPageImpl<CAeroWizardAxPage>(title)
\r
5600 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
\r
5601 // not empty so we handle accelerators/create controls
\r
5602 BEGIN_MSG_MAP(CAeroWizardAxPage)
\r
5603 CHAIN_MSG_MAP(CAeroWizardAxPageImpl<CAeroWizardAxPage<t_wDlgTemplateID> >)
\r
5605 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
\r
5606 DECLARE_EMPTY_MSG_MAP()
\r
5607 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
\r
5610 #endif // _ATL_NO_HOSTING
\r
5612 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
\r
5615 ///////////////////////////////////////////////////////////////////////////////
\r
5616 // TaskDialog support
\r
5618 #if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
\r
5620 ///////////////////////////////////////////////////////////////////////////////
\r
5621 // AtlTaskDialog - support for TaskDialog() function
\r
5623 inline int AtlTaskDialog(HWND hWndParent,
\r
5624 ATL::_U_STRINGorID WindowTitle, ATL::_U_STRINGorID MainInstructionText, ATL::_U_STRINGorID ContentText,
\r
5625 TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons = 0U, ATL::_U_STRINGorID Icon = (LPCTSTR)NULL)
\r
5629 #ifdef _WTL_TASKDIALOG_DIRECT
\r
5631 HRESULT hRet = ::TaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpstr), T2CW(ContentText.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet);
\r
5632 ATLVERIFY(SUCCEEDED(hRet));
\r
5634 // This allows apps to run on older versions of Windows
\r
5635 typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialog)(HWND hwndParent, HINSTANCE hInstance, PCWSTR pszWindowTitle, PCWSTR pszMainInstruction, PCWSTR pszContent, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons, PCWSTR pszIcon, int* pnButton);
\r
5637 HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
\r
5638 if(m_hCommCtrlDLL != NULL)
\r
5640 PFN_TaskDialog pfnTaskDialog = (PFN_TaskDialog)::GetProcAddress(m_hCommCtrlDLL, "TaskDialog");
\r
5641 if(pfnTaskDialog != NULL)
\r
5644 HRESULT hRet = pfnTaskDialog(hWndParent, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle.m_lpstr), T2CW(MainInstructionText.m_lpstr), T2CW(ContentText.m_lpstr), dwCommonButtons, T2CW(Icon.m_lpstr), &nRet);
\r
5645 ATLVERIFY(SUCCEEDED(hRet));
\r
5648 ::FreeLibrary(m_hCommCtrlDLL);
\r
5656 ///////////////////////////////////////////////////////////////////////////////
\r
5657 // CTaskDialogConfig - TASKDIALOGCONFIG wrapper
\r
5659 class CTaskDialogConfig : public TASKDIALOGCONFIG
\r
5663 CTaskDialogConfig()
\r
5670 memset(this, 0, sizeof(TASKDIALOGCONFIG)); // initialize structure to 0/NULL
\r
5671 this->cbSize = sizeof(TASKDIALOGCONFIG);
\r
5672 this->hInstance = ModuleHelper::GetResourceInstance();
\r
5675 // Operations - setting values
\r
5677 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons)
\r
5679 this->dwCommonButtons = dwCommonButtons;
\r
5682 // window title text
\r
5683 void SetWindowTitle(UINT nID)
\r
5685 this->pszWindowTitle = MAKEINTRESOURCEW(nID);
\r
5688 void SetWindowTitle(LPCWSTR lpstrWindowTitle)
\r
5690 this->pszWindowTitle = lpstrWindowTitle;
\r
5694 void SetMainIcon(HICON hIcon)
\r
5696 this->dwFlags |= TDF_USE_HICON_MAIN;
\r
5697 this->hMainIcon = hIcon;
\r
5700 void SetMainIcon(UINT nID)
\r
5702 this->dwFlags &= ~TDF_USE_HICON_MAIN;
\r
5703 this->pszMainIcon = MAKEINTRESOURCEW(nID);
\r
5706 void SetMainIcon(LPCWSTR lpstrMainIcon)
\r
5708 this->dwFlags &= ~TDF_USE_HICON_MAIN;
\r
5709 this->pszMainIcon = lpstrMainIcon;
\r
5712 // main instruction text
\r
5713 void SetMainInstructionText(UINT nID)
\r
5715 this->pszMainInstruction = MAKEINTRESOURCEW(nID);
\r
5718 void SetMainInstructionText(LPCWSTR lpstrMainInstruction)
\r
5720 this->pszMainInstruction = lpstrMainInstruction;
\r
5724 void SetContentText(UINT nID)
\r
5726 this->pszContent = MAKEINTRESOURCEW(nID);
\r
5729 void SetContentText(LPCWSTR lpstrContent)
\r
5731 this->pszContent = lpstrContent;
\r
5735 void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0)
\r
5737 this->pButtons = pButtons;
\r
5738 this->cButtons = cButtons;
\r
5739 if(nDefaultButton != 0)
\r
5740 this->nDefaultButton = nDefaultButton;
\r
5743 void SetDefaultButton(int nDefaultButton)
\r
5745 this->nDefaultButton = nDefaultButton;
\r
5749 void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0)
\r
5751 this->pRadioButtons = pRadioButtons;
\r
5752 this->cRadioButtons = cRadioButtons;
\r
5753 if(nDefaultRadioButton != 0)
\r
5754 this->nDefaultRadioButton = nDefaultRadioButton;
\r
5757 void SetDefaultRadioButton(int nDefaultRadioButton)
\r
5759 this->nDefaultRadioButton = nDefaultRadioButton;
\r
5762 // verification text
\r
5763 void SetVerificationText(UINT nID)
\r
5765 this->pszVerificationText = MAKEINTRESOURCEW(nID);
\r
5768 void SetVerificationText(LPCWSTR lpstrVerificationText)
\r
5770 this->pszVerificationText = lpstrVerificationText;
\r
5773 // expanded information text
\r
5774 void SetExpandedInformationText(UINT nID)
\r
5776 this->pszExpandedInformation = MAKEINTRESOURCEW(nID);
\r
5779 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation)
\r
5781 this->pszExpandedInformation = lpstrExpandedInformation;
\r
5784 // expanded control text
\r
5785 void SetExpandedControlText(UINT nID)
\r
5787 this->pszExpandedControlText = MAKEINTRESOURCEW(nID);
\r
5790 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText)
\r
5792 this->pszExpandedControlText = lpstrExpandedControlText;
\r
5795 // collapsed control text
\r
5796 void SetCollapsedControlText(UINT nID)
\r
5798 this->pszCollapsedControlText = MAKEINTRESOURCEW(nID);
\r
5801 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText)
\r
5803 this->pszCollapsedControlText = lpstrCollapsedControlText;
\r
5807 void SetFooterIcon(HICON hIcon)
\r
5809 this->dwFlags |= TDF_USE_HICON_FOOTER;
\r
5810 this->hFooterIcon = hIcon;
\r
5813 void SetFooterIcon(UINT nID)
\r
5815 this->dwFlags &= ~TDF_USE_HICON_FOOTER;
\r
5816 this->pszFooterIcon = MAKEINTRESOURCEW(nID);
\r
5819 void SetFooterIcon(LPCWSTR lpstrFooterIcon)
\r
5821 this->dwFlags &= ~TDF_USE_HICON_FOOTER;
\r
5822 this->pszFooterIcon = lpstrFooterIcon;
\r
5826 void SetFooterText(UINT nID)
\r
5828 this->pszFooter = MAKEINTRESOURCEW(nID);
\r
5831 void SetFooterText(LPCWSTR lpstrFooterText)
\r
5833 this->pszFooter = lpstrFooterText;
\r
5836 // width (in DLUs)
\r
5837 void SetWidth(UINT cxWidth)
\r
5839 this->cxWidth = cxWidth;
\r
5843 void ModifyFlags(DWORD dwRemove, DWORD dwAdd)
\r
5845 this->dwFlags = (this->dwFlags & ~dwRemove) | dwAdd;
\r
5850 ///////////////////////////////////////////////////////////////////////////////
\r
5851 // CTaskDialogImpl - implements a Task Dialog
\r
5853 template <class T>
\r
5854 class ATL_NO_VTABLE CTaskDialogImpl
\r
5857 CTaskDialogConfig m_tdc;
\r
5858 HWND m_hWnd; // used only in callback functions
\r
5861 CTaskDialogImpl(HWND hWndParent = NULL) : m_hWnd(NULL)
\r
5863 m_tdc.hwndParent = hWndParent;
\r
5864 m_tdc.pfCallback = T::TaskDialogCallback;
\r
5865 m_tdc.lpCallbackData = (LONG_PTR)static_cast<T*>(this);
\r
5869 HRESULT DoModal(HWND hWndParent = ::GetActiveWindow(), int* pnButton = NULL, int* pnRadioButton = NULL, BOOL* pfVerificationFlagChecked = NULL)
\r
5871 if(m_tdc.hwndParent == NULL)
\r
5872 m_tdc.hwndParent = hWndParent;
\r
5874 #ifdef _WTL_TASKDIALOG_DIRECT
\r
5875 return ::TaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked);
\r
5878 // This allows apps to run on older versions of Windows
\r
5879 typedef HRESULT (STDAPICALLTYPE *PFN_TaskDialogIndirect)(const TASKDIALOGCONFIG* pTaskConfig, int* pnButton, int* pnRadioButton, BOOL* pfVerificationFlagChecked);
\r
5881 HRESULT hRet = E_UNEXPECTED;
\r
5882 HMODULE m_hCommCtrlDLL = ::LoadLibrary(_T("comctl32.dll"));
\r
5883 if(m_hCommCtrlDLL != NULL)
\r
5885 PFN_TaskDialogIndirect pfnTaskDialogIndirect = (PFN_TaskDialogIndirect)::GetProcAddress(m_hCommCtrlDLL, "TaskDialogIndirect");
\r
5886 if(pfnTaskDialogIndirect != NULL)
\r
5887 hRet = pfnTaskDialogIndirect(&m_tdc, pnButton, pnRadioButton, pfVerificationFlagChecked);
\r
5889 ::FreeLibrary(m_hCommCtrlDLL);
\r
5896 // Operations - setting values of TASKDIALOGCONFIG
\r
5898 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons)
\r
5899 { m_tdc.SetCommonButtons(dwCommonButtons); }
\r
5900 // window title text
\r
5901 void SetWindowTitle(UINT nID)
\r
5902 { m_tdc.SetWindowTitle(nID); }
\r
5903 void SetWindowTitle(LPCWSTR lpstrWindowTitle)
\r
5904 { m_tdc.SetWindowTitle(lpstrWindowTitle); }
\r
5906 void SetMainIcon(HICON hIcon)
\r
5907 { m_tdc.SetMainIcon(hIcon); }
\r
5908 void SetMainIcon(UINT nID)
\r
5909 { m_tdc.SetMainIcon(nID); }
\r
5910 void SetMainIcon(LPCWSTR lpstrMainIcon)
\r
5911 { m_tdc.SetMainIcon(lpstrMainIcon); }
\r
5912 // main instruction text
\r
5913 void SetMainInstructionText(UINT nID)
\r
5914 { m_tdc.SetMainInstructionText(nID); }
\r
5915 void SetMainInstructionText(LPCWSTR lpstrMainInstruction)
\r
5916 { m_tdc.SetMainInstructionText(lpstrMainInstruction); }
\r
5918 void SetContentText(UINT nID)
\r
5919 { m_tdc.SetContentText(nID); }
\r
5920 void SetContentText(LPCWSTR lpstrContent)
\r
5921 { m_tdc.SetContentText(lpstrContent); }
\r
5923 void SetButtons(const TASKDIALOG_BUTTON* pButtons, UINT cButtons, int nDefaultButton = 0)
\r
5924 { m_tdc.SetButtons(pButtons, cButtons, nDefaultButton); }
\r
5925 void SetDefaultButton(int nDefaultButton)
\r
5926 { m_tdc.SetDefaultButton(nDefaultButton); }
\r
5928 void SetRadioButtons(const TASKDIALOG_BUTTON* pRadioButtons, UINT cRadioButtons, int nDefaultRadioButton = 0)
\r
5929 { m_tdc.SetRadioButtons(pRadioButtons, cRadioButtons, nDefaultRadioButton); }
\r
5930 void SetDefaultRadioButton(int nDefaultRadioButton)
\r
5931 { m_tdc.SetDefaultRadioButton(nDefaultRadioButton); }
\r
5932 // verification text
\r
5933 void SetVerificationText(UINT nID)
\r
5934 { m_tdc.SetVerificationText(nID); }
\r
5935 void SetVerificationText(LPCWSTR lpstrVerificationText)
\r
5936 { m_tdc.SetVerificationText(lpstrVerificationText); }
\r
5937 // expanded information text
\r
5938 void SetExpandedInformationText(UINT nID)
\r
5939 { m_tdc.SetExpandedInformationText(nID); }
\r
5940 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation)
\r
5941 { m_tdc.SetExpandedInformationText(lpstrExpandedInformation); }
\r
5942 // expanded control text
\r
5943 void SetExpandedControlText(UINT nID)
\r
5944 { m_tdc.SetExpandedControlText(nID); }
\r
5945 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText)
\r
5946 { m_tdc.SetExpandedControlText(lpstrExpandedControlText); }
\r
5947 // collapsed control text
\r
5948 void SetCollapsedControlText(UINT nID)
\r
5949 { m_tdc.SetCollapsedControlText(nID); }
\r
5950 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText)
\r
5951 { m_tdc.SetCollapsedControlText(lpstrCollapsedControlText); }
\r
5953 void SetFooterIcon(HICON hIcon)
\r
5954 { m_tdc.SetFooterIcon(hIcon); }
\r
5955 void SetFooterIcon(UINT nID)
\r
5956 { m_tdc.SetFooterIcon(nID); }
\r
5957 void SetFooterIcon(LPCWSTR lpstrFooterIcon)
\r
5958 { m_tdc.SetFooterIcon(lpstrFooterIcon); }
\r
5960 void SetFooterText(UINT nID)
\r
5961 { m_tdc.SetFooterText(nID); }
\r
5962 void SetFooterText(LPCWSTR lpstrFooterText)
\r
5963 { m_tdc.SetFooterText(lpstrFooterText); }
\r
5964 // width (in DLUs)
\r
5965 void SetWidth(UINT cxWidth)
\r
5966 { m_tdc.SetWidth(cxWidth); }
\r
5968 void ModifyFlags(DWORD dwRemove, DWORD dwAdd)
\r
5969 { m_tdc.ModifyFlags(dwRemove, dwAdd); }
\r
5972 static HRESULT CALLBACK TaskDialogCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LONG_PTR lpRefData)
\r
5974 T* pT = (T*)lpRefData;
\r
5975 ATLASSERT(pT->m_hWnd == NULL || pT->m_hWnd == hWnd);
\r
5977 BOOL bRet = FALSE;
\r
5980 case TDN_DIALOG_CONSTRUCTED:
\r
5981 pT->m_hWnd = hWnd;
\r
5982 pT->OnDialogConstructed();
\r
5987 case TDN_BUTTON_CLICKED:
\r
5988 bRet = pT->OnButtonClicked((int)wParam);
\r
5990 case TDN_RADIO_BUTTON_CLICKED:
\r
5991 pT->OnRadioButtonClicked((int)wParam);
\r
5993 case TDN_HYPERLINK_CLICKED:
\r
5994 pT->OnHyperlinkClicked((LPCWSTR)lParam);
\r
5996 case TDN_EXPANDO_BUTTON_CLICKED:
\r
5997 pT->OnExpandoButtonClicked((wParam != 0));
\r
5999 case TDN_VERIFICATION_CLICKED:
\r
6000 pT->OnVerificationClicked((wParam != 0));
\r
6006 bRet = pT->OnTimer((DWORD)wParam);
\r
6008 case TDN_NAVIGATED:
\r
6009 pT->OnNavigated();
\r
6011 case TDN_DESTROYED:
\r
6012 pT->OnDestroyed();
\r
6013 pT->m_hWnd = NULL;
\r
6016 ATLTRACE2(atlTraceUI, 0, _T("Unknown notification received in CTaskDialogImpl::TaskDialogCallback\n"));
\r
6020 return (HRESULT)bRet;
\r
6023 // Overrideables - notification handlers
\r
6024 void OnDialogConstructed()
\r
6032 BOOL OnButtonClicked(int /*nButton*/)
\r
6034 return FALSE; // don't prevent dialog to close
\r
6037 void OnRadioButtonClicked(int /*nRadioButton*/)
\r
6041 void OnHyperlinkClicked(LPCWSTR /*pszHREF*/)
\r
6045 void OnExpandoButtonClicked(bool /*bExpanded*/)
\r
6049 void OnVerificationClicked(bool /*bChecked*/)
\r
6057 BOOL OnTimer(DWORD /*dwTickCount*/)
\r
6059 return FALSE; // don't reset counter
\r
6062 void OnNavigated()
\r
6066 void OnDestroyed()
\r
6070 // Commands - valid to call only from handlers
\r
6071 void NavigatePage(TASKDIALOGCONFIG& tdc)
\r
6073 ATLASSERT(m_hWnd != NULL);
\r
6075 tdc.cbSize = sizeof(TASKDIALOGCONFIG);
\r
6076 if(tdc.hwndParent == NULL)
\r
6077 tdc.hwndParent = m_tdc.hwndParent;
\r
6078 tdc.pfCallback = m_tdc.pfCallback;
\r
6079 tdc.lpCallbackData = m_tdc.lpCallbackData;
\r
6080 (TASKDIALOGCONFIG)m_tdc = tdc;
\r
6082 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&tdc);
\r
6085 // modify TASKDIALOGCONFIG values, then call this to update task dialog
\r
6086 void NavigatePage()
\r
6088 ATLASSERT(m_hWnd != NULL);
\r
6089 ::SendMessage(m_hWnd, TDM_NAVIGATE_PAGE, 0, (LPARAM)&m_tdc);
\r
6092 void ClickButton(int nButton)
\r
6094 ATLASSERT(m_hWnd != NULL);
\r
6095 ::SendMessage(m_hWnd, TDM_CLICK_BUTTON, nButton, 0L);
\r
6098 void SetMarqueeProgressBar(BOOL bMarquee)
\r
6100 ATLASSERT(m_hWnd != NULL);
\r
6101 ::SendMessage(m_hWnd, TDM_SET_MARQUEE_PROGRESS_BAR, bMarquee, 0L);
\r
6104 BOOL SetProgressBarState(int nNewState)
\r
6106 ATLASSERT(m_hWnd != NULL);
\r
6107 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_STATE, nNewState, 0L);
\r
6110 DWORD SetProgressBarRange(int nMinRange, int nMaxRange)
\r
6112 ATLASSERT(m_hWnd != NULL);
\r
6113 return (DWORD)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_RANGE, 0, MAKELPARAM(nMinRange, nMaxRange));
\r
6116 int SetProgressBarPos(int nNewPos)
\r
6118 ATLASSERT(m_hWnd != NULL);
\r
6119 return (int)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_POS, nNewPos, 0L);
\r
6122 BOOL SetProgressBarMarquee(BOOL bMarquee, UINT uSpeed)
\r
6124 ATLASSERT(m_hWnd != NULL);
\r
6125 return (BOOL)::SendMessage(m_hWnd, TDM_SET_PROGRESS_BAR_MARQUEE, bMarquee, uSpeed);
\r
6128 void SetElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText)
\r
6130 ATLASSERT(m_hWnd != NULL);
\r
6131 ::SendMessage(m_hWnd, TDM_SET_ELEMENT_TEXT, element, (LPARAM)lpstrText);
\r
6134 void ClickRadioButton(int nRadioButton)
\r
6136 ATLASSERT(m_hWnd != NULL);
\r
6137 ::SendMessage(m_hWnd, TDM_CLICK_RADIO_BUTTON, nRadioButton, 0L);
\r
6140 void EnableButton(int nButton, BOOL bEnable)
\r
6142 ATLASSERT(m_hWnd != NULL);
\r
6143 ::SendMessage(m_hWnd, TDM_ENABLE_BUTTON, nButton, bEnable);
\r
6146 void EnableRadioButton(int nButton, BOOL bEnable)
\r
6148 ATLASSERT(m_hWnd != NULL);
\r
6149 ::SendMessage(m_hWnd, TDM_ENABLE_RADIO_BUTTON, nButton, bEnable);
\r
6152 void ClickVerification(BOOL bCheck, BOOL bFocus)
\r
6154 ATLASSERT(m_hWnd != NULL);
\r
6155 ::SendMessage(m_hWnd, TDM_CLICK_VERIFICATION, bCheck, bFocus);
\r
6158 void UpdateElementText(TASKDIALOG_ELEMENTS element, LPCWSTR lpstrText)
\r
6160 ATLASSERT(m_hWnd != NULL);
\r
6161 ::SendMessage(m_hWnd, TDM_UPDATE_ELEMENT_TEXT, element, (LPARAM)lpstrText);
\r
6164 void SetButtonElevationRequiredState(int nButton, BOOL bElevation)
\r
6166 ATLASSERT(m_hWnd != NULL);
\r
6167 ::SendMessage(m_hWnd, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE, nButton, bElevation);
\r
6170 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, HICON hIcon)
\r
6172 ATLASSERT(m_hWnd != NULL);
\r
6174 if(element == TDIE_ICON_MAIN)
\r
6175 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) != 0);
\r
6176 else if(element == TDIE_ICON_FOOTER)
\r
6177 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) != 0);
\r
6179 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)hIcon);
\r
6182 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element, LPCWSTR lpstrIcon)
\r
6184 ATLASSERT(m_hWnd != NULL);
\r
6186 if(element == TDIE_ICON_MAIN)
\r
6187 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_MAIN) == 0);
\r
6188 else if(element == TDIE_ICON_FOOTER)
\r
6189 ATLASSERT((m_tdc.dwFlags & TDF_USE_HICON_FOOTER) == 0);
\r
6191 ::SendMessage(m_hWnd, TDM_UPDATE_ICON, element, (LPARAM)lpstrIcon);
\r
6196 ///////////////////////////////////////////////////////////////////////////////
\r
6197 // CTaskDialog - for non-customized task dialogs
\r
6199 class CTaskDialog : public CTaskDialogImpl<CTaskDialog>
\r
6202 CTaskDialog(HWND hWndParent = NULL) : CTaskDialogImpl<CTaskDialog>(hWndParent)
\r
6204 m_tdc.pfCallback = NULL;
\r
6208 #endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
\r
6210 }; // namespace WTL
\r
6212 #endif // __ATLDLGS_H__
\r