1 // Windows Template Library - WTL version 8.0
2 // Copyright (C) Microsoft Corporation. All rights reserved.
4 // This file is a part of the Windows Template Library.
5 // The use and distribution terms for this software are covered by the
6 // Microsoft Permissive License (Ms-PL) which can be found in the file
7 // Ms-PL.txt at the root of this distribution.
15 #error ATL requires C++ compilation (use a .cpp suffix)
19 #error atldlgs.h requires atlapp.h to be included first
23 #error atldlgs.h requires atlwin.h to be included first
29 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
31 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
34 ///////////////////////////////////////////////////////////////////////////////
35 // Classes in this file:
40 // CMultiFileDialogImpl<T>
42 // CShellFileDialogImpl<T>
43 // CShellFileOpenDialogImpl<T>
44 // CShellFileOpenDialog
45 // CShellFileSaveDialogImpl<T>
46 // CShellFileSaveDialog
47 // CFolderDialogImpl<T>
51 // CRichEditFontDialogImpl<T>
52 // CRichEditFontDialog
53 // CColorDialogImpl<T>
55 // CPrintDialogImpl<T>
57 // CPrintDialogExImpl<T>
59 // CPageSetupDialogImpl<T>
61 // CFindReplaceDialogImpl<T>
65 // CIndirectDialogImpl<T, TDlgTemplate, TBase>
67 // CPropertySheetWindow
68 // CPropertySheetImpl<T, TBase>
70 // CPropertyPageWindow
71 // CPropertyPageImpl<T, TBase>
72 // CPropertyPage<t_wDlgTemplateID>
73 // CAxPropertyPageImpl<T, TBase>
74 // CAxPropertyPage<t_wDlgTemplateID>
76 // CWizard97SheetWindow
77 // CWizard97SheetImpl<T, TBase>
79 // CWizard97PageWindow
80 // CWizard97PageImpl<T, TBase>
81 // CWizard97ExteriorPageImpl<T, TBase>
82 // CWizard97InteriorPageImpl<T, TBase>
84 // CAeroWizardFrameWindow
85 // CAeroWizardFrameImpl<T, TBase>
87 // CAeroWizardPageWindow
88 // CAeroWizardPageImpl<T, TBase>
89 // CAeroWizardPage<t_wDlgTemplateID>
90 // CAeroWizardAxPageImpl<T, TBase>
91 // CAeroWizardAxPage<t_wDlgTemplateID>
104 ///////////////////////////////////////////////////////////////////////////////
105 // CFileDialogImpl - used for File Open or File Save As
107 // compatibility with the old (vc6.0) headers
108 #if (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
109 #ifndef CDSIZEOF_STRUCT
110 #define CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member))
112 #define OPENFILENAME_SIZE_VERSION_400A CDSIZEOF_STRUCT(OPENFILENAMEA,lpTemplateName)
113 #define OPENFILENAME_SIZE_VERSION_400W CDSIZEOF_STRUCT(OPENFILENAMEW,lpTemplateName)
115 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400W
117 #define OPENFILENAME_SIZE_VERSION_400 OPENFILENAME_SIZE_VERSION_400A
119 #endif // (_WIN32_WINNT >= 0x0500) && !defined(OPENFILENAME_SIZE_VERSION_400)
121 #if !defined(_WIN32_WCE) && !defined(CDN_INCLUDEITEM)
122 #define CDN_INCLUDEITEM (CDN_FIRST - 0x0007)
126 class ATL_NO_VTABLE CFileDialogImpl
: public ATL::CDialogImplBase
129 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
130 OPENFILENAMEEX m_ofn
;
134 BOOL m_bOpenFileDialog
; // TRUE for file open, FALSE for file save
135 TCHAR m_szFileTitle
[_MAX_FNAME
]; // contains file title after return
136 TCHAR m_szFileName
[_MAX_PATH
]; // contains full path name after return
138 CFileDialogImpl(BOOL bOpenFileDialog
, // TRUE for FileOpen, FALSE for FileSaveAs
139 LPCTSTR lpszDefExt
= NULL
,
140 LPCTSTR lpszFileName
= NULL
,
141 DWORD dwFlags
= OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
,
142 LPCTSTR lpszFilter
= NULL
,
143 HWND hWndParent
= NULL
)
145 memset(&m_ofn
, 0, sizeof(m_ofn
)); // initialize structure to 0/NULL
146 m_szFileName
[0] = _T('\0');
147 m_szFileTitle
[0] = _T('\0');
149 m_bOpenFileDialog
= bOpenFileDialog
;
151 m_ofn
.lStructSize
= sizeof(m_ofn
);
152 #if (_WIN32_WINNT >= 0x0500)
153 // adjust struct size if running on older version of Windows
154 if(AtlIsOldWindows())
156 ATLASSERT(sizeof(m_ofn
) > OPENFILENAME_SIZE_VERSION_400
); // must be
157 m_ofn
.lStructSize
= OPENFILENAME_SIZE_VERSION_400
;
159 #endif // (_WIN32_WINNT >= 0x0500)
160 m_ofn
.lpstrFile
= m_szFileName
;
161 m_ofn
.nMaxFile
= _MAX_PATH
;
162 m_ofn
.lpstrDefExt
= lpszDefExt
;
163 m_ofn
.lpstrFileTitle
= (LPTSTR
)m_szFileTitle
;
164 m_ofn
.nMaxFileTitle
= _MAX_FNAME
;
166 m_ofn
.Flags
= dwFlags
| OFN_EXPLORER
| OFN_ENABLEHOOK
| OFN_ENABLESIZING
;
168 m_ofn
.Flags
= dwFlags
| OFN_EXPLORER
| OFN_ENABLEHOOK
;
169 #endif // !_WIN32_WCE
170 m_ofn
.lpstrFilter
= lpszFilter
;
171 m_ofn
.hInstance
= ModuleHelper::GetResourceInstance();
172 m_ofn
.lpfnHook
= (LPOFNHOOKPROC
)T::StartDialogProc
;
173 m_ofn
.hwndOwner
= hWndParent
;
175 // setup initial file name
176 if(lpszFileName
!= NULL
)
177 SecureHelper::strncpy_x(m_szFileName
, _countof(m_szFileName
), lpszFileName
, _TRUNCATE
);
180 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
182 ATLASSERT((m_ofn
.Flags
& OFN_ENABLEHOOK
) != 0);
183 ATLASSERT(m_ofn
.lpfnHook
!= NULL
); // can still be a user hook
185 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
187 if(m_ofn
.hwndOwner
== NULL
) // set only if not specified before
188 m_ofn
.hwndOwner
= hWndParent
;
190 ATLASSERT(m_hWnd
== NULL
);
191 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (ATL::CDialogImplBase
*)this);
194 if(m_bOpenFileDialog
)
195 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
196 bRet
= ::GetOpenFileNameEx(&m_ofn
);
198 bRet
= ::GetSaveFileName((LPOPENFILENAME
)&m_ofn
);
200 bRet
= ::GetOpenFileName(&m_ofn
);
202 bRet
= ::GetSaveFileName(&m_ofn
);
207 return bRet
? IDOK
: IDCANCEL
;
211 ATL::CWindow
GetFileDialogWindow() const
213 ATLASSERT(::IsWindow(m_hWnd
));
214 return ATL::CWindow(GetParent());
217 int GetFilePath(LPTSTR lpstrFilePath
, int nLength
) const
219 ATLASSERT(::IsWindow(m_hWnd
));
220 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
222 return (int)GetFileDialogWindow().SendMessage(CDM_GETFILEPATH
, nLength
, (LPARAM
)lpstrFilePath
);
225 int GetFolderIDList(LPVOID lpBuff
, int nLength
) const
227 ATLASSERT(::IsWindow(m_hWnd
));
228 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
230 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERIDLIST
, nLength
, (LPARAM
)lpBuff
);
233 int GetFolderPath(LPTSTR lpstrFolderPath
, int nLength
) const
235 ATLASSERT(::IsWindow(m_hWnd
));
236 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
238 return (int)GetFileDialogWindow().SendMessage(CDM_GETFOLDERPATH
, nLength
, (LPARAM
)lpstrFolderPath
);
241 int GetSpec(LPTSTR lpstrSpec
, int nLength
) const
243 ATLASSERT(::IsWindow(m_hWnd
));
244 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
246 return (int)GetFileDialogWindow().SendMessage(CDM_GETSPEC
, nLength
, (LPARAM
)lpstrSpec
);
249 void SetControlText(int nCtrlID
, LPCTSTR lpstrText
)
251 ATLASSERT(::IsWindow(m_hWnd
));
252 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
254 GetFileDialogWindow().SendMessage(CDM_SETCONTROLTEXT
, nCtrlID
, (LPARAM
)lpstrText
);
257 void SetDefExt(LPCTSTR lpstrExt
)
259 ATLASSERT(::IsWindow(m_hWnd
));
260 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
262 GetFileDialogWindow().SendMessage(CDM_SETDEFEXT
, 0, (LPARAM
)lpstrExt
);
265 BOOL
GetReadOnlyPref() const // return TRUE if readonly checked
267 return ((m_ofn
.Flags
& OFN_READONLY
) != 0) ? TRUE
: FALSE
;
271 void HideControl(int nCtrlID
)
273 ATLASSERT(::IsWindow(m_hWnd
));
274 ATLASSERT((m_ofn
.Flags
& OFN_EXPLORER
) != 0);
276 GetFileDialogWindow().SendMessage(CDM_HIDECONTROL
, nCtrlID
);
279 // Special override for common dialogs
280 BOOL
EndDialog(INT_PTR
/*nRetCode*/ = 0)
282 ATLASSERT(::IsWindow(m_hWnd
));
283 GetFileDialogWindow().SendMessage(WM_COMMAND
, MAKEWPARAM(IDCANCEL
, 0));
287 // Message map and handlers
288 BEGIN_MSG_MAP(CFileDialogImpl
)
289 NOTIFY_CODE_HANDLER(CDN_FILEOK
, _OnFileOK
)
290 NOTIFY_CODE_HANDLER(CDN_FOLDERCHANGE
, _OnFolderChange
)
291 NOTIFY_CODE_HANDLER(CDN_HELP
, _OnHelp
)
292 NOTIFY_CODE_HANDLER(CDN_INITDONE
, _OnInitDone
)
293 NOTIFY_CODE_HANDLER(CDN_SELCHANGE
, _OnSelChange
)
294 NOTIFY_CODE_HANDLER(CDN_SHAREVIOLATION
, _OnShareViolation
)
295 NOTIFY_CODE_HANDLER(CDN_TYPECHANGE
, _OnTypeChange
)
297 NOTIFY_CODE_HANDLER(CDN_INCLUDEITEM
, _OnIncludeItem
)
298 #endif // !_WIN32_WCE
301 LRESULT
_OnFileOK(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
303 ATLASSERT(::IsWindow(m_hWnd
));
304 T
* pT
= static_cast<T
*>(this);
305 return !pT
->OnFileOK((LPOFNOTIFY
)pnmh
);
308 LRESULT
_OnFolderChange(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
310 ATLASSERT(::IsWindow(m_hWnd
));
311 T
* pT
= static_cast<T
*>(this);
312 pT
->OnFolderChange((LPOFNOTIFY
)pnmh
);
316 LRESULT
_OnHelp(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
318 ATLASSERT(::IsWindow(m_hWnd
));
319 T
* pT
= static_cast<T
*>(this);
320 pT
->OnHelp((LPOFNOTIFY
)pnmh
);
324 LRESULT
_OnInitDone(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
326 ATLASSERT(::IsWindow(m_hWnd
));
327 T
* pT
= static_cast<T
*>(this);
328 pT
->OnInitDone((LPOFNOTIFY
)pnmh
);
332 LRESULT
_OnSelChange(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
334 ATLASSERT(::IsWindow(m_hWnd
));
335 T
* pT
= static_cast<T
*>(this);
336 pT
->OnSelChange((LPOFNOTIFY
)pnmh
);
340 LRESULT
_OnShareViolation(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
342 ATLASSERT(::IsWindow(m_hWnd
));
343 T
* pT
= static_cast<T
*>(this);
344 return pT
->OnShareViolation((LPOFNOTIFY
)pnmh
);
347 LRESULT
_OnTypeChange(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
349 ATLASSERT(::IsWindow(m_hWnd
));
350 T
* pT
= static_cast<T
*>(this);
351 pT
->OnTypeChange((LPOFNOTIFY
)pnmh
);
356 LRESULT
_OnIncludeItem(int /*idCtrl*/, LPNMHDR pnmh
, BOOL
& /*bHandled*/)
358 ATLASSERT(::IsWindow(m_hWnd
));
359 T
* pT
= static_cast<T
*>(this);
360 return pT
->OnIncludeItem((LPOFNOTIFYEX
)pnmh
);
362 #endif // !_WIN32_WCE
365 BOOL
OnFileOK(LPOFNOTIFY
/*lpon*/)
370 void OnFolderChange(LPOFNOTIFY
/*lpon*/)
374 void OnHelp(LPOFNOTIFY
/*lpon*/)
378 void OnInitDone(LPOFNOTIFY
/*lpon*/)
382 void OnSelChange(LPOFNOTIFY
/*lpon*/)
386 int OnShareViolation(LPOFNOTIFY
/*lpon*/)
391 void OnTypeChange(LPOFNOTIFY
/*lpon*/)
396 BOOL
OnIncludeItem(LPOFNOTIFYEX
/*lponex*/)
398 return TRUE
; // include item
400 #endif // !_WIN32_WCE
403 class CFileDialog
: public CFileDialogImpl
<CFileDialog
>
406 CFileDialog(BOOL bOpenFileDialog
, // TRUE for FileOpen, FALSE for FileSaveAs
407 LPCTSTR lpszDefExt
= NULL
,
408 LPCTSTR lpszFileName
= NULL
,
409 DWORD dwFlags
= OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
,
410 LPCTSTR lpszFilter
= NULL
,
411 HWND hWndParent
= NULL
)
412 : CFileDialogImpl
<CFileDialog
>(bOpenFileDialog
, lpszDefExt
, lpszFileName
, dwFlags
, lpszFilter
, hWndParent
)
415 // override base class map and references to handlers
416 DECLARE_EMPTY_MSG_MAP()
419 #if defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
420 class CFileDialogEx
: public CFileDialogImpl
<CFileDialogEx
>
423 CFileDialogEx( // Supports only FileOpen
424 LPCTSTR lpszDefExt
= NULL
,
425 LPCTSTR lpszFileName
= NULL
,
426 DWORD dwFlags
= OFN_HIDEREADONLY
| OFN_OVERWRITEPROMPT
,
427 OFN_EXFLAG ExFlags
= OFN_EXFLAG_THUMBNAILVIEW
,
428 OFN_SORTORDER dwSortOrder
= OFN_SORTORDER_AUTO
,
429 LPCTSTR lpszFilter
= NULL
,
430 HWND hWndParent
= NULL
)
431 : CFileDialogImpl
<CFileDialogEx
>(TRUE
, lpszDefExt
, lpszFileName
, dwFlags
, lpszFilter
, hWndParent
)
433 m_ofn
.ExFlags
= ExFlags
;
434 m_ofn
.dwSortOrder
= dwSortOrder
;
437 // override base class map and references to handlers
438 DECLARE_EMPTY_MSG_MAP()
440 #endif // defined(__AYGSHELL_H__) && (_WIN32_WCE >= 0x0501)
443 ///////////////////////////////////////////////////////////////////////////////
444 // Multi File Dialog - Multi-select File Open dialog
448 // The class dynamically resizes the buffer as the file selection changes
449 // (as described in Knowledge Base article 131462). It also expands selected
450 // shortcut files to take into account the full path of the target file.
451 // Note that this doesn't work on Win9x for the old style dialogs, as well as
452 // on NT for non-Unicode builds.
454 #ifndef _WTL_FIXED_OFN_BUFFER_LENGTH
455 #define _WTL_FIXED_OFN_BUFFER_LENGTH 0x10000
459 class ATL_NO_VTABLE CMultiFileDialogImpl
: public CFileDialogImpl
< T
>
462 mutable LPCTSTR m_pNextFile
;
467 CMultiFileDialogImpl(
468 LPCTSTR lpszDefExt
= NULL
,
469 LPCTSTR lpszFileName
= NULL
,
470 DWORD dwFlags
= OFN_HIDEREADONLY
,
471 LPCTSTR lpszFilter
= NULL
,
472 HWND hWndParent
= NULL
)
473 : CFileDialogImpl
<T
>(TRUE
, lpszDefExt
, lpszFileName
, dwFlags
, lpszFilter
, hWndParent
),
476 m_ofn
.Flags
|= OFN_ALLOWMULTISELECT
; // Force multiple selection mode
479 OSVERSIONINFO ovi
= { sizeof(ovi
) };
480 ::GetVersionEx(&ovi
);
481 m_bIsNT
= (ovi
.dwPlatformId
== VER_PLATFORM_WIN32_NT
);
484 // On NT platforms, GetOpenFileNameA thunks to GetOpenFileNameW and there
485 // is absolutely nothing we can do except to start off with a large buffer.
486 ATLVERIFY(ResizeFilenameBuffer(_WTL_FIXED_OFN_BUFFER_LENGTH
));
491 ~CMultiFileDialogImpl()
493 if (m_ofn
.lpstrFile
!= m_szFileName
) // Free the buffer if we allocated it
494 delete[] m_ofn
.lpstrFile
;
498 // Get the directory that the files were chosen from.
499 // The function returns the number of characters copied, not including the terminating zero.
500 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
501 // If the function fails, the return value is zero.
502 int GetDirectory(LPTSTR pBuffer
, int nBufLen
) const
504 if (m_ofn
.lpstrFile
== NULL
)
507 LPCTSTR pStr
= m_ofn
.lpstrFile
;
508 int nLength
= lstrlen(pStr
);
509 if (pStr
[nLength
+ 1] == 0)
511 // The OFN buffer contains a single item so extract its path.
512 LPCTSTR pSep
= _strrchr(pStr
, _T('\\'));
514 nLength
= (int)(DWORD_PTR
)(pSep
- pStr
);
518 if (pBuffer
== NULL
) // If the buffer is NULL, return the required length
522 else if (nBufLen
> nLength
)
524 SecureHelper::strncpy_x(pBuffer
, nBufLen
, pStr
, nLength
);
531 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
532 bool GetDirectory(_CSTRING_NS::CString
& strDir
) const
536 int nLength
= GetDirectory(NULL
, 0);
539 bRet
= (GetDirectory(strDir
.GetBuffer(nLength
), nLength
) > 0);
540 strDir
.ReleaseBuffer(nLength
- 1);
545 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
547 // Get the first filename as a pointer into the buffer.
548 LPCTSTR
GetFirstFileName() const
550 if (m_ofn
.lpstrFile
== NULL
)
553 m_pNextFile
= NULL
; // Reset internal buffer pointer
555 LPCTSTR pStr
= m_ofn
.lpstrFile
;
556 int nLength
= lstrlen(pStr
);
557 if (pStr
[nLength
+ 1] != 0)
559 // Multiple items were selected. The first string is the directory,
560 // so skip forwards to the second string.
563 // Set up m_pNext so it points to the second item (or null).
569 // A single item was selected. Skip forward past the path.
570 LPCTSTR pSep
= _strrchr(pStr
, _T('\\'));
578 // Get the next filename as a pointer into the buffer.
579 LPCTSTR
GetNextFileName() const
581 if (m_pNextFile
== NULL
)
584 LPCTSTR pStr
= m_pNextFile
;
585 // Set "m_pNextFile" to point to the next file name, or null if we
586 // have reached the last file in the list.
587 int nLength
= lstrlen(pStr
);
588 m_pNextFile
= (pStr
[nLength
+ 1] != 0) ? &pStr
[nLength
+ 1] : NULL
;
593 // Get the first filename as a full path.
594 // The function returns the number of characters copied, not including the terminating zero.
595 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
596 // If the function fails, the return value is zero.
597 int GetFirstPathName(LPTSTR pBuffer
, int nBufLen
) const
599 LPCTSTR pStr
= GetFirstFileName();
600 int nLengthDir
= GetDirectory(NULL
, 0);
601 if((pStr
== NULL
) || (nLengthDir
== 0))
604 // Figure out the required length.
605 int nLengthTotal
= nLengthDir
+ lstrlen(pStr
);
608 if(pBuffer
== NULL
) // If the buffer is NULL, return the required length
610 nRet
= nLengthTotal
+ 1;
612 else if (nBufLen
> nLengthTotal
) // If the buffer is big enough, go ahead and construct the path
614 GetDirectory(pBuffer
, nBufLen
);
615 SecureHelper::strcat_x(pBuffer
, nBufLen
, _T("\\"));
616 SecureHelper::strcat_x(pBuffer
, nBufLen
, pStr
);
623 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
624 bool GetFirstPathName(_CSTRING_NS::CString
& strPath
) const
628 int nLength
= GetFirstPathName(NULL
, 0);
631 bRet
= (GetFirstPathName(strPath
.GetBuffer(nLength
), nLength
) > 0);
632 strPath
.ReleaseBuffer(nLength
- 1);
637 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
639 // Get the next filename as a full path.
640 // The function returns the number of characters copied, not including the terminating zero.
641 // If the buffer is NULL, the function returns the required size, in characters, including the terminating zero.
642 // If the function fails, the return value is zero.
643 // The internal position marker is moved forward only if the function succeeds and the buffer was large enough.
644 int GetNextPathName(LPTSTR pBuffer
, int nBufLen
) const
646 if (m_pNextFile
== NULL
)
650 LPCTSTR pStr
= m_pNextFile
;
651 // Does the filename contain a backslash?
652 if (_strrchr(pStr
, _T('\\')) != NULL
)
654 // Yes, so we'll assume it's a full path.
655 int nLength
= lstrlen(pStr
);
657 if (pBuffer
== NULL
) // If the buffer is NULL, return the required length
661 else if (nBufLen
> nLength
) // The buffer is big enough, so go ahead and copy the filename
663 SecureHelper::strcpy_x(pBuffer
, nBufLen
, GetNextFileName());
669 // The filename is relative, so construct the full path.
670 int nLengthDir
= GetDirectory(NULL
, 0);
673 // Calculate the required space.
674 int nLengthTotal
= nLengthDir
+ lstrlen(pStr
);
676 if(pBuffer
== NULL
) // If the buffer is NULL, return the required length
678 nRet
= nLengthTotal
+ 1;
680 else if (nBufLen
> nLengthTotal
) // If the buffer is big enough, go ahead and construct the path
682 GetDirectory(pBuffer
, nBufLen
);
683 SecureHelper::strcat_x(pBuffer
, nBufLen
, _T("\\"));
684 SecureHelper::strcat_x(pBuffer
, nBufLen
, GetNextFileName());
693 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
694 bool GetNextPathName(_CSTRING_NS::CString
& strPath
) const
698 int nLength
= GetNextPathName(NULL
, 0);
701 bRet
= (GetNextPathName(strPath
.GetBuffer(nLength
), nLength
) > 0);
702 strPath
.ReleaseBuffer(nLength
- 1);
707 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
710 bool ResizeFilenameBuffer(DWORD dwLength
)
712 if (dwLength
> m_ofn
.nMaxFile
)
714 // Free the old buffer.
715 if (m_ofn
.lpstrFile
!= m_szFileName
)
717 delete[] m_ofn
.lpstrFile
;
718 m_ofn
.lpstrFile
= NULL
;
722 // Allocate the new buffer.
723 LPTSTR lpstrBuff
= NULL
;
724 ATLTRY(lpstrBuff
= new TCHAR
[dwLength
]);
725 if (lpstrBuff
!= NULL
)
727 m_ofn
.lpstrFile
= lpstrBuff
;
728 m_ofn
.lpstrFile
[0] = 0;
729 m_ofn
.nMaxFile
= dwLength
;
733 return (m_ofn
.lpstrFile
!= NULL
);
736 void OnSelChange(LPOFNOTIFY
/*lpon*/)
739 // There is no point resizing the buffer in ANSI builds running on NT.
744 // Get the buffer length required to hold the spec.
745 int nLength
= GetSpec(NULL
, 0);
747 return; // no files are selected, presumably
749 // Add room for the directory, and an extra terminating zero.
750 nLength
+= GetFolderPath(NULL
, 0) + 1;
752 if (!ResizeFilenameBuffer(nLength
))
758 // If we are not following links then our work is done.
759 if ((m_ofn
.Flags
& OFN_NODEREFERENCELINKS
) != 0)
762 // Get the file spec, which is the text in the edit control.
763 if (GetSpec(m_ofn
.lpstrFile
, m_ofn
.nMaxFile
) <= 0)
766 // Get the ID-list of the current folder.
767 int nBytes
= GetFolderIDList(NULL
, 0);
768 CTempBuffer
<ITEMIDLIST
> idlist
;
769 idlist
.AllocateBytes(nBytes
);
770 if ((nBytes
<= 0) || (GetFolderIDList(idlist
, nBytes
) <= 0))
773 // First bind to the desktop folder, then to the current folder.
774 ATL::CComPtr
<IShellFolder
> pDesktop
, pFolder
;
775 if (FAILED(::SHGetDesktopFolder(&pDesktop
)))
777 if (FAILED(pDesktop
->BindToObject(idlist
, NULL
, IID_IShellFolder
, (void**)&pFolder
)))
780 // Work through the file spec, looking for quoted filenames. If we find a shortcut file, then
781 // we need to add enough extra buffer space to hold its target path.
782 DWORD nExtraChars
= 0;
783 bool bInsideQuotes
= false;
784 LPCTSTR pAnchor
= m_ofn
.lpstrFile
;
785 LPCTSTR pChar
= m_ofn
.lpstrFile
;
786 for ( ; *pChar
; ++pChar
)
788 // Look for quotation marks.
789 if (*pChar
== _T('\"'))
791 // We are either entering or leaving a passage of quoted text.
792 bInsideQuotes
= !bInsideQuotes
;
794 // Is it an opening or closing quote?
797 // We found an opening quote, so set "pAnchor" to the following character.
800 else // closing quote
802 // Each quoted entity should be shorter than MAX_PATH.
803 if (pChar
- pAnchor
>= MAX_PATH
)
806 // Get the ID-list and attributes of the file.
808 int nFileNameLength
= (int)(DWORD_PTR
)(pChar
- pAnchor
);
809 TCHAR szFileName
[MAX_PATH
];
810 SecureHelper::strncpy_x(szFileName
, MAX_PATH
, pAnchor
, nFileNameLength
);
811 LPITEMIDLIST pidl
= NULL
;
812 DWORD dwAttrib
= SFGAO_LINK
;
813 if (SUCCEEDED(pFolder
->ParseDisplayName(NULL
, NULL
, T2W(szFileName
), NULL
, &pidl
, &dwAttrib
)))
815 // Is it a shortcut file?
816 if (dwAttrib
& SFGAO_LINK
)
818 // Bind to its IShellLink interface.
819 ATL::CComPtr
<IShellLink
> pLink
;
820 if (SUCCEEDED(pFolder
->BindToObject(pidl
, NULL
, IID_IShellLink
, (void**)&pLink
)))
822 // Get the shortcut's target path.
823 TCHAR szPath
[MAX_PATH
];
824 if (SUCCEEDED(pLink
->GetPath(szPath
, MAX_PATH
, NULL
, 0)))
826 // If the target path is longer than the shortcut name, then add on the number
827 // of extra characters that are required.
828 int nNewLength
= lstrlen(szPath
);
829 if (nNewLength
> nFileNameLength
)
830 nExtraChars
+= nNewLength
- nFileNameLength
;
835 // Free the ID-list returned by ParseDisplayName.
836 ::CoTaskMemFree(pidl
);
842 // If we need more space for shortcut targets, then reallocate.
844 ATLVERIFY(ResizeFilenameBuffer(m_ofn
.nMaxFile
+ nExtraChars
));
847 // Helper for _ATM_MIN_CRT
848 static const TCHAR
* _strrchr(const TCHAR
* p
, TCHAR ch
)
851 return _tcsrchr(p
, ch
);
852 #else // _ATL_MIN_CRT
853 const TCHAR
* lpsz
= NULL
;
861 #endif // _ATL_MIN_CRT
865 class CMultiFileDialog
: public CMultiFileDialogImpl
<CMultiFileDialog
>
869 LPCTSTR lpszDefExt
= NULL
,
870 LPCTSTR lpszFileName
= NULL
,
871 DWORD dwFlags
= OFN_HIDEREADONLY
,
872 LPCTSTR lpszFilter
= NULL
,
873 HWND hWndParent
= NULL
)
874 : CMultiFileDialogImpl
<CMultiFileDialog
>(lpszDefExt
, lpszFileName
, dwFlags
, lpszFilter
, hWndParent
)
877 BEGIN_MSG_MAP(CMultiFileDialog
)
878 CHAIN_MSG_MAP(CMultiFileDialogImpl
<CMultiFileDialog
>)
882 #endif // !_WIN32_WCE
885 ///////////////////////////////////////////////////////////////////////////////
886 // Shell File Dialog - new Shell File Open and Save dialogs in Vista
888 // Note: Use GetPtr() to access dialog interface methods.
890 // CShellFileOpenDialog dlg;
891 // dlg.GetPtr()->SetTitle(L"MyFileOpenDialog");
893 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
895 ///////////////////////////////////////////////////////////////////////////////
896 // CShellFileDialogImpl - base class for CShellFileOpenDialogImpl and CShellFileSaveDialogImpl
899 class ATL_NO_VTABLE CShellFileDialogImpl
: public IFileDialogEvents
903 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
907 T
* pT
= static_cast<T
*>(this);
908 if(pT
->m_spFileDlg
== NULL
)
915 pT
->_Advise(dwCookie
);
917 HRESULT hRet
= pT
->m_spFileDlg
->Show(hWndParent
);
920 else if(hRet
== HRESULT_FROM_WIN32(ERROR_CANCELLED
))
923 ATLASSERT(FALSE
); // error
925 pT
->_Unadvise(dwCookie
);
932 const T
* pT
= static_cast<const T
*>(this);
933 return (pT
->m_spFileDlg
== NULL
);
936 // Operations - get file path after dialog returns
937 HRESULT
GetFilePath(LPWSTR lpstrFilePath
, int cchLength
)
939 T
* pT
= static_cast<T
*>(this);
940 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
942 ATL::CComPtr
<IShellItem
> spItem
;
943 HRESULT hRet
= pT
->m_spFileDlg
->GetResult(&spItem
);
946 hRet
= GetFileNameFromShellItem(spItem
, SIGDN_FILESYSPATH
, lpstrFilePath
, cchLength
);
951 HRESULT
GetFileTitle(LPWSTR lpstrFileTitle
, int cchLength
)
953 T
* pT
= static_cast<T
*>(this);
954 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
956 ATL::CComPtr
<IShellItem
> spItem
;
957 HRESULT hRet
= pT
->m_spFileDlg
->GetResult(&spItem
);
960 hRet
= GetFileNameFromShellItem(spItem
, SIGDN_NORMALDISPLAY
, lpstrFileTitle
, cchLength
);
965 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
966 HRESULT
GetFilePath(_CSTRING_NS::CString
& strFilePath
)
968 T
* pT
= static_cast<T
*>(this);
969 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
971 ATL::CComPtr
<IShellItem
> spItem
;
972 HRESULT hRet
= pT
->m_spFileDlg
->GetResult(&spItem
);
975 hRet
= GetFileNameFromShellItem(spItem
, SIGDN_FILESYSPATH
, strFilePath
);
980 HRESULT
GetFileTitle(_CSTRING_NS::CString
& strFileTitle
)
982 T
* pT
= static_cast<T
*>(this);
983 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
985 ATL::CComPtr
<IShellItem
> spItem
;
986 HRESULT hRet
= pT
->m_spFileDlg
->GetResult(&spItem
);
989 hRet
= GetFileNameFromShellItem(spItem
, SIGDN_NORMALDISPLAY
, strFileTitle
);
993 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
995 // Helpers for IShellItem
996 static HRESULT
GetFileNameFromShellItem(IShellItem
* pShellItem
, SIGDN type
, LPWSTR lpstr
, int cchLength
)
998 ATLASSERT(pShellItem
!= NULL
);
1000 LPWSTR lpstrName
= NULL
;
1001 HRESULT hRet
= pShellItem
->GetDisplayName(type
, &lpstrName
);
1005 if(lstrlenW(lpstrName
) < cchLength
)
1007 SecureHelper::strcpyW_x(lpstr
, cchLength
, lpstrName
);
1012 hRet
= DISP_E_BUFFERTOOSMALL
;
1015 ::CoTaskMemFree(lpstrName
);
1021 #if defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
1022 static HRESULT
GetFileNameFromShellItem(IShellItem
* pShellItem
, SIGDN type
, _CSTRING_NS::CString
& str
)
1024 ATLASSERT(pShellItem
!= NULL
);
1026 LPWSTR lpstrName
= NULL
;
1027 HRESULT hRet
= pShellItem
->GetDisplayName(type
, &lpstrName
);
1032 ::CoTaskMemFree(lpstrName
);
1037 #endif // defined(_WTL_USE_CSTRING) || defined(__ATLSTR_H__)
1040 void _Advise(DWORD
& dwCookie
)
1042 T
* pT
= static_cast<T
*>(this);
1043 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
1044 HRESULT hRet
= pT
->m_spFileDlg
->Advise((IFileDialogEvents
*)this, &dwCookie
);
1045 ATLVERIFY(SUCCEEDED(hRet
));
1048 void _Unadvise(DWORD dwCookie
)
1050 T
* pT
= static_cast<T
*>(this);
1051 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
1052 HRESULT hRet
= pT
->m_spFileDlg
->Unadvise(dwCookie
);
1053 ATLVERIFY(SUCCEEDED(hRet
));
1056 void _Init(LPCWSTR lpszFileName
, DWORD dwOptions
, LPCWSTR lpszDefExt
, const COMDLG_FILTERSPEC
* arrFilterSpec
, UINT uFilterSpecCount
)
1058 T
* pT
= static_cast<T
*>(this);
1059 ATLASSERT(pT
->m_spFileDlg
!= NULL
);
1061 HRESULT hRet
= E_FAIL
;
1063 if(lpszFileName
!= NULL
)
1065 hRet
= pT
->m_spFileDlg
->SetFileName(lpszFileName
);
1066 ATLASSERT(SUCCEEDED(hRet
));
1069 hRet
= pT
->m_spFileDlg
->SetOptions(dwOptions
);
1070 ATLASSERT(SUCCEEDED(hRet
));
1072 if(lpszDefExt
!= NULL
)
1074 hRet
= pT
->m_spFileDlg
->SetDefaultExtension(lpszDefExt
);
1075 ATLASSERT(SUCCEEDED(hRet
));
1078 if(arrFilterSpec
!= NULL
&& uFilterSpecCount
!= 0U)
1080 hRet
= pT
->m_spFileDlg
->SetFileTypes(uFilterSpecCount
, arrFilterSpec
);
1081 ATLASSERT(SUCCEEDED(hRet
));
1085 // Implementation - IUnknown interface
1086 STDMETHOD(QueryInterface
)(REFIID riid
, void** ppvObject
)
1088 if(ppvObject
== NULL
)
1091 T
* pT
= static_cast<T
*>(this);
1092 if(IsEqualGUID(riid
, IID_IUnknown
) || IsEqualGUID(riid
, IID_IFileDialogEvents
))
1094 *ppvObject
= (IFileDialogEvents
*)pT
;
1095 // AddRef() not needed
1099 return E_NOINTERFACE
;
1102 virtual ULONG STDMETHODCALLTYPE
AddRef()
1107 virtual ULONG STDMETHODCALLTYPE
Release()
1112 // Implementation - IFileDialogEvents interface
1113 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnFileOk(IFileDialog
* pfd
)
1115 T
* pT
= static_cast<T
*>(this);
1116 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1117 pfd
; // avoid level 4 warning
1118 return pT
->OnFileOk();
1121 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnFolderChanging(IFileDialog
* pfd
, IShellItem
* psiFolder
)
1123 T
* pT
= static_cast<T
*>(this);
1124 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1125 pfd
; // avoid level 4 warning
1126 return pT
->OnFolderChanging(psiFolder
);
1129 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnFolderChange(IFileDialog
* pfd
)
1131 T
* pT
= static_cast<T
*>(this);
1132 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1133 pfd
; // avoid level 4 warning
1134 return pT
->OnFolderChange();
1137 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnSelectionChange(IFileDialog
* pfd
)
1139 T
* pT
= static_cast<T
*>(this);
1140 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1141 pfd
; // avoid level 4 warning
1142 return pT
->OnSelectionChange();
1145 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnShareViolation(IFileDialog
* pfd
, IShellItem
* psi
, FDE_SHAREVIOLATION_RESPONSE
* pResponse
)
1147 T
* pT
= static_cast<T
*>(this);
1148 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1149 pfd
; // avoid level 4 warning
1150 return pT
->OnShareViolation(psi
, pResponse
);
1153 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnTypeChange(IFileDialog
* pfd
)
1155 T
* pT
= static_cast<T
*>(this);
1156 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1157 pfd
; // avoid level 4 warning
1158 return pT
->OnTypeChange();
1161 virtual HRESULT STDMETHODCALLTYPE
IFileDialogEvents::OnOverwrite(IFileDialog
* pfd
, IShellItem
* psi
, FDE_OVERWRITE_RESPONSE
* pResponse
)
1163 T
* pT
= static_cast<T
*>(this);
1164 ATLASSERT(pT
->m_spFileDlg
.IsEqualObject(pfd
));
1165 pfd
; // avoid level 4 warning
1166 return pT
->OnOverwrite(psi
, pResponse
);
1169 // Overrideables - Event handlers
1175 HRESULT
OnFolderChanging(IShellItem
* /*psiFolder*/)
1180 HRESULT
OnFolderChange()
1185 HRESULT
OnSelectionChange()
1190 HRESULT
OnShareViolation(IShellItem
* /*psi*/, FDE_SHAREVIOLATION_RESPONSE
* /*pResponse*/)
1195 HRESULT
OnTypeChange()
1200 HRESULT
OnOverwrite(IShellItem
* /*psi*/, FDE_OVERWRITE_RESPONSE
* /*pResponse*/)
1207 ///////////////////////////////////////////////////////////////////////////////
1208 // CShellFileOpenDialogImpl - implements new Shell File Open dialog
1211 class ATL_NO_VTABLE CShellFileOpenDialogImpl
: public CShellFileDialogImpl
< T
>
1214 ATL::CComPtr
<IFileOpenDialog
> m_spFileDlg
;
1216 CShellFileOpenDialogImpl(LPCWSTR lpszFileName
= NULL
,
1217 DWORD dwOptions
= FOS_FORCEFILESYSTEM
| FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
,
1218 LPCWSTR lpszDefExt
= NULL
,
1219 const COMDLG_FILTERSPEC
* arrFilterSpec
= NULL
,
1220 UINT uFilterSpecCount
= 0U)
1222 HRESULT hRet
= m_spFileDlg
.CoCreateInstance(CLSID_FileOpenDialog
);
1225 _Init(lpszFileName
, dwOptions
, lpszDefExt
, arrFilterSpec
, uFilterSpecCount
);
1228 IFileOpenDialog
* GetPtr()
1235 ///////////////////////////////////////////////////////////////////////////////
1236 // CShellFileOpenDialog - new Shell File Open dialog without events
1238 class CShellFileOpenDialog
: public CShellFileOpenDialogImpl
<CShellFileOpenDialog
>
1241 CShellFileOpenDialog(LPCWSTR lpszFileName
= NULL
,
1242 DWORD dwOptions
= FOS_FORCEFILESYSTEM
| FOS_PATHMUSTEXIST
| FOS_FILEMUSTEXIST
,
1243 LPCWSTR lpszDefExt
= NULL
,
1244 const COMDLG_FILTERSPEC
* arrFilterSpec
= NULL
,
1245 UINT uFilterSpecCount
= 0U) : CShellFileOpenDialogImpl
<CShellFileOpenDialog
>(lpszFileName
, dwOptions
, lpszDefExt
, arrFilterSpec
, uFilterSpecCount
)
1248 // Implementation (remove _Advise/_Unadvise code using template magic)
1249 void _Advise(DWORD
& /*dwCookie*/)
1252 void _Unadvise(DWORD
/*dwCookie*/)
1257 ///////////////////////////////////////////////////////////////////////////////
1258 // CShellFileSaveDialogImpl - implements new Shell File Save dialog
1261 class ATL_NO_VTABLE CShellFileSaveDialogImpl
: public CShellFileDialogImpl
< T
>
1264 ATL::CComPtr
<IFileSaveDialog
> m_spFileDlg
;
1266 CShellFileSaveDialogImpl(LPCWSTR lpszFileName
= NULL
,
1267 DWORD dwOptions
= FOS_FORCEFILESYSTEM
| FOS_PATHMUSTEXIST
| FOS_OVERWRITEPROMPT
,
1268 LPCWSTR lpszDefExt
= NULL
,
1269 const COMDLG_FILTERSPEC
* arrFilterSpec
= NULL
,
1270 UINT uFilterSpecCount
= 0U)
1272 HRESULT hRet
= m_spFileDlg
.CoCreateInstance(CLSID_FileSaveDialog
);
1275 _Init(lpszFileName
, dwOptions
, lpszDefExt
, arrFilterSpec
, uFilterSpecCount
);
1278 IFileSaveDialog
* GetPtr()
1285 ///////////////////////////////////////////////////////////////////////////////
1286 // CShellFileSaveDialog - new Shell File Save dialog without events
1288 class CShellFileSaveDialog
: public CShellFileSaveDialogImpl
<CShellFileSaveDialog
>
1291 CShellFileSaveDialog(LPCWSTR lpszFileName
= NULL
,
1292 DWORD dwOptions
= FOS_FORCEFILESYSTEM
| FOS_PATHMUSTEXIST
| FOS_OVERWRITEPROMPT
,
1293 LPCWSTR lpszDefExt
= NULL
,
1294 const COMDLG_FILTERSPEC
* arrFilterSpec
= NULL
,
1295 UINT uFilterSpecCount
= 0U) : CShellFileSaveDialogImpl
<CShellFileSaveDialog
>(lpszFileName
, dwOptions
, lpszDefExt
, arrFilterSpec
, uFilterSpecCount
)
1298 // Implementation (remove _Advise/_Unadvise code using template magic)
1299 void _Advise(DWORD
& /*dwCookie*/)
1302 void _Unadvise(DWORD
/*dwCookie*/)
1306 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
1309 ///////////////////////////////////////////////////////////////////////////////
1310 // CFolderDialogImpl - used for browsing for a folder
1315 class ATL_NO_VTABLE CFolderDialogImpl
1319 LPCTSTR m_lpstrInitialFolder
;
1320 LPCITEMIDLIST m_pidlInitialSelection
;
1321 bool m_bExpandInitialSelection
;
1322 TCHAR m_szFolderDisplayName
[MAX_PATH
];
1323 TCHAR m_szFolderPath
[MAX_PATH
];
1324 LPITEMIDLIST m_pidlSelected
;
1325 HWND m_hWnd
; // used only in the callback function
1328 CFolderDialogImpl(HWND hWndParent
= NULL
, LPCTSTR lpstrTitle
= NULL
, UINT uFlags
= BIF_RETURNONLYFSDIRS
) :
1329 m_lpstrInitialFolder(NULL
), m_pidlInitialSelection(NULL
), m_bExpandInitialSelection(false), m_pidlSelected(NULL
), m_hWnd(NULL
)
1331 memset(&m_bi
, 0, sizeof(m_bi
)); // initialize structure to 0/NULL
1333 m_bi
.hwndOwner
= hWndParent
;
1334 m_bi
.pidlRoot
= NULL
;
1335 m_bi
.pszDisplayName
= m_szFolderDisplayName
;
1336 m_bi
.lpszTitle
= lpstrTitle
;
1337 m_bi
.ulFlags
= uFlags
;
1338 m_bi
.lpfn
= BrowseCallbackProc
;
1339 m_bi
.lParam
= (LPARAM
)static_cast<T
*>(this);
1341 m_szFolderPath
[0] = 0;
1342 m_szFolderDisplayName
[0] = 0;
1345 ~CFolderDialogImpl()
1347 ::CoTaskMemFree(m_pidlSelected
);
1351 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
1353 if(m_bi
.hwndOwner
== NULL
) // set only if not specified before
1354 m_bi
.hwndOwner
= hWndParent
;
1356 // Clear out any previous results
1357 m_szFolderPath
[0] = 0;
1358 m_szFolderDisplayName
[0] = 0;
1359 ::CoTaskMemFree(m_pidlSelected
);
1361 INT_PTR nRet
= IDCANCEL
;
1362 m_pidlSelected
= ::SHBrowseForFolder(&m_bi
);
1364 if(m_pidlSelected
!= NULL
)
1368 // If BIF_RETURNONLYFSDIRS is set, we try to get the filesystem path.
1369 // Otherwise, the caller must handle the ID-list directly.
1370 if((m_bi
.ulFlags
& BIF_RETURNONLYFSDIRS
) != 0)
1372 if(::SHGetPathFromIDList(m_pidlSelected
, m_szFolderPath
) == FALSE
)
1380 // Methods to call before DoModal
1381 void SetInitialFolder(LPCTSTR lpstrInitialFolder
, bool bExpand
= true)
1383 // lpstrInitialFolder may be a file if BIF_BROWSEINCLUDEFILES is specified
1384 m_lpstrInitialFolder
= lpstrInitialFolder
;
1385 m_bExpandInitialSelection
= bExpand
;
1388 void SetInitialSelection(LPCITEMIDLIST pidl
, bool bExpand
= true)
1390 m_pidlInitialSelection
= pidl
;
1391 m_bExpandInitialSelection
= bExpand
;
1394 // Methods to call after DoModal
1395 LPITEMIDLIST
GetSelectedItem(bool bDetach
= false)
1397 LPITEMIDLIST pidl
= m_pidlSelected
;
1399 m_pidlSelected
= NULL
;
1404 LPCTSTR
GetFolderPath() const
1406 return m_szFolderPath
;
1409 LPCTSTR
GetFolderDisplayName() const
1411 return m_szFolderDisplayName
;
1414 int GetFolderImageIndex() const
1419 // Callback function and overrideables
1420 static int CALLBACK
BrowseCallbackProc(HWND hWnd
, UINT uMsg
, LPARAM lParam
, LPARAM lpData
)
1422 #ifndef BFFM_VALIDATEFAILED
1424 const int BFFM_VALIDATEFAILED
= 4;
1426 const int BFFM_VALIDATEFAILED
= 3;
1428 #endif // !BFFM_VALIDATEFAILED
1429 #ifndef BFFM_IUNKNOWN
1430 const int BFFM_IUNKNOWN
= 5;
1431 #endif // !BFFM_IUNKNOWN
1432 #ifndef BIF_NEWDIALOGSTYLE
1433 const UINT BIF_NEWDIALOGSTYLE
= 0x0040;
1434 #endif // !BIF_NEWDIALOGSTYLE
1438 bool bClear
= false;
1439 if(pT
->m_hWnd
== NULL
)
1446 ATLASSERT(pT
->m_hWnd
== hWnd
);
1451 case BFFM_INITIALIZED
:
1452 // Set initial selection
1453 // Note that m_pidlInitialSelection, if set, takes precedence over m_lpstrInitialFolder
1454 if(pT
->m_pidlInitialSelection
!= NULL
)
1455 pT
->SetSelection(pT
->m_pidlInitialSelection
);
1456 else if(pT
->m_lpstrInitialFolder
!= NULL
)
1457 pT
->SetSelection(pT
->m_lpstrInitialFolder
);
1459 // Expand initial selection if appropriate
1460 if(pT
->m_bExpandInitialSelection
&& ((pT
->m_bi
.ulFlags
& BIF_NEWDIALOGSTYLE
) != 0))
1462 if(pT
->m_pidlInitialSelection
!= NULL
)
1463 pT
->SetExpanded(pT
->m_pidlInitialSelection
);
1464 else if(pT
->m_lpstrInitialFolder
!= NULL
)
1465 pT
->SetExpanded(pT
->m_lpstrInitialFolder
);
1467 pT
->OnInitialized();
1469 case BFFM_SELCHANGED
:
1470 pT
->OnSelChanged((LPITEMIDLIST
)lParam
);
1472 case BFFM_VALIDATEFAILED
:
1473 nRet
= pT
->OnValidateFailed((LPCTSTR
)lParam
);
1476 pT
->OnIUnknown((IUnknown
*)lParam
);
1479 ATLTRACE2(atlTraceUI
, 0, _T("Unknown message received in CFolderDialogImpl::BrowseCallbackProc\n"));
1488 void OnInitialized()
1492 void OnSelChanged(LPITEMIDLIST
/*pItemIDList*/)
1496 int OnValidateFailed(LPCTSTR
/*lpstrFolderPath*/)
1498 return 1; // 1=continue, 0=EndDialog
1501 void OnIUnknown(IUnknown
* /*pUnknown*/)
1505 // Commands - valid to call only from handlers
1506 void EnableOK(BOOL bEnable
)
1508 ATLASSERT(m_hWnd
!= NULL
);
1509 ::SendMessage(m_hWnd
, BFFM_ENABLEOK
, 0, bEnable
);
1512 void SetSelection(LPCITEMIDLIST pItemIDList
)
1514 ATLASSERT(m_hWnd
!= NULL
);
1515 ::SendMessage(m_hWnd
, BFFM_SETSELECTION
, FALSE
, (LPARAM
)pItemIDList
);
1518 void SetSelection(LPCTSTR lpstrFolderPath
)
1520 ATLASSERT(m_hWnd
!= NULL
);
1521 ::SendMessage(m_hWnd
, BFFM_SETSELECTION
, TRUE
, (LPARAM
)lpstrFolderPath
);
1524 void SetStatusText(LPCTSTR lpstrText
)
1526 ATLASSERT(m_hWnd
!= NULL
);
1527 ::SendMessage(m_hWnd
, BFFM_SETSTATUSTEXT
, 0, (LPARAM
)lpstrText
);
1530 void SetOKText(LPCTSTR lpstrOKText
)
1532 #ifndef BFFM_SETOKTEXT
1533 const UINT BFFM_SETOKTEXT
= WM_USER
+ 105;
1535 ATLASSERT(m_hWnd
!= NULL
);
1537 LPCWSTR lpstr
= T2CW(lpstrOKText
);
1538 ::SendMessage(m_hWnd
, BFFM_SETOKTEXT
, (WPARAM
)lpstr
, 0L);
1541 void SetExpanded(LPCITEMIDLIST pItemIDList
)
1543 #ifndef BFFM_SETEXPANDED
1544 const UINT BFFM_SETEXPANDED
= WM_USER
+ 106;
1546 ATLASSERT(m_hWnd
!= NULL
);
1547 ::SendMessage(m_hWnd
, BFFM_SETEXPANDED
, FALSE
, (LPARAM
)pItemIDList
);
1550 void SetExpanded(LPCTSTR lpstrFolderPath
)
1552 #ifndef BFFM_SETEXPANDED
1553 const UINT BFFM_SETEXPANDED
= WM_USER
+ 106;
1555 ATLASSERT(m_hWnd
!= NULL
);
1557 LPCWSTR lpstr
= T2CW(lpstrFolderPath
);
1558 ::SendMessage(m_hWnd
, BFFM_SETEXPANDED
, TRUE
, (LPARAM
)lpstr
);
1562 class CFolderDialog
: public CFolderDialogImpl
<CFolderDialog
>
1565 CFolderDialog(HWND hWndParent
= NULL
, LPCTSTR lpstrTitle
= NULL
, UINT uFlags
= BIF_RETURNONLYFSDIRS
)
1566 : CFolderDialogImpl
<CFolderDialog
>(hWndParent
, lpstrTitle
, uFlags
)
1570 #endif // !_WIN32_WCE
1573 ///////////////////////////////////////////////////////////////////////////////
1574 // CCommonDialogImplBase - base class for common dialog classes
1576 class ATL_NO_VTABLE CCommonDialogImplBase
: public ATL::CWindowImplBase
1579 static UINT_PTR APIENTRY
HookProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
1581 if(uMsg
!= WM_INITDIALOG
)
1583 CCommonDialogImplBase
* pT
= (CCommonDialogImplBase
*)ModuleHelper::ExtractCreateWndData();
1584 ATLASSERT(pT
!= NULL
);
1585 ATLASSERT(pT
->m_hWnd
== NULL
);
1586 ATLASSERT(::IsWindow(hWnd
));
1587 // subclass dialog's window
1588 if(!pT
->SubclassWindow(hWnd
))
1590 ATLTRACE2(atlTraceUI
, 0, _T("Subclassing a common dialog failed\n"));
1593 // check message map for WM_INITDIALOG handler
1595 if(pT
->ProcessWindowMessage(pT
->m_hWnd
, uMsg
, wParam
, lParam
, lRes
, 0) == FALSE
)
1600 // Special override for common dialogs
1601 BOOL
EndDialog(INT_PTR
/*nRetCode*/ = 0)
1603 ATLASSERT(::IsWindow(m_hWnd
));
1604 SendMessage(WM_COMMAND
, MAKEWPARAM(IDABORT
, 0));
1608 // Implementation - try to override these, to prevent errors
1609 HWND
Create(HWND
, ATL::_U_RECT
, LPCTSTR
, DWORD
, DWORD
, ATL::_U_MENUorID
, ATOM
, LPVOID
)
1611 ATLASSERT(FALSE
); // should not be called
1615 static LRESULT CALLBACK
StartWindowProc(HWND
/*hWnd*/, UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/)
1617 ATLASSERT(FALSE
); // should not be called
1623 ///////////////////////////////////////////////////////////////////////////////
1624 // CFontDialogImpl - font selection dialog
1629 class ATL_NO_VTABLE CFontDialogImpl
: public CCommonDialogImplBase
1632 enum { _cchStyleName
= 64 };
1635 TCHAR m_szStyleName
[_cchStyleName
]; // contains style name after return
1636 LOGFONT m_lf
; // default LOGFONT to store the info
1639 CFontDialogImpl(LPLOGFONT lplfInitial
= NULL
,
1640 DWORD dwFlags
= CF_EFFECTS
| CF_SCREENFONTS
,
1641 HDC hDCPrinter
= NULL
,
1642 HWND hWndParent
= NULL
)
1644 memset(&m_cf
, 0, sizeof(m_cf
));
1645 memset(&m_lf
, 0, sizeof(m_lf
));
1646 memset(&m_szStyleName
, 0, sizeof(m_szStyleName
));
1648 m_cf
.lStructSize
= sizeof(m_cf
);
1649 m_cf
.hwndOwner
= hWndParent
;
1650 m_cf
.rgbColors
= RGB(0, 0, 0);
1651 m_cf
.lpszStyle
= (LPTSTR
)&m_szStyleName
;
1652 m_cf
.Flags
= dwFlags
| CF_ENABLEHOOK
;
1653 m_cf
.lpfnHook
= (LPCFHOOKPROC
)T::HookProc
;
1655 if(lplfInitial
!= NULL
)
1657 m_cf
.lpLogFont
= lplfInitial
;
1658 m_cf
.Flags
|= CF_INITTOLOGFONTSTRUCT
;
1659 m_lf
= *lplfInitial
;
1663 m_cf
.lpLogFont
= &m_lf
;
1666 if(hDCPrinter
!= NULL
)
1668 m_cf
.hDC
= hDCPrinter
;
1669 m_cf
.Flags
|= CF_PRINTERFONTS
;
1674 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
1676 ATLASSERT((m_cf
.Flags
& CF_ENABLEHOOK
) != 0);
1677 ATLASSERT(m_cf
.lpfnHook
!= NULL
); // can still be a user hook
1679 if(m_cf
.hwndOwner
== NULL
) // set only if not specified before
1680 m_cf
.hwndOwner
= hWndParent
;
1682 ATLASSERT(m_hWnd
== NULL
);
1683 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (CCommonDialogImplBase
*)this);
1685 BOOL bRet
= ::ChooseFont(&m_cf
);
1689 if(bRet
) // copy logical font from user's initialization buffer (if needed)
1690 SecureHelper::memcpy_x(&m_lf
, sizeof(m_lf
), m_cf
.lpLogFont
, sizeof(m_lf
));
1692 return bRet
? IDOK
: IDCANCEL
;
1695 // works only when the dialog is dislayed or after
1696 void GetCurrentFont(LPLOGFONT lplf
) const
1698 ATLASSERT(lplf
!= NULL
);
1701 ::SendMessage(m_hWnd
, WM_CHOOSEFONT_GETLOGFONT
, 0, (LPARAM
)lplf
);
1706 // works only when the dialog is dislayed or before
1708 void SetLogFont(LPLOGFONT lplf
)
1710 ATLASSERT(lplf
!= NULL
);
1711 #ifndef WM_CHOOSEFONT_SETLOGFONT
1712 const UINT WM_CHOOSEFONT_SETLOGFONT
= (WM_USER
+ 101);
1716 ::SendMessage(m_hWnd
, WM_CHOOSEFONT_SETLOGFONT
, 0, (LPARAM
)lplf
);
1721 m_cf
.Flags
|= CF_INITTOLOGFONTSTRUCT
;
1725 void SetFlags(DWORD dwFlags
)
1727 #ifndef WM_CHOOSEFONT_SETFLAGS
1728 const UINT WM_CHOOSEFONT_SETFLAGS
= (WM_USER
+ 102);
1732 CHOOSEFONT cf
= { sizeof(CHOOSEFONT
) };
1734 ::SendMessage(m_hWnd
, WM_CHOOSEFONT_SETFLAGS
, 0, (LPARAM
)&cf
);
1738 m_cf
.Flags
= dwFlags
;
1741 #endif // !_WIN32_WCE
1743 // Helpers for parsing information after successful return
1744 LPCTSTR
GetFaceName() const // return the face name of the font
1746 return (LPCTSTR
)m_cf
.lpLogFont
->lfFaceName
;
1749 LPCTSTR
GetStyleName() const // return the style name of the font
1751 return m_cf
.lpszStyle
;
1754 int GetSize() const // return the pt size of the font
1756 return m_cf
.iPointSize
;
1759 COLORREF
GetColor() const // return the color of the font
1761 return m_cf
.rgbColors
;
1764 int GetWeight() const // return the chosen font weight
1766 return (int)m_cf
.lpLogFont
->lfWeight
;
1769 BOOL
IsStrikeOut() const // return TRUE if strikeout
1771 return (m_cf
.lpLogFont
->lfStrikeOut
) ? TRUE
: FALSE
;
1774 BOOL
IsUnderline() const // return TRUE if underline
1776 return (m_cf
.lpLogFont
->lfUnderline
) ? TRUE
: FALSE
;
1779 BOOL
IsBold() const // return TRUE if bold font
1781 return (m_cf
.lpLogFont
->lfWeight
== FW_BOLD
) ? TRUE
: FALSE
;
1784 BOOL
IsItalic() const // return TRUE if italic font
1786 return m_cf
.lpLogFont
->lfItalic
? TRUE
: FALSE
;
1790 class CFontDialog
: public CFontDialogImpl
<CFontDialog
>
1793 CFontDialog(LPLOGFONT lplfInitial
= NULL
,
1794 DWORD dwFlags
= CF_EFFECTS
| CF_SCREENFONTS
,
1795 HDC hDCPrinter
= NULL
,
1796 HWND hWndParent
= NULL
)
1797 : CFontDialogImpl
<CFontDialog
>(lplfInitial
, dwFlags
, hDCPrinter
, hWndParent
)
1800 DECLARE_EMPTY_MSG_MAP()
1803 #endif // _WIN32_WCE
1806 ///////////////////////////////////////////////////////////////////////////////
1807 // CRichEditFontDialogImpl - font selection for the Rich Edit ctrl
1809 #if defined(_RICHEDIT_) && !defined(_WIN32_WCE)
1812 class ATL_NO_VTABLE CRichEditFontDialogImpl
: public CFontDialogImpl
< T
>
1815 CRichEditFontDialogImpl(const CHARFORMAT
& charformat
,
1816 DWORD dwFlags
= CF_SCREENFONTS
,
1817 HDC hDCPrinter
= NULL
,
1818 HWND hWndParent
= NULL
)
1819 : CFontDialogImpl
< T
>(NULL
, dwFlags
, hDCPrinter
, hWndParent
)
1821 m_cf
.Flags
|= CF_INITTOLOGFONTSTRUCT
;
1822 m_cf
.Flags
|= FillInLogFont(charformat
);
1823 m_cf
.lpLogFont
= &m_lf
;
1825 if((charformat
.dwMask
& CFM_COLOR
) != 0)
1826 m_cf
.rgbColors
= charformat
.crTextColor
;
1829 void GetCharFormat(CHARFORMAT
& cf
) const
1834 if((m_cf
.Flags
& CF_NOSTYLESEL
) == 0)
1836 cf
.dwMask
|= CFM_BOLD
| CFM_ITALIC
;
1837 cf
.dwEffects
|= IsBold() ? CFE_BOLD
: 0;
1838 cf
.dwEffects
|= IsItalic() ? CFE_ITALIC
: 0;
1840 if((m_cf
.Flags
& CF_NOSIZESEL
) == 0)
1842 cf
.dwMask
|= CFM_SIZE
;
1843 // GetSize() returns in tenths of points so mulitply by 2 to get twips
1844 cf
.yHeight
= GetSize() * 2;
1847 if((m_cf
.Flags
& CF_NOFACESEL
) == 0)
1849 cf
.dwMask
|= CFM_FACE
;
1850 cf
.bPitchAndFamily
= m_cf
.lpLogFont
->lfPitchAndFamily
;
1851 #if (_RICHEDIT_VER >= 0x0200)
1852 SecureHelper::strcpy_x(cf
.szFaceName
, _countof(cf
.szFaceName
), GetFaceName());
1853 #else // !(_RICHEDIT_VER >= 0x0200)
1854 SecureHelper::strcpyA_x(cf
.szFaceName
, _countof(cf
.szFaceName
), T2A((LPTSTR
)(LPCTSTR
)GetFaceName()));
1855 #endif // !(_RICHEDIT_VER >= 0x0200)
1858 if((m_cf
.Flags
& CF_EFFECTS
) != 0)
1860 cf
.dwMask
|= CFM_UNDERLINE
| CFM_STRIKEOUT
| CFM_COLOR
;
1861 cf
.dwEffects
|= IsUnderline() ? CFE_UNDERLINE
: 0;
1862 cf
.dwEffects
|= IsStrikeOut() ? CFE_STRIKEOUT
: 0;
1863 cf
.crTextColor
= GetColor();
1865 if((m_cf
.Flags
& CF_NOSCRIPTSEL
) == 0)
1867 cf
.bCharSet
= m_cf
.lpLogFont
->lfCharSet
;
1868 cf
.dwMask
|= CFM_CHARSET
;
1873 DWORD
FillInLogFont(const CHARFORMAT
& cf
)
1877 if((cf
.dwMask
& CFM_SIZE
) != 0)
1879 HDC hDC
= ::CreateDC(_T("DISPLAY"), NULL
, NULL
, NULL
);
1880 LONG yPerInch
= ::GetDeviceCaps(hDC
, LOGPIXELSY
);
1881 m_lf
.lfHeight
= -(int)((cf
.yHeight
* yPerInch
) / 1440);
1887 m_lf
.lfEscapement
= 0;
1888 m_lf
.lfOrientation
= 0;
1890 if((cf
.dwMask
& (CFM_ITALIC
| CFM_BOLD
)) == (CFM_ITALIC
| CFM_BOLD
))
1892 m_lf
.lfWeight
= ((cf
.dwEffects
& CFE_BOLD
) != 0) ? FW_BOLD
: FW_NORMAL
;
1893 m_lf
.lfItalic
= (BYTE
)(((cf
.dwEffects
& CFE_ITALIC
) != 0) ? TRUE
: FALSE
);
1897 dwFlags
|= CF_NOSTYLESEL
;
1898 m_lf
.lfWeight
= FW_DONTCARE
;
1899 m_lf
.lfItalic
= FALSE
;
1902 if((cf
.dwMask
& (CFM_UNDERLINE
| CFM_STRIKEOUT
| CFM_COLOR
)) == (CFM_UNDERLINE
|CFM_STRIKEOUT
|CFM_COLOR
))
1904 dwFlags
|= CF_EFFECTS
;
1905 m_lf
.lfUnderline
= (BYTE
)(((cf
.dwEffects
& CFE_UNDERLINE
) != 0) ? TRUE
: FALSE
);
1906 m_lf
.lfStrikeOut
= (BYTE
)(((cf
.dwEffects
& CFE_STRIKEOUT
) != 0) ? TRUE
: FALSE
);
1910 m_lf
.lfUnderline
= (BYTE
)FALSE
;
1911 m_lf
.lfStrikeOut
= (BYTE
)FALSE
;
1914 if((cf
.dwMask
& CFM_CHARSET
) != 0)
1915 m_lf
.lfCharSet
= cf
.bCharSet
;
1917 dwFlags
|= CF_NOSCRIPTSEL
;
1918 m_lf
.lfOutPrecision
= OUT_DEFAULT_PRECIS
;
1919 m_lf
.lfClipPrecision
= CLIP_DEFAULT_PRECIS
;
1920 m_lf
.lfQuality
= DEFAULT_QUALITY
;
1921 if((cf
.dwMask
& CFM_FACE
) != 0)
1923 m_lf
.lfPitchAndFamily
= cf
.bPitchAndFamily
;
1924 #if (_RICHEDIT_VER >= 0x0200)
1925 SecureHelper::strcpy_x(m_lf
.lfFaceName
, _countof(m_lf
.lfFaceName
), cf
.szFaceName
);
1926 #else // !(_RICHEDIT_VER >= 0x0200)
1927 SecureHelper::strcpy_x(m_lf
.lfFaceName
, _countof(m_lf
.lfFaceName
), A2T((LPSTR
)cf
.szFaceName
));
1928 #endif // !(_RICHEDIT_VER >= 0x0200)
1932 m_lf
.lfPitchAndFamily
= DEFAULT_PITCH
|FF_DONTCARE
;
1933 m_lf
.lfFaceName
[0] = (TCHAR
)0;
1939 class CRichEditFontDialog
: public CRichEditFontDialogImpl
<CRichEditFontDialog
>
1942 CRichEditFontDialog(const CHARFORMAT
& charformat
,
1943 DWORD dwFlags
= CF_SCREENFONTS
,
1944 HDC hDCPrinter
= NULL
,
1945 HWND hWndParent
= NULL
)
1946 : CRichEditFontDialogImpl
<CRichEditFontDialog
>(charformat
, dwFlags
, hDCPrinter
, hWndParent
)
1949 DECLARE_EMPTY_MSG_MAP()
1952 #endif // defined(_RICHEDIT_) && !defined(_WIN32_WCE)
1955 ///////////////////////////////////////////////////////////////////////////////
1956 // CColorDialogImpl - color selection
1958 #if !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
1961 #pragma comment(lib, "commdlg.lib")
1963 #ifndef SETRGBSTRING
1964 #define SETRGBSTRING _T("commdlg_SetRGBColor")
1967 #ifndef COLOROKSTRING
1968 #define COLOROKSTRING _T("commdlg_ColorOK")
1973 class ATL_NO_VTABLE CColorDialogImpl
: public CCommonDialogImplBase
1979 CColorDialogImpl(COLORREF clrInit
= 0, DWORD dwFlags
= 0, HWND hWndParent
= NULL
)
1981 memset(&m_cc
, 0, sizeof(m_cc
));
1983 m_cc
.lStructSize
= sizeof(m_cc
);
1984 m_cc
.lpCustColors
= GetCustomColors();
1985 m_cc
.hwndOwner
= hWndParent
;
1986 m_cc
.Flags
= dwFlags
| CC_ENABLEHOOK
;
1987 m_cc
.lpfnHook
= (LPCCHOOKPROC
)T::HookProc
;
1991 m_cc
.rgbResult
= clrInit
;
1992 m_cc
.Flags
|= CC_RGBINIT
;
1997 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
1999 ATLASSERT((m_cc
.Flags
& CC_ENABLEHOOK
) != 0);
2000 ATLASSERT(m_cc
.lpfnHook
!= NULL
); // can still be a user hook
2002 if(m_cc
.hwndOwner
== NULL
) // set only if not specified before
2003 m_cc
.hwndOwner
= hWndParent
;
2005 ATLASSERT(m_hWnd
== NULL
);
2006 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (CCommonDialogImplBase
*)this);
2008 BOOL bRet
= ::ChooseColor(&m_cc
);
2012 return bRet
? IDOK
: IDCANCEL
;
2015 // Set the current color while dialog is displayed
2016 void SetCurrentColor(COLORREF clr
)
2018 ATLASSERT(::IsWindow(m_hWnd
));
2019 SendMessage(_GetSetRGBMessage(), 0, (LPARAM
)clr
);
2022 // Get the selected color after DoModal returns, or in OnColorOK
2023 COLORREF
GetColor() const
2025 return m_cc
.rgbResult
;
2028 // Special override for the color dialog
2029 static UINT_PTR APIENTRY
HookProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2031 if(uMsg
!= WM_INITDIALOG
&& uMsg
!= _GetColorOKMessage())
2034 LPCHOOSECOLOR lpCC
= (LPCHOOSECOLOR
)lParam
;
2035 CCommonDialogImplBase
* pT
= NULL
;
2037 if(uMsg
== WM_INITDIALOG
)
2039 pT
= (CCommonDialogImplBase
*)ModuleHelper::ExtractCreateWndData();
2040 lpCC
->lCustData
= (LPARAM
)pT
;
2041 ATLASSERT(pT
!= NULL
);
2042 ATLASSERT(pT
->m_hWnd
== NULL
);
2043 ATLASSERT(::IsWindow(hWnd
));
2044 // subclass dialog's window
2045 if(!pT
->SubclassWindow(hWnd
))
2047 ATLTRACE2(atlTraceUI
, 0, _T("Subclassing a Color common dialog failed\n"));
2051 else if(uMsg
== _GetColorOKMessage())
2053 pT
= (CCommonDialogImplBase
*)lpCC
->lCustData
;
2054 ATLASSERT(pT
!= NULL
);
2055 ATLASSERT(::IsWindow(pT
->m_hWnd
));
2058 // pass to the message map
2060 if(pT
->ProcessWindowMessage(pT
->m_hWnd
, uMsg
, wParam
, lParam
, lRes
, 0) == FALSE
)
2066 static COLORREF
* GetCustomColors()
2068 static COLORREF rgbCustomColors
[16] =
2070 RGB(255, 255, 255), RGB(255, 255, 255),
2071 RGB(255, 255, 255), RGB(255, 255, 255),
2072 RGB(255, 255, 255), RGB(255, 255, 255),
2073 RGB(255, 255, 255), RGB(255, 255, 255),
2074 RGB(255, 255, 255), RGB(255, 255, 255),
2075 RGB(255, 255, 255), RGB(255, 255, 255),
2076 RGB(255, 255, 255), RGB(255, 255, 255),
2077 RGB(255, 255, 255), RGB(255, 255, 255),
2080 return rgbCustomColors
;
2083 static UINT
_GetSetRGBMessage()
2085 static UINT uSetRGBMessage
= 0;
2086 if(uSetRGBMessage
== 0)
2088 CStaticDataInitCriticalSectionLock lock
;
2089 if(FAILED(lock
.Lock()))
2091 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetSetRGBMessage.\n"));
2096 if(uSetRGBMessage
== 0)
2097 uSetRGBMessage
= ::RegisterWindowMessage(SETRGBSTRING
);
2101 ATLASSERT(uSetRGBMessage
!= 0);
2102 return uSetRGBMessage
;
2105 static UINT
_GetColorOKMessage()
2107 static UINT uColorOKMessage
= 0;
2108 if(uColorOKMessage
== 0)
2110 CStaticDataInitCriticalSectionLock lock
;
2111 if(FAILED(lock
.Lock()))
2113 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CColorDialogImpl::_GetColorOKMessage.\n"));
2118 if(uColorOKMessage
== 0)
2119 uColorOKMessage
= ::RegisterWindowMessage(COLOROKSTRING
);
2123 ATLASSERT(uColorOKMessage
!= 0);
2124 return uColorOKMessage
;
2127 // Message map and handlers
2128 BEGIN_MSG_MAP(CColorDialogImpl
)
2129 MESSAGE_HANDLER(_GetColorOKMessage(), _OnColorOK
)
2132 LRESULT
_OnColorOK(UINT
, WPARAM
, LPARAM
, BOOL
&)
2134 T
* pT
= static_cast<T
*>(this);
2135 return pT
->OnColorOK();
2139 BOOL
OnColorOK() // validate color
2145 class CColorDialog
: public CColorDialogImpl
<CColorDialog
>
2148 CColorDialog(COLORREF clrInit
= 0, DWORD dwFlags
= 0, HWND hWndParent
= NULL
)
2149 : CColorDialogImpl
<CColorDialog
>(clrInit
, dwFlags
, hWndParent
)
2152 // override base class map and references to handlers
2153 DECLARE_EMPTY_MSG_MAP()
2156 #endif // !defined(_WIN32_WCE) || ((_WIN32_WCE > 420) && !(defined(WIN32_PLATFORM_WFSP) && (_WIN32_WCE > 0x0500)))
2159 ///////////////////////////////////////////////////////////////////////////////
2160 // CPrintDialogImpl - used for Print... and PrintSetup...
2165 static HDC
_AtlCreateDC(HGLOBAL hDevNames
, HGLOBAL hDevMode
)
2167 if(hDevNames
== NULL
)
2170 LPDEVNAMES lpDevNames
= (LPDEVNAMES
)::GlobalLock(hDevNames
);
2171 LPDEVMODE lpDevMode
= (hDevMode
!= NULL
) ? (LPDEVMODE
)::GlobalLock(hDevMode
) : NULL
;
2173 if(lpDevNames
== NULL
)
2176 HDC hDC
= ::CreateDC((LPCTSTR
)lpDevNames
+ lpDevNames
->wDriverOffset
,
2177 (LPCTSTR
)lpDevNames
+ lpDevNames
->wDeviceOffset
,
2178 (LPCTSTR
)lpDevNames
+ lpDevNames
->wOutputOffset
,
2181 ::GlobalUnlock(hDevNames
);
2182 if(hDevMode
!= NULL
)
2183 ::GlobalUnlock(hDevMode
);
2188 class ATL_NO_VTABLE CPrintDialogImpl
: public CCommonDialogImplBase
2191 // print dialog parameter block (note this is a reference)
2195 CPrintDialogImpl(BOOL bPrintSetupOnly
= FALSE
, // TRUE for Print Setup, FALSE for Print Dialog
2196 DWORD dwFlags
= PD_ALLPAGES
| PD_USEDEVMODECOPIES
| PD_NOPAGENUMS
| PD_NOSELECTION
,
2197 HWND hWndParent
= NULL
)
2200 memset(&m_pdActual
, 0, sizeof(m_pdActual
));
2202 m_pd
.lStructSize
= sizeof(m_pdActual
);
2203 m_pd
.hwndOwner
= hWndParent
;
2204 m_pd
.Flags
= (dwFlags
| PD_ENABLEPRINTHOOK
| PD_ENABLESETUPHOOK
);
2205 m_pd
.lpfnPrintHook
= (LPPRINTHOOKPROC
)T::HookProc
;
2206 m_pd
.lpfnSetupHook
= (LPSETUPHOOKPROC
)T::HookProc
;
2209 m_pd
.Flags
|= PD_PRINTSETUP
;
2211 m_pd
.Flags
|= PD_RETURNDC
;
2213 m_pd
.Flags
&= ~PD_RETURNIC
; // do not support information context
2217 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
2219 ATLASSERT((m_pd
.Flags
& PD_ENABLEPRINTHOOK
) != 0);
2220 ATLASSERT((m_pd
.Flags
& PD_ENABLESETUPHOOK
) != 0);
2221 ATLASSERT(m_pd
.lpfnPrintHook
!= NULL
); // can still be a user hook
2222 ATLASSERT(m_pd
.lpfnSetupHook
!= NULL
); // can still be a user hook
2223 ATLASSERT((m_pd
.Flags
& PD_RETURNDEFAULT
) == 0); // use GetDefaults for this
2225 if(m_pd
.hwndOwner
== NULL
) // set only if not specified before
2226 m_pd
.hwndOwner
= hWndParent
;
2228 ATLASSERT(m_hWnd
== NULL
);
2229 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (CCommonDialogImplBase
*)this);
2231 BOOL bRet
= ::PrintDlg(&m_pd
);
2235 return bRet
? IDOK
: IDCANCEL
;
2238 // GetDefaults will not display a dialog but will get device defaults
2241 m_pd
.Flags
|= PD_RETURNDEFAULT
;
2242 ATLASSERT(m_pd
.hDevMode
== NULL
); // must be NULL
2243 ATLASSERT(m_pd
.hDevNames
== NULL
); // must be NULL
2245 return ::PrintDlg(&m_pd
);
2248 // Helpers for parsing information after successful return num. copies requested
2249 int GetCopies() const
2251 if((m_pd
.Flags
& PD_USEDEVMODECOPIES
) != 0)
2253 LPDEVMODE lpDevMode
= GetDevMode();
2254 return (lpDevMode
!= NULL
) ? lpDevMode
->dmCopies
: -1;
2257 return m_pd
.nCopies
;
2260 BOOL
PrintCollate() const // TRUE if collate checked
2262 return ((m_pd
.Flags
& PD_COLLATE
) != 0) ? TRUE
: FALSE
;
2265 BOOL
PrintSelection() const // TRUE if printing selection
2267 return ((m_pd
.Flags
& PD_SELECTION
) != 0) ? TRUE
: FALSE
;
2270 BOOL
PrintAll() const // TRUE if printing all pages
2272 return (!PrintRange() && !PrintSelection()) ? TRUE
: FALSE
;
2275 BOOL
PrintRange() const // TRUE if printing page range
2277 return ((m_pd
.Flags
& PD_PAGENUMS
) != 0) ? TRUE
: FALSE
;
2280 BOOL
PrintToFile() const // TRUE if printing to a file
2282 return ((m_pd
.Flags
& PD_PRINTTOFILE
) != 0) ? TRUE
: FALSE
;
2285 int GetFromPage() const // starting page if valid
2287 return PrintRange() ? m_pd
.nFromPage
: -1;
2290 int GetToPage() const // ending page if valid
2292 return PrintRange() ? m_pd
.nToPage
: -1;
2295 LPDEVMODE
GetDevMode() const // return DEVMODE
2297 if(m_pd
.hDevMode
== NULL
)
2300 return (LPDEVMODE
)::GlobalLock(m_pd
.hDevMode
);
2303 LPCTSTR
GetDriverName() const // return driver name
2305 if(m_pd
.hDevNames
== NULL
)
2308 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pd
.hDevNames
);
2312 return (LPCTSTR
)lpDev
+ lpDev
->wDriverOffset
;
2315 LPCTSTR
GetDeviceName() const // return device name
2317 if(m_pd
.hDevNames
== NULL
)
2320 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pd
.hDevNames
);
2324 return (LPCTSTR
)lpDev
+ lpDev
->wDeviceOffset
;
2327 LPCTSTR
GetPortName() const // return output port name
2329 if(m_pd
.hDevNames
== NULL
)
2332 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pd
.hDevNames
);
2336 return (LPCTSTR
)lpDev
+ lpDev
->wOutputOffset
;
2339 HDC
GetPrinterDC() const // return HDC (caller must delete)
2341 ATLASSERT((m_pd
.Flags
& PD_RETURNDC
) != 0);
2345 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
2346 // This DC is returned, but also stored in m_pd.hDC as though it had been
2347 // returned by CommDlg. It is assumed that any previously obtained DC
2348 // has been/will be deleted by the user. This may be
2349 // used without ever invoking the print/print setup dialogs.
2350 HDC
CreatePrinterDC()
2352 m_pd
.hDC
= _AtlCreateDC(m_pd
.hDevNames
, m_pd
.hDevMode
);
2357 PRINTDLG m_pdActual
; // the Print/Print Setup need to share this
2359 // The following handle the case of print setup... from the print dialog
2360 CPrintDialogImpl(PRINTDLG
& pdInit
) : m_pd(pdInit
)
2363 BEGIN_MSG_MAP(CPrintDialogImpl
)
2365 COMMAND_ID_HANDLER(psh1
, OnPrintSetup
) // print setup button when print is displayed
2367 COMMAND_ID_HANDLER(0x0400, OnPrintSetup
) // value from dlgs.h
2371 LRESULT
OnPrintSetup(WORD wNotifyCode
, WORD wID
, HWND hWndCtl
, BOOL
& /*bHandled*/)
2374 ModuleHelper::AddCreateWndData(&dlgSetup
.m_thunk
.cd
, (CCommonDialogImplBase
*)&dlgSetup
);
2375 return DefWindowProc(WM_COMMAND
, MAKEWPARAM(wID
, wNotifyCode
), (LPARAM
)hWndCtl
);
2379 class CPrintDialog
: public CPrintDialogImpl
<CPrintDialog
>
2382 CPrintDialog(BOOL bPrintSetupOnly
= FALSE
,
2383 DWORD dwFlags
= PD_ALLPAGES
| PD_USEDEVMODECOPIES
| PD_NOPAGENUMS
| PD_NOSELECTION
,
2384 HWND hWndParent
= NULL
)
2385 : CPrintDialogImpl
<CPrintDialog
>(bPrintSetupOnly
, dwFlags
, hWndParent
)
2388 CPrintDialog(PRINTDLG
& pdInit
) : CPrintDialogImpl
<CPrintDialog
>(pdInit
)
2392 #endif // _WIN32_WCE
2395 ///////////////////////////////////////////////////////////////////////////////
2396 // CPrintDialogExImpl - new print dialog for Windows 2000
2398 #if (WINVER >= 0x0500) && !defined(_WIN32_WCE)
2404 extern "C" const __declspec(selectany
) IID IID_IPrintDialogCallback
= {0x5852a2c3, 0x6530, 0x11d1, {0xb6, 0xa3, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
2405 extern "C" const __declspec(selectany
) IID IID_IPrintDialogServices
= {0x509aaeda, 0x5639, 0x11d1, {0xb6, 0xa1, 0x0, 0x0, 0xf8, 0x75, 0x7b, 0xf9}};
2411 class ATL_NO_VTABLE CPrintDialogExImpl
:
2412 public ATL::CWindow
,
2413 public ATL::CMessageMap
,
2414 public IPrintDialogCallback
,
2415 public ATL::IObjectWithSiteImpl
< T
>
2421 CPrintDialogExImpl(DWORD dwFlags
= PD_ALLPAGES
| PD_USEDEVMODECOPIES
| PD_NOPAGENUMS
| PD_NOSELECTION
| PD_NOCURRENTPAGE
,
2422 HWND hWndParent
= NULL
)
2424 memset(&m_pdex
, 0, sizeof(m_pdex
));
2426 m_pdex
.lStructSize
= sizeof(PRINTDLGEX
);
2427 m_pdex
.hwndOwner
= hWndParent
;
2428 m_pdex
.Flags
= dwFlags
;
2429 m_pdex
.nStartPage
= START_PAGE_GENERAL
;
2430 // callback object will be set in DoModal
2432 m_pdex
.Flags
&= ~PD_RETURNIC
; // do not support information context
2436 HRESULT
DoModal(HWND hWndParent
= ::GetActiveWindow())
2438 ATLASSERT(m_hWnd
== NULL
);
2439 ATLASSERT((m_pdex
.Flags
& PD_RETURNDEFAULT
) == 0); // use GetDefaults for this
2441 if(m_pdex
.hwndOwner
== NULL
) // set only if not specified before
2442 m_pdex
.hwndOwner
= hWndParent
;
2444 T
* pT
= static_cast<T
*>(this);
2445 m_pdex
.lpCallback
= (IUnknown
*)(IPrintDialogCallback
*)pT
;
2447 HRESULT hResult
= ::PrintDlgEx(&m_pdex
);
2454 BOOL
EndDialog(INT_PTR
/*nRetCode*/ = 0)
2456 ATLASSERT(::IsWindow(m_hWnd
));
2457 SendMessage(WM_COMMAND
, MAKEWPARAM(IDABORT
, 0));
2461 // GetDefaults will not display a dialog but will get device defaults
2462 HRESULT
GetDefaults()
2464 m_pdex
.Flags
|= PD_RETURNDEFAULT
;
2465 ATLASSERT(m_pdex
.hDevMode
== NULL
); // must be NULL
2466 ATLASSERT(m_pdex
.hDevNames
== NULL
); // must be NULL
2468 return ::PrintDlgEx(&m_pdex
);
2471 // Helpers for parsing information after successful return num. copies requested
2472 int GetCopies() const
2474 if((m_pdex
.Flags
& PD_USEDEVMODECOPIES
) != 0)
2476 LPDEVMODE lpDevMode
= GetDevMode();
2477 return (lpDevMode
!= NULL
) ? lpDevMode
->dmCopies
: -1;
2480 return m_pdex
.nCopies
;
2483 BOOL
PrintCollate() const // TRUE if collate checked
2485 return ((m_pdex
.Flags
& PD_COLLATE
) != 0) ? TRUE
: FALSE
;
2488 BOOL
PrintSelection() const // TRUE if printing selection
2490 return ((m_pdex
.Flags
& PD_SELECTION
) != 0) ? TRUE
: FALSE
;
2493 BOOL
PrintAll() const // TRUE if printing all pages
2495 return (!PrintRange() && !PrintSelection()) ? TRUE
: FALSE
;
2498 BOOL
PrintRange() const // TRUE if printing page range
2500 return ((m_pdex
.Flags
& PD_PAGENUMS
) != 0) ? TRUE
: FALSE
;
2503 BOOL
PrintToFile() const // TRUE if printing to a file
2505 return ((m_pdex
.Flags
& PD_PRINTTOFILE
) != 0) ? TRUE
: FALSE
;
2508 LPDEVMODE
GetDevMode() const // return DEVMODE
2510 if(m_pdex
.hDevMode
== NULL
)
2513 return (LPDEVMODE
)::GlobalLock(m_pdex
.hDevMode
);
2516 LPCTSTR
GetDriverName() const // return driver name
2518 if(m_pdex
.hDevNames
== NULL
)
2521 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pdex
.hDevNames
);
2525 return (LPCTSTR
)lpDev
+ lpDev
->wDriverOffset
;
2528 LPCTSTR
GetDeviceName() const // return device name
2530 if(m_pdex
.hDevNames
== NULL
)
2533 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pdex
.hDevNames
);
2537 return (LPCTSTR
)lpDev
+ lpDev
->wDeviceOffset
;
2540 LPCTSTR
GetPortName() const // return output port name
2542 if(m_pdex
.hDevNames
== NULL
)
2545 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_pdex
.hDevNames
);
2549 return (LPCTSTR
)lpDev
+ lpDev
->wOutputOffset
;
2552 HDC
GetPrinterDC() const // return HDC (caller must delete)
2554 ATLASSERT((m_pdex
.Flags
& PD_RETURNDC
) != 0);
2558 // This helper creates a DC based on the DEVNAMES and DEVMODE structures.
2559 // This DC is returned, but also stored in m_pdex.hDC as though it had been
2560 // returned by CommDlg. It is assumed that any previously obtained DC
2561 // has been/will be deleted by the user. This may be
2562 // used without ever invoking the print/print setup dialogs.
2563 HDC
CreatePrinterDC()
2565 m_pdex
.hDC
= _AtlCreateDC(m_pdex
.hDevNames
, m_pdex
.hDevMode
);
2569 // Implementation - interfaces
2572 STDMETHOD(QueryInterface
)(REFIID riid
, void** ppvObject
)
2574 if(ppvObject
== NULL
)
2577 T
* pT
= static_cast<T
*>(this);
2578 if(IsEqualGUID(riid
, IID_IUnknown
) || IsEqualGUID(riid
, IID_IPrintDialogCallback
))
2580 *ppvObject
= (IPrintDialogCallback
*)pT
;
2581 // AddRef() not needed
2584 else if(IsEqualGUID(riid
, IID_IObjectWithSite
))
2586 *ppvObject
= (IObjectWithSite
*)pT
;
2587 // AddRef() not needed
2591 return E_NOINTERFACE
;
2594 virtual ULONG STDMETHODCALLTYPE
AddRef()
2599 virtual ULONG STDMETHODCALLTYPE
Release()
2604 // IPrintDialogCallback
2605 STDMETHOD(InitDone
)()
2610 STDMETHOD(SelectionChange
)()
2615 STDMETHOD(HandleMessage
)(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
* plResult
)
2617 // set up m_hWnd the first time
2622 HRESULT hRet
= ProcessWindowMessage(hWnd
, uMsg
, wParam
, lParam
, *plResult
, 0) ? S_OK
: S_FALSE
;
2623 if(hRet
== S_OK
&& uMsg
== WM_NOTIFY
) // return in DWLP_MSGRESULT
2624 ::SetWindowLongPtr(GetParent(), DWLP_MSGRESULT
, (LONG_PTR
)*plResult
);
2626 if(uMsg
== WM_INITDIALOG
&& hRet
== S_OK
&& (BOOL
)*plResult
!= FALSE
)
2633 class CPrintDialogEx
: public CPrintDialogExImpl
<CPrintDialogEx
>
2637 DWORD dwFlags
= PD_ALLPAGES
| PD_USEDEVMODECOPIES
| PD_NOPAGENUMS
| PD_NOSELECTION
| PD_NOCURRENTPAGE
,
2638 HWND hWndParent
= NULL
)
2639 : CPrintDialogExImpl
<CPrintDialogEx
>(dwFlags
, hWndParent
)
2642 DECLARE_EMPTY_MSG_MAP()
2645 #endif // (WINVER >= 0x0500) && !defined(_WIN32_WCE)
2648 ///////////////////////////////////////////////////////////////////////////////
2649 // CPageSetupDialogImpl - Page Setup dialog
2654 class ATL_NO_VTABLE CPageSetupDialogImpl
: public CCommonDialogImplBase
2658 ATL::CWndProcThunk m_thunkPaint
;
2661 CPageSetupDialogImpl(DWORD dwFlags
= PSD_MARGINS
| PSD_INWININIINTLMEASURE
, HWND hWndParent
= NULL
)
2663 memset(&m_psd
, 0, sizeof(m_psd
));
2665 m_psd
.lStructSize
= sizeof(m_psd
);
2666 m_psd
.hwndOwner
= hWndParent
;
2667 m_psd
.Flags
= (dwFlags
| PSD_ENABLEPAGESETUPHOOK
| PSD_ENABLEPAGEPAINTHOOK
);
2668 m_psd
.lpfnPageSetupHook
= (LPPAGESETUPHOOK
)T::HookProc
;
2669 m_thunkPaint
.Init((WNDPROC
)T::PaintHookProc
, this);
2670 #if (_ATL_VER >= 0x0700)
2671 m_psd
.lpfnPagePaintHook
= (LPPAGEPAINTHOOK
)m_thunkPaint
.GetWNDPROC();
2673 m_psd
.lpfnPagePaintHook
= (LPPAGEPAINTHOOK
)&(m_thunkPaint
.thunk
);
2677 DECLARE_EMPTY_MSG_MAP()
2680 LPDEVMODE
GetDevMode() const // return DEVMODE
2682 if(m_psd
.hDevMode
== NULL
)
2685 return (LPDEVMODE
)::GlobalLock(m_psd
.hDevMode
);
2688 LPCTSTR
GetDriverName() const // return driver name
2690 if(m_psd
.hDevNames
== NULL
)
2693 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_psd
.hDevNames
);
2694 return (LPCTSTR
)lpDev
+ lpDev
->wDriverOffset
;
2697 LPCTSTR
GetDeviceName() const // return device name
2699 if(m_psd
.hDevNames
== NULL
)
2702 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_psd
.hDevNames
);
2703 return (LPCTSTR
)lpDev
+ lpDev
->wDeviceOffset
;
2706 LPCTSTR
GetPortName() const // return output port name
2708 if(m_psd
.hDevNames
== NULL
)
2711 LPDEVNAMES lpDev
= (LPDEVNAMES
)::GlobalLock(m_psd
.hDevNames
);
2712 return (LPCTSTR
)lpDev
+ lpDev
->wOutputOffset
;
2715 HDC
CreatePrinterDC()
2717 return _AtlCreateDC(m_psd
.hDevNames
, m_psd
.hDevMode
);
2720 SIZE
GetPaperSize() const
2723 size
.cx
= m_psd
.ptPaperSize
.x
;
2724 size
.cy
= m_psd
.ptPaperSize
.y
;
2728 void GetMargins(LPRECT lpRectMargins
, LPRECT lpRectMinMargins
) const
2730 if(lpRectMargins
!= NULL
)
2731 *lpRectMargins
= m_psd
.rtMargin
;
2732 if(lpRectMinMargins
!= NULL
)
2733 *lpRectMinMargins
= m_psd
.rtMinMargin
;
2737 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
2739 ATLASSERT((m_psd
.Flags
& PSD_ENABLEPAGESETUPHOOK
) != 0);
2740 ATLASSERT((m_psd
.Flags
& PSD_ENABLEPAGEPAINTHOOK
) != 0);
2741 ATLASSERT(m_psd
.lpfnPageSetupHook
!= NULL
); // can still be a user hook
2742 ATLASSERT(m_psd
.lpfnPagePaintHook
!= NULL
); // can still be a user hook
2744 if(m_psd
.hwndOwner
== NULL
) // set only if not specified before
2745 m_psd
.hwndOwner
= hWndParent
;
2747 ATLASSERT(m_hWnd
== NULL
);
2748 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (CCommonDialogImplBase
*)this);
2750 BOOL bRet
= ::PageSetupDlg(&m_psd
);
2754 return bRet
? IDOK
: IDCANCEL
;
2758 static UINT_PTR CALLBACK
PaintHookProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
2764 case WM_PSD_PAGESETUPDLG
:
2765 uRet
= pT
->PreDrawPage(LOWORD(wParam
), HIWORD(wParam
), (LPPAGESETUPDLG
)lParam
);
2767 case WM_PSD_FULLPAGERECT
:
2768 case WM_PSD_MINMARGINRECT
:
2769 case WM_PSD_MARGINRECT
:
2770 case WM_PSD_GREEKTEXTRECT
:
2771 case WM_PSD_ENVSTAMPRECT
:
2772 case WM_PSD_YAFULLPAGERECT
:
2773 uRet
= pT
->OnDrawPage(uMsg
, (HDC
)wParam
, (LPRECT
)lParam
);
2776 ATLTRACE2(atlTraceUI
, 0, _T("CPageSetupDialogImpl::PaintHookProc - unknown message received\n"));
2783 UINT_PTR
PreDrawPage(WORD
/*wPaper*/, WORD
/*wFlags*/, LPPAGESETUPDLG
/*pPSD*/)
2785 // return 1 to prevent any more drawing
2789 UINT_PTR
OnDrawPage(UINT
/*uMsg*/, HDC
/*hDC*/, LPRECT
/*lpRect*/)
2791 return 0; // do the default
2795 class CPageSetupDialog
: public CPageSetupDialogImpl
<CPageSetupDialog
>
2798 CPageSetupDialog(DWORD dwFlags
= PSD_MARGINS
| PSD_INWININIINTLMEASURE
, HWND hWndParent
= NULL
)
2799 : CPageSetupDialogImpl
<CPageSetupDialog
>(dwFlags
, hWndParent
)
2802 // override PaintHookProc and references to handlers
2803 static UINT_PTR CALLBACK
PaintHookProc(HWND
, UINT
, WPARAM
, LPARAM
)
2809 #endif // _WIN32_WCE
2812 ///////////////////////////////////////////////////////////////////////////////
2813 // CFindReplaceDialogImpl - Find/FindReplace modeless dialogs
2818 class ATL_NO_VTABLE CFindReplaceDialogImpl
: public CCommonDialogImplBase
2821 enum { _cchFindReplaceBuffer
= 128 };
2824 TCHAR m_szFindWhat
[_cchFindReplaceBuffer
];
2825 TCHAR m_szReplaceWith
[_cchFindReplaceBuffer
];
2828 CFindReplaceDialogImpl()
2830 memset(&m_fr
, 0, sizeof(m_fr
));
2831 m_szFindWhat
[0] = _T('\0');
2832 m_szReplaceWith
[0] = _T('\0');
2834 m_fr
.lStructSize
= sizeof(m_fr
);
2835 m_fr
.Flags
= FR_ENABLEHOOK
;
2836 m_fr
.lpfnHook
= (LPFRHOOKPROC
)T::HookProc
;
2837 m_fr
.lpstrFindWhat
= (LPTSTR
)m_szFindWhat
;
2838 m_fr
.wFindWhatLen
= _cchFindReplaceBuffer
;
2839 m_fr
.lpstrReplaceWith
= (LPTSTR
)m_szReplaceWith
;
2840 m_fr
.wReplaceWithLen
= _cchFindReplaceBuffer
;
2843 // Note: You must allocate the object on the heap.
2844 // If you do not, you must override OnFinalMessage()
2845 virtual void OnFinalMessage(HWND
/*hWnd*/)
2850 HWND
Create(BOOL bFindDialogOnly
, // TRUE for Find, FALSE for FindReplace
2851 LPCTSTR lpszFindWhat
,
2852 LPCTSTR lpszReplaceWith
= NULL
,
2853 DWORD dwFlags
= FR_DOWN
,
2854 HWND hWndParent
= NULL
)
2856 ATLASSERT((m_fr
.Flags
& FR_ENABLEHOOK
) != 0);
2857 ATLASSERT(m_fr
.lpfnHook
!= NULL
);
2859 m_fr
.Flags
|= dwFlags
;
2861 if(hWndParent
== NULL
)
2862 m_fr
.hwndOwner
= ::GetActiveWindow();
2864 m_fr
.hwndOwner
= hWndParent
;
2865 ATLASSERT(m_fr
.hwndOwner
!= NULL
); // must have an owner for modeless dialog
2867 if(lpszFindWhat
!= NULL
)
2868 SecureHelper::strncpy_x(m_szFindWhat
, _countof(m_szFindWhat
), lpszFindWhat
, _TRUNCATE
);
2870 if(lpszReplaceWith
!= NULL
)
2871 SecureHelper::strncpy_x(m_szReplaceWith
, _countof(m_szReplaceWith
), lpszReplaceWith
, _TRUNCATE
);
2873 ATLASSERT(m_hWnd
== NULL
);
2874 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, (CCommonDialogImplBase
*)this);
2878 hWnd
= ::FindText(&m_fr
);
2880 hWnd
= ::ReplaceText(&m_fr
);
2882 ATLASSERT(m_hWnd
== hWnd
);
2886 static const UINT
GetFindReplaceMsg()
2888 static const UINT nMsgFindReplace
= ::RegisterWindowMessage(FINDMSGSTRING
);
2889 return nMsgFindReplace
;
2891 // call while handling FINDMSGSTRING registered message
2892 // to retreive the object
2893 static T
* PASCAL
GetNotifier(LPARAM lParam
)
2895 ATLASSERT(lParam
!= NULL
);
2896 T
* pDlg
= (T
*)(lParam
- offsetof(T
, m_fr
));
2901 // Helpers for parsing information after successful return
2902 LPCTSTR
GetFindString() const // get find string
2904 return (LPCTSTR
)m_fr
.lpstrFindWhat
;
2907 LPCTSTR
GetReplaceString() const // get replacement string
2909 return (LPCTSTR
)m_fr
.lpstrReplaceWith
;
2912 BOOL
SearchDown() const // TRUE if search down, FALSE is up
2914 return ((m_fr
.Flags
& FR_DOWN
) != 0) ? TRUE
: FALSE
;
2917 BOOL
FindNext() const // TRUE if command is find next
2919 return ((m_fr
.Flags
& FR_FINDNEXT
) != 0) ? TRUE
: FALSE
;
2922 BOOL
MatchCase() const // TRUE if matching case
2924 return ((m_fr
.Flags
& FR_MATCHCASE
) != 0) ? TRUE
: FALSE
;
2927 BOOL
MatchWholeWord() const // TRUE if matching whole words only
2929 return ((m_fr
.Flags
& FR_WHOLEWORD
) != 0) ? TRUE
: FALSE
;
2932 BOOL
ReplaceCurrent() const // TRUE if replacing current string
2934 return ((m_fr
. Flags
& FR_REPLACE
) != 0) ? TRUE
: FALSE
;
2937 BOOL
ReplaceAll() const // TRUE if replacing all occurrences
2939 return ((m_fr
.Flags
& FR_REPLACEALL
) != 0) ? TRUE
: FALSE
;
2942 BOOL
IsTerminating() const // TRUE if terminating dialog
2944 return ((m_fr
.Flags
& FR_DIALOGTERM
) != 0) ? TRUE
: FALSE
;
2948 class CFindReplaceDialog
: public CFindReplaceDialogImpl
<CFindReplaceDialog
>
2951 DECLARE_EMPTY_MSG_MAP()
2954 #endif // !_WIN32_WCE
2957 #if (_ATL_VER >= 0x800)
2958 typedef ATL::_DialogSplitHelper::DLGTEMPLATEEX DLGTEMPLATEEX
;
2959 typedef ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX DLGITEMTEMPLATEEX
;
2960 #else // (_ATL_VER >= 0x800)
2961 typedef ATL::_DialogSizeHelper::_ATL_DLGTEMPLATEEX DLGTEMPLATEEX
;
2962 #pragma pack(push, 4)
2963 struct DLGITEMTEMPLATEEX
2975 #endif // (_ATL_VER >= 0x800)
2978 ///////////////////////////////////////////////////////////////////////////////
2979 // CMemDlgTemplate - in-memory dialog template - DLGTEMPLATE or DLGTEMPLATEEX
2981 class CMemDlgTemplate
2986 CTRL_BUTTON
= 0x0080,
2988 CTRL_STATIC
= 0x0082,
2989 CTRL_LISTBOX
= 0x0083,
2990 CTRL_SCROLLBAR
= 0x0084,
2991 CTRL_COMBOBOX
= 0x0085
2994 CMemDlgTemplate() : m_pData(NULL
), m_pPtr(NULL
), m_cAllocated(0)
3002 bool IsValid() const
3004 return (m_pData
!= NULL
);
3007 bool IsTemplateEx() const
3009 return (IsValid() && ((DLGTEMPLATEEX
*)m_pData
)->signature
== 0xFFFF);
3012 LPDLGTEMPLATE
GetTemplatePtr()
3014 return reinterpret_cast<LPDLGTEMPLATE
>(m_pData
);
3017 DLGTEMPLATEEX
* GetTemplateExPtr()
3019 return reinterpret_cast<DLGTEMPLATEEX
*>(m_pData
);
3025 ATLVERIFY(::GlobalFree(m_pData
) == NULL
);
3032 void Create(bool bDlgEx
, LPCTSTR lpszCaption
, short nX
, short nY
, short nWidth
, short nHeight
, DWORD dwStyle
= 0, DWORD dwExStyle
= 0,
3033 LPCTSTR lpstrFontName
= NULL
, WORD wFontSize
= 0, WORD wWeight
= 0, BYTE bItalic
= 0, BYTE bCharset
= 0, DWORD dwHelpID
= 0,
3034 ATL::_U_STRINGorID ClassName
= 0U, ATL::_U_STRINGorID Menu
= 0U)
3036 // Should have DS_SETFONT style to set the dialog font name and size
3037 if (lpstrFontName
!= NULL
)
3039 dwStyle
|= DS_SETFONT
;
3043 dwStyle
&= ~DS_SETFONT
;
3048 DLGTEMPLATEEX dlg
= {1, 0xFFFF, dwHelpID
, dwExStyle
, dwStyle
, 0, nX
, nY
, nWidth
, nHeight
};
3049 AddData(&dlg
, sizeof(dlg
));
3053 DLGTEMPLATE dlg
= {dwStyle
, dwExStyle
, 0, nX
, nY
, nWidth
, nHeight
};
3054 AddData(&dlg
, sizeof(dlg
));
3058 if (Menu
.m_lpstr
== NULL
)
3061 AddData(&menuData
, sizeof(WORD
));
3063 else if (IS_INTRESOURCE(Menu
.m_lpstr
))
3065 WORD menuData
[] = {0xFFFF, (WORD
)Menu
.m_lpstr
};
3066 AddData(menuData
, sizeof(menuData
));
3070 AddString(Menu
.m_lpstr
);
3073 // Windows CE doesn't support the addition of menus to a dialog box
3074 ATLASSERT(Menu
.m_lpstr
== NULL
);
3075 Menu
.m_lpstr
; // avoid level 4 warning
3077 AddData(&menuData
, sizeof(WORD
));
3078 #endif // _WIN32_WCE
3080 if (ClassName
.m_lpstr
== NULL
)
3083 AddData(&classData
, sizeof(WORD
));
3085 else if (IS_INTRESOURCE(ClassName
.m_lpstr
))
3087 WORD classData
[] = {0xFFFF, (WORD
)ClassName
.m_lpstr
};
3088 AddData(classData
, sizeof(classData
));
3092 AddString(ClassName
.m_lpstr
);
3095 // Set dialog caption
3096 AddString(lpszCaption
);
3098 if (lpstrFontName
!= NULL
)
3100 AddData(&wFontSize
, sizeof(wFontSize
));
3104 AddData(&wWeight
, sizeof(wWeight
));
3105 AddData(&bItalic
, sizeof(bItalic
));
3106 AddData(&bCharset
, sizeof(bCharset
));
3109 AddString(lpstrFontName
);
3113 void AddControl(ATL::_U_STRINGorID ClassName
, WORD wId
, short nX
, short nY
, short nWidth
, short nHeight
, DWORD dwStyle
, DWORD dwExStyle
,
3114 ATL::_U_STRINGorID Text
, const WORD
* pCreationData
= NULL
, WORD nCreationData
= 0, DWORD dwHelpID
= 0)
3116 ATLASSERT(IsValid());
3119 m_pPtr
= (LPBYTE
)(DWORD_PTR
)((DWORD
)(DWORD_PTR
)(m_pPtr
+ 3) & (~3));
3123 DLGTEMPLATEEX
* dlg
= (DLGTEMPLATEEX
*)m_pData
;
3126 DLGITEMTEMPLATEEX item
= {dwHelpID
, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle
, ATL::CControlWinTraits::GetWndStyle(0) | dwStyle
, nX
, nY
, nWidth
, nHeight
, wId
};
3127 AddData(&item
, sizeof(item
));
3131 LPDLGTEMPLATE dlg
= (LPDLGTEMPLATE
)m_pData
;
3134 DLGITEMTEMPLATE item
= {ATL::CControlWinTraits::GetWndStyle(0) | dwStyle
, ATL::CControlWinTraits::GetWndExStyle(0) | dwExStyle
, nX
, nY
, nWidth
, nHeight
, wId
};
3135 AddData(&item
, sizeof(item
));
3138 ATLASSERT(ClassName
.m_lpstr
!= NULL
);
3139 if (IS_INTRESOURCE(ClassName
.m_lpstr
))
3141 WORD wData
[] = {0xFFFF, (WORD
)ClassName
.m_lpstr
};
3142 AddData(wData
, sizeof(wData
));
3146 AddString(ClassName
.m_lpstr
);
3149 if (Text
.m_lpstr
== NULL
)
3152 AddData(&classData
, sizeof(WORD
));
3154 else if (IS_INTRESOURCE(Text
.m_lpstr
))
3156 WORD wData
[] = {0xFFFF, (WORD
)Text
.m_lpstr
};
3157 AddData(wData
, sizeof(wData
));
3161 AddString(Text
.m_lpstr
);
3164 AddData(&nCreationData
, sizeof(nCreationData
));
3166 if ((nCreationData
!= 0))
3168 ATLASSERT(pCreationData
!= NULL
);
3169 AddData(pCreationData
, nCreationData
* sizeof(WORD
));
3173 void AddStdControl(StdCtrlType CtrlType
, WORD wId
, short nX
, short nY
, short nWidth
, short nHeight
,
3174 DWORD dwStyle
, DWORD dwExStyle
, ATL::_U_STRINGorID Text
, const WORD
* pCreationData
= NULL
, WORD nCreationData
= 0, DWORD dwHelpID
= 0)
3176 AddControl(CtrlType
, wId
, nX
, nY
, nWidth
, nHeight
, dwStyle
, dwExStyle
, Text
, pCreationData
, nCreationData
, dwHelpID
);
3180 void AddData(LPCVOID pData
, size_t nData
)
3182 ATLASSERT(pData
!= NULL
);
3184 const size_t ALLOCATION_INCREMENT
= 1024;
3186 if (m_pData
== NULL
)
3188 m_cAllocated
= ((nData
/ ALLOCATION_INCREMENT
) + 1) * ALLOCATION_INCREMENT
;
3189 m_pPtr
= m_pData
= static_cast<LPBYTE
>(::GlobalAlloc(GPTR
, m_cAllocated
));
3190 ATLASSERT(m_pData
!= NULL
);
3192 else if (((m_pPtr
- m_pData
) + nData
) > m_cAllocated
)
3194 size_t ptrPos
= (m_pPtr
- m_pData
);
3195 m_cAllocated
+= ((nData
/ ALLOCATION_INCREMENT
) + 1) * ALLOCATION_INCREMENT
;
3196 m_pData
= static_cast<LPBYTE
>(::GlobalReAlloc(m_pData
, m_cAllocated
, 0));
3197 ATLASSERT(m_pData
!= NULL
);
3198 m_pPtr
= m_pData
+ ptrPos
;
3201 SecureHelper::memcpy_x(m_pPtr
, m_cAllocated
- (m_pPtr
- m_pData
), pData
, nData
);
3206 void AddString(LPCTSTR lpszStr
)
3208 if (lpszStr
== NULL
)
3211 AddData(&szEmpty
, sizeof(szEmpty
));
3216 LPCWSTR lpstr
= T2CW(lpszStr
);
3217 int nSize
= lstrlenW(lpstr
) + 1;
3218 AddData(lpstr
, nSize
* sizeof(WCHAR
));
3224 SIZE_T m_cAllocated
;
3228 ///////////////////////////////////////////////////////////////////////////////
3229 // Dialog and control macros for indirect dialogs
3232 #define BEGIN_DIALOG(x, y, width, height) \
3233 void DoInitTemplate() \
3235 bool bExTemplate = false; \
3236 short nX = x, nY = y, nWidth = width, nHeight = height; \
3237 LPCTSTR szCaption = NULL; \
3238 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
3239 DWORD dwExStyle = 0; \
3240 LPCTSTR szFontName = NULL; \
3241 WORD wFontSize = 0; \
3244 BYTE bCharset = 0; \
3245 DWORD dwHelpID = 0; \
3246 ATL::_U_STRINGorID Menu = 0U; \
3247 ATL::_U_STRINGorID ClassName = 0U;
3249 // for DLGTEMPLATEEX
3250 #define BEGIN_DIALOG_EX(x, y, width, height, helpID) \
3251 void DoInitTemplate() \
3253 bool bExTemplate = true; \
3254 short nX = x, nY = y, nWidth = width, nHeight = height; \
3255 LPCTSTR szCaption = NULL; \
3256 DWORD dwStyle = WS_POPUP | WS_BORDER | WS_SYSMENU; \
3257 DWORD dwExStyle = 0; \
3258 LPCTSTR szFontName = NULL; \
3259 WORD wFontSize = 0; \
3262 BYTE bCharset = 0; \
3263 DWORD dwHelpID = helpID; \
3264 ATL::_U_STRINGorID Menu = 0U; \
3265 ATL::_U_STRINGorID ClassName = 0U;
3267 #define END_DIALOG() \
3268 m_Template.Create(bExTemplate, szCaption, nX, nY, nWidth, nHeight, dwStyle, dwExStyle, szFontName, wFontSize, wWeight, bItalic, bCharset, dwHelpID, ClassName, Menu); \
3271 #define DIALOG_CAPTION(caption) \
3272 szCaption = caption;
3273 #define DIALOG_STYLE(style) \
3275 #define DIALOG_EXSTYLE(exStyle) \
3276 dwExStyle = exStyle;
3277 #define DIALOG_FONT(pointSize, typeFace) \
3278 wFontSize = pointSize; \
3279 szFontName = typeFace;
3280 #define DIALOG_FONT_EX(pointsize, typeface, weight, italic, charset) \
3281 ATLASSERT(bExTemplate); \
3282 wFontSize = pointsize; \
3283 szFontName = typeface; \
3287 #define DIALOG_MENU(menuName) \
3289 #define DIALOG_CLASS(className) \
3290 ClassName = className;
3292 #define BEGIN_CONTROLS_MAP() \
3293 void DoInitControls() \
3296 #define END_CONTROLS_MAP() \
3300 #define CONTROL_LTEXT(text, id, x, y, width, height, style, exStyle) \
3301 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_LEFT | WS_GROUP, exStyle, text, NULL, 0);
3302 #define CONTROL_CTEXT(text, id, x, y, width, height, style, exStyle) \
3303 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_CENTER | WS_GROUP, exStyle, text, NULL, 0);
3304 #define CONTROL_RTEXT(text, id, x, y, width, height, style, exStyle) \
3305 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_RIGHT | WS_GROUP, exStyle, text, NULL, 0);
3306 #define CONTROL_PUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
3307 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3308 #define CONTROL_DEFPUSHBUTTON(text, id, x, y, width, height, style, exStyle) \
3309 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_DEFPUSHBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3311 #define CONTROL_PUSHBOX(text, id, x, y, width, height, style, exStyle) \
3312 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_PUSHBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3313 #endif // !_WIN32_WCE
3314 #define CONTROL_STATE3(text, id, x, y, width, height, style, exStyle) \
3315 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
3316 #define CONTROL_AUTO3STATE(text, id, x, y, width, height, style, exStyle) \
3317 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTO3STATE | WS_TABSTOP, exStyle, text, NULL, 0);
3318 #define CONTROL_CHECKBOX(text, id, x, y, width, height, style, exStyle) \
3319 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_CHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3320 #define CONTROL_AUTOCHECKBOX(text, id, x, y, width, height, style, exStyle) \
3321 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTOCHECKBOX | WS_TABSTOP, exStyle, text, NULL, 0);
3322 #define CONTROL_RADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
3323 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_RADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3324 #define CONTROL_AUTORADIOBUTTON(text, id, x, y, width, height, style, exStyle) \
3325 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_AUTORADIOBUTTON | WS_TABSTOP, exStyle, text, NULL, 0);
3326 #define CONTROL_COMBOBOX(id, x, y, width, height, style, exStyle) \
3327 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_COMBOBOX, (WORD)id, x, y, width, height, style | CBS_DROPDOWN | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
3328 #define CONTROL_EDITTEXT(id, x, y, width, height, style, exStyle) \
3329 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_EDIT, (WORD)id, x, y, width, height, style | ES_LEFT | WS_BORDER | WS_TABSTOP, exStyle, (LPCTSTR)NULL, NULL, 0);
3330 #define CONTROL_GROUPBOX(text, id, x, y, width, height, style, exStyle) \
3331 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_BUTTON, (WORD)id, x, y, width, height, style | BS_GROUPBOX, exStyle, text, NULL, 0);
3332 #define CONTROL_LISTBOX(id, x, y, width, height, style, exStyle) \
3333 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_LISTBOX, (WORD)id, x, y, width, height, style | LBS_NOTIFY | WS_BORDER, exStyle, (LPCTSTR)NULL, NULL, 0);
3334 #define CONTROL_SCROLLBAR(id, x, y, width, height, style, exStyle) \
3335 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_SCROLLBAR, (WORD)id, x, y, width, height, style | SBS_HORZ, exStyle, (LPCTSTR)NULL, NULL, 0);
3336 #define CONTROL_ICON(text, id, x, y, width, height, style, exStyle) \
3337 m_Template.AddStdControl(WTL::CMemDlgTemplate::CTRL_STATIC, (WORD)id, x, y, width, height, style | SS_ICON, exStyle, text, NULL, 0);
3338 #define CONTROL_CONTROL(text, id, className, style, x, y, width, height, exStyle) \
3339 m_Template.AddControl(className, (WORD)id, x, y, width, height, style, exStyle, text, NULL, 0);
3342 ///////////////////////////////////////////////////////////////////////////////
3343 // CIndirectDialogImpl - dialogs with template in memory
3345 template <class T
, class TDlgTemplate
= CMemDlgTemplate
, class TBase
= ATL::CDialogImpl
<T
, ATL::CWindow
> >
3346 class ATL_NO_VTABLE CIndirectDialogImpl
: public TBase
3349 enum { IDD
= 0 }; // no dialog template resource
3351 TDlgTemplate m_Template
;
3353 void CreateTemplate()
3355 T
* pT
= static_cast<T
*>(this);
3356 pT
->DoInitTemplate();
3357 pT
->DoInitControls();
3360 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow(), LPARAM dwInitParam
= NULL
)
3362 T
* pT
= static_cast<T
*>(this);
3363 ATLASSERT(pT
->m_hWnd
== NULL
);
3365 if (!m_Template
.IsValid())
3368 #if (_ATL_VER >= 0x0800)
3369 // Allocate the thunk structure here, where we can fail gracefully.
3370 BOOL result
= m_thunk
.Init(NULL
, NULL
);
3371 if (result
== FALSE
)
3373 SetLastError(ERROR_OUTOFMEMORY
);
3376 #endif // (_ATL_VER >= 0x0800)
3378 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, pT
);
3384 return ::DialogBoxIndirectParam(ModuleHelper::GetResourceInstance(), m_Template
.GetTemplatePtr(), hWndParent
, (DLGPROC
)T::StartDialogProc
, dwInitParam
);
3387 HWND
Create(HWND hWndParent
, LPARAM dwInitParam
= NULL
)
3389 T
* pT
= static_cast<T
*>(this);
3390 ATLASSERT(pT
->m_hWnd
== NULL
);
3392 if (!m_Template
.IsValid())
3395 #if (_ATL_VER >= 0x0800)
3396 // Allocate the thunk structure here, where we can fail gracefully.
3397 BOOL result
= m_thunk
.Init(NULL
, NULL
);
3398 if (result
== FALSE
)
3400 SetLastError(ERROR_OUTOFMEMORY
);
3403 #endif // (_ATL_VER >= 0x0800)
3405 ModuleHelper::AddCreateWndData(&m_thunk
.cd
, pT
);
3411 HWND hWnd
= ::CreateDialogIndirectParam(ModuleHelper::GetResourceInstance(), (LPCDLGTEMPLATE
)m_Template
.GetTemplatePtr(), hWndParent
, (DLGPROC
)T::StartDialogProc
, dwInitParam
);
3412 ATLASSERT(m_hWnd
== hWnd
);
3418 HWND
Create(HWND hWndParent
, RECT
&, LPARAM dwInitParam
= NULL
)
3420 return Create(hWndParent
, dwInitParam
);
3423 void DoInitTemplate()
3425 ATLASSERT(FALSE
); // MUST be defined in derived class
3428 void DoInitControls()
3430 ATLASSERT(FALSE
); // MUST be defined in derived class
3434 ///////////////////////////////////////////////////////////////////////////////
3435 // CPropertySheetWindow - client side for a property sheet
3437 class CPropertySheetWindow
: public ATL::CWindow
3441 CPropertySheetWindow(HWND hWnd
= NULL
) : ATL::CWindow(hWnd
)
3444 CPropertySheetWindow
& operator =(HWND hWnd
)
3451 int GetPageCount() const
3453 ATLASSERT(::IsWindow(m_hWnd
));
3454 HWND hWndTabCtrl
= GetTabControl();
3455 ATLASSERT(hWndTabCtrl
!= NULL
);
3456 return (int)::SendMessage(hWndTabCtrl
, TCM_GETITEMCOUNT
, 0, 0L);
3459 HWND
GetActivePage() const
3461 ATLASSERT(::IsWindow(m_hWnd
));
3462 return (HWND
)::SendMessage(m_hWnd
, PSM_GETCURRENTPAGEHWND
, 0, 0L);
3465 int GetActiveIndex() const
3467 ATLASSERT(::IsWindow(m_hWnd
));
3468 HWND hWndTabCtrl
= GetTabControl();
3469 ATLASSERT(hWndTabCtrl
!= NULL
);
3470 return (int)::SendMessage(hWndTabCtrl
, TCM_GETCURSEL
, 0, 0L);
3473 BOOL
SetActivePage(int nPageIndex
)
3475 ATLASSERT(::IsWindow(m_hWnd
));
3476 return (BOOL
)::SendMessage(m_hWnd
, PSM_SETCURSEL
, nPageIndex
, 0L);
3479 BOOL
SetActivePage(HPROPSHEETPAGE hPage
)
3481 ATLASSERT(::IsWindow(m_hWnd
));
3482 ATLASSERT(hPage
!= NULL
);
3483 return (BOOL
)::SendMessage(m_hWnd
, PSM_SETCURSEL
, 0, (LPARAM
)hPage
);
3486 BOOL
SetActivePageByID(int nPageID
)
3488 ATLASSERT(::IsWindow(m_hWnd
));
3489 return (BOOL
)::SendMessage(m_hWnd
, PSM_SETCURSELID
, 0, nPageID
);
3492 void SetTitle(LPCTSTR lpszText
, UINT nStyle
= 0)
3494 ATLASSERT(::IsWindow(m_hWnd
));
3495 ATLASSERT((nStyle
& ~PSH_PROPTITLE
) == 0); // only PSH_PROPTITLE is valid
3496 ATLASSERT(lpszText
!= NULL
);
3497 ::SendMessage(m_hWnd
, PSM_SETTITLE
, nStyle
, (LPARAM
)lpszText
);
3500 HWND
GetTabControl() const
3502 ATLASSERT(::IsWindow(m_hWnd
));
3503 return (HWND
)::SendMessage(m_hWnd
, PSM_GETTABCONTROL
, 0, 0L);
3506 void SetFinishText(LPCTSTR lpszText
)
3508 ATLASSERT(::IsWindow(m_hWnd
));
3509 ::SendMessage(m_hWnd
, PSM_SETFINISHTEXT
, 0, (LPARAM
)lpszText
);
3512 void SetWizardButtons(DWORD dwFlags
)
3514 ATLASSERT(::IsWindow(m_hWnd
));
3515 ::PostMessage(m_hWnd
, PSM_SETWIZBUTTONS
, 0, dwFlags
);
3519 BOOL
AddPage(HPROPSHEETPAGE hPage
)
3521 ATLASSERT(::IsWindow(m_hWnd
));
3522 ATLASSERT(hPage
!= NULL
);
3523 return (BOOL
)::SendMessage(m_hWnd
, PSM_ADDPAGE
, 0, (LPARAM
)hPage
);
3526 BOOL
AddPage(LPCPROPSHEETPAGE pPage
)
3528 ATLASSERT(::IsWindow(m_hWnd
));
3529 ATLASSERT(pPage
!= NULL
);
3530 HPROPSHEETPAGE hPage
= ::CreatePropertySheetPage(pPage
);
3533 return (BOOL
)::SendMessage(m_hWnd
, PSM_ADDPAGE
, 0, (LPARAM
)hPage
);
3537 BOOL
InsertPage(int nNewPageIndex
, HPROPSHEETPAGE hPage
)
3539 ATLASSERT(::IsWindow(m_hWnd
));
3540 ATLASSERT(hPage
!= NULL
);
3541 return (BOOL
)::SendMessage(m_hWnd
, PSM_INSERTPAGE
, nNewPageIndex
, (LPARAM
)hPage
);
3544 BOOL
InsertPage(int nNewPageIndex
, LPCPROPSHEETPAGE pPage
)
3546 ATLASSERT(::IsWindow(m_hWnd
));
3547 ATLASSERT(pPage
!= NULL
);
3548 HPROPSHEETPAGE hPage
= ::CreatePropertySheetPage(pPage
);
3551 return (BOOL
)::SendMessage(m_hWnd
, PSM_INSERTPAGE
, nNewPageIndex
, (LPARAM
)hPage
);
3554 BOOL
InsertPage(HPROPSHEETPAGE hPageInsertAfter
, HPROPSHEETPAGE hPage
)
3556 ATLASSERT(::IsWindow(m_hWnd
));
3557 ATLASSERT(hPage
!= NULL
);
3558 return (BOOL
)::SendMessage(m_hWnd
, PSM_INSERTPAGE
, (WPARAM
)hPageInsertAfter
, (LPARAM
)hPage
);
3561 BOOL
InsertPage(HPROPSHEETPAGE hPageInsertAfter
, LPCPROPSHEETPAGE pPage
)
3563 ATLASSERT(::IsWindow(m_hWnd
));
3564 ATLASSERT(pPage
!= NULL
);
3565 HPROPSHEETPAGE hPage
= ::CreatePropertySheetPage(pPage
);
3568 return (BOOL
)::SendMessage(m_hWnd
, PSM_INSERTPAGE
, (WPARAM
)hPageInsertAfter
, (LPARAM
)hPage
);
3570 #endif // !_WIN32_WCE
3572 void RemovePage(int nPageIndex
)
3574 ATLASSERT(::IsWindow(m_hWnd
));
3575 ::SendMessage(m_hWnd
, PSM_REMOVEPAGE
, nPageIndex
, 0L);
3578 void RemovePage(HPROPSHEETPAGE hPage
)
3580 ATLASSERT(::IsWindow(m_hWnd
));
3581 ATLASSERT(hPage
!= NULL
);
3582 ::SendMessage(m_hWnd
, PSM_REMOVEPAGE
, 0, (LPARAM
)hPage
);
3585 BOOL
PressButton(int nButton
)
3587 ATLASSERT(::IsWindow(m_hWnd
));
3588 return (BOOL
)::SendMessage(m_hWnd
, PSM_PRESSBUTTON
, nButton
, 0L);
3593 ATLASSERT(::IsWindow(m_hWnd
));
3594 return (BOOL
)::SendMessage(m_hWnd
, PSM_APPLY
, 0, 0L);
3597 void CancelToClose()
3599 ATLASSERT(::IsWindow(m_hWnd
));
3600 ::SendMessage(m_hWnd
, PSM_CANCELTOCLOSE
, 0, 0L);
3603 void SetModified(HWND hWndPage
, BOOL bChanged
= TRUE
)
3605 ATLASSERT(::IsWindow(m_hWnd
));
3606 ATLASSERT(::IsWindow(hWndPage
));
3607 UINT uMsg
= bChanged
? PSM_CHANGED
: PSM_UNCHANGED
;
3608 ::SendMessage(m_hWnd
, uMsg
, (WPARAM
)hWndPage
, 0L);
3611 LRESULT
QuerySiblings(WPARAM wParam
, LPARAM lParam
)
3613 ATLASSERT(::IsWindow(m_hWnd
));
3614 return ::SendMessage(m_hWnd
, PSM_QUERYSIBLINGS
, wParam
, lParam
);
3619 ATLASSERT(::IsWindow(m_hWnd
));
3620 ::SendMessage(m_hWnd
, PSM_REBOOTSYSTEM
, 0, 0L);
3623 void RestartWindows()
3625 ATLASSERT(::IsWindow(m_hWnd
));
3626 ::SendMessage(m_hWnd
, PSM_RESTARTWINDOWS
, 0, 0L);
3629 BOOL
IsDialogMessage(LPMSG lpMsg
)
3631 ATLASSERT(::IsWindow(m_hWnd
));
3632 return (BOOL
)::SendMessage(m_hWnd
, PSM_ISDIALOGMESSAGE
, 0, (LPARAM
)lpMsg
);
3635 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3636 int HwndToIndex(HWND hWnd
) const
3638 ATLASSERT(::IsWindow(m_hWnd
));
3639 return (int)::SendMessage(m_hWnd
, PSM_HWNDTOINDEX
, (WPARAM
)hWnd
, 0L);
3642 HWND
IndexToHwnd(int nIndex
) const
3644 ATLASSERT(::IsWindow(m_hWnd
));
3645 return (HWND
)::SendMessage(m_hWnd
, PSM_INDEXTOHWND
, nIndex
, 0L);
3648 int PageToIndex(HPROPSHEETPAGE hPage
) const
3650 ATLASSERT(::IsWindow(m_hWnd
));
3651 return (int)::SendMessage(m_hWnd
, PSM_PAGETOINDEX
, 0, (LPARAM
)hPage
);
3654 HPROPSHEETPAGE
IndexToPage(int nIndex
) const
3656 ATLASSERT(::IsWindow(m_hWnd
));
3657 return (HPROPSHEETPAGE
)::SendMessage(m_hWnd
, PSM_INDEXTOPAGE
, nIndex
, 0L);
3660 int IdToIndex(int nID
) const
3662 ATLASSERT(::IsWindow(m_hWnd
));
3663 return (int)::SendMessage(m_hWnd
, PSM_IDTOINDEX
, 0, nID
);
3666 int IndexToId(int nIndex
) const
3668 ATLASSERT(::IsWindow(m_hWnd
));
3669 return (int)::SendMessage(m_hWnd
, PSM_INDEXTOID
, nIndex
, 0L);
3672 int GetResult() const
3674 ATLASSERT(::IsWindow(m_hWnd
));
3675 return (int)::SendMessage(m_hWnd
, PSM_GETRESULT
, 0, 0L);
3678 BOOL
RecalcPageSizes()
3680 ATLASSERT(::IsWindow(m_hWnd
));
3681 return (BOOL
)::SendMessage(m_hWnd
, PSM_RECALCPAGESIZES
, 0, 0L);
3684 void SetHeaderTitle(int nIndex
, LPCTSTR lpstrHeaderTitle
)
3686 ATLASSERT(::IsWindow(m_hWnd
));
3687 ::SendMessage(m_hWnd
, PSM_SETHEADERTITLE
, nIndex
, (LPARAM
)lpstrHeaderTitle
);
3690 void SetHeaderSubTitle(int nIndex
, LPCTSTR lpstrHeaderSubTitle
)
3692 ATLASSERT(::IsWindow(m_hWnd
));
3693 ::SendMessage(m_hWnd
, PSM_SETHEADERSUBTITLE
, nIndex
, (LPARAM
)lpstrHeaderSubTitle
);
3695 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
3697 // Implementation - override to prevent usage
3698 HWND
Create(LPCTSTR
, HWND
, ATL::_U_RECT
= NULL
, LPCTSTR
= NULL
, DWORD
= 0, DWORD
= 0, ATL::_U_MENUorID
= 0U, LPVOID
= NULL
)
3705 ///////////////////////////////////////////////////////////////////////////////
3706 // CPropertySheetImpl - implements a property sheet
3708 template <class T
, class TBase
= CPropertySheetWindow
>
3709 class ATL_NO_VTABLE CPropertySheetImpl
: public ATL::CWindowImplBaseT
< TBase
>
3712 PROPSHEETHEADER m_psh
;
3713 ATL::CSimpleArray
<HPROPSHEETPAGE
> m_arrPages
;
3715 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
3716 #ifndef PROPSHEET_LINK_SIZE
3717 #define PROPSHEET_LINK_SIZE 128
3718 #endif // PROPSHEET_LINK_SIZE
3719 TCHAR m_szLink
[PROPSHEET_LINK_SIZE
];
3720 static LPCTSTR m_pszTitle
;
3721 static LPCTSTR m_pszLink
;
3722 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
3724 // Construction/Destruction
3725 CPropertySheetImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
, UINT uStartPage
= 0, HWND hWndParent
= NULL
)
3727 memset(&m_psh
, 0, sizeof(PROPSHEETHEADER
));
3728 m_psh
.dwSize
= sizeof(PROPSHEETHEADER
);
3729 m_psh
.dwFlags
= PSH_USECALLBACK
;
3730 m_psh
.hInstance
= ModuleHelper::GetResourceInstance();
3731 m_psh
.phpage
= NULL
; // will be set later
3732 m_psh
.nPages
= 0; // will be set later
3733 m_psh
.pszCaption
= title
.m_lpstr
;
3734 m_psh
.nStartPage
= uStartPage
;
3735 m_psh
.hwndParent
= hWndParent
; // if NULL, will be set in DoModal/Create
3736 m_psh
.pfnCallback
= T::PropSheetCallback
;
3738 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
3739 m_psh
.dwFlags
|= PSH_MAXIMIZE
;
3741 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
3744 ~CPropertySheetImpl()
3746 if(m_arrPages
.GetSize() > 0) // sheet never created, destroy all pages
3748 for(int i
= 0; i
< m_arrPages
.GetSize(); i
++)
3749 ::DestroyPropertySheetPage((HPROPSHEETPAGE
)m_arrPages
[i
]);
3753 // Callback function and overrideables
3754 static int CALLBACK
PropSheetCallback(HWND hWnd
, UINT uMsg
, LPARAM lParam
)
3756 lParam
; // avoid level 4 warning
3759 if(uMsg
== PSCB_INITIALIZED
)
3761 ATLASSERT(hWnd
!= NULL
);
3762 T
* pT
= (T
*)ModuleHelper::ExtractCreateWndData();
3763 // subclass the sheet window
3764 pT
->SubclassWindow(hWnd
);
3765 // remove page handles array
3766 pT
->_CleanUpPages();
3768 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
3769 m_pszTitle
= pT
->m_psh
.pszCaption
;
3770 if(*pT
->m_szLink
!= 0)
3771 m_pszLink
= pT
->m_szLink
;
3772 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific
3774 pT
->OnSheetInitialized();
3776 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific uMsg
3781 case PSCB_GETVERSION
:
3782 nRet
= COMCTL32_VERSION
;
3784 case PSCB_GETTITLE
:
3785 if(m_pszTitle
!= NULL
)
3787 lstrcpy((LPTSTR
)lParam
, m_pszTitle
);
3791 case PSCB_GETLINKTEXT
:
3792 if(m_pszLink
!= NULL
)
3794 lstrcpy((LPTSTR
)lParam
, m_pszLink
);
3802 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
3807 void OnSheetInitialized()
3812 HWND
Create(HWND hWndParent
= NULL
)
3814 ATLASSERT(m_hWnd
== NULL
);
3816 m_psh
.dwFlags
|= PSH_MODELESS
;
3817 if(m_psh
.hwndParent
== NULL
)
3818 m_psh
.hwndParent
= hWndParent
;
3819 m_psh
.phpage
= (HPROPSHEETPAGE
*)m_arrPages
.GetData();
3820 m_psh
.nPages
= m_arrPages
.GetSize();
3822 T
* pT
= static_cast<T
*>(this);
3823 ModuleHelper::AddCreateWndData(&pT
->m_thunk
.cd
, pT
);
3825 HWND hWnd
= (HWND
)::PropertySheet(&m_psh
);
3826 _CleanUpPages(); // ensure clean-up, required if call failed
3828 ATLASSERT(m_hWnd
== hWnd
);
3833 INT_PTR
DoModal(HWND hWndParent
= ::GetActiveWindow())
3835 ATLASSERT(m_hWnd
== NULL
);
3837 m_psh
.dwFlags
&= ~PSH_MODELESS
;
3838 if(m_psh
.hwndParent
== NULL
)
3839 m_psh
.hwndParent
= hWndParent
;
3840 m_psh
.phpage
= (HPROPSHEETPAGE
*)m_arrPages
.GetData();
3841 m_psh
.nPages
= m_arrPages
.GetSize();
3843 T
* pT
= static_cast<T
*>(this);
3844 ModuleHelper::AddCreateWndData(&pT
->m_thunk
.cd
, pT
);
3846 INT_PTR nRet
= ::PropertySheet(&m_psh
);
3847 _CleanUpPages(); // ensure clean-up, required if call failed
3852 // implementation helper - clean up pages array
3853 void _CleanUpPages()
3856 m_psh
.phpage
= NULL
;
3857 m_arrPages
.RemoveAll();
3860 // Attributes (extended overrides of client class methods)
3861 // These now can be called before the sheet is created
3862 // Note: Calling these after the sheet is created gives unpredictable results
3863 int GetPageCount() const
3865 if(m_hWnd
== NULL
) // not created yet
3866 return m_arrPages
.GetSize();
3867 return TBase::GetPageCount();
3870 int GetActiveIndex() const
3872 if(m_hWnd
== NULL
) // not created yet
3873 return m_psh
.nStartPage
;
3874 return TBase::GetActiveIndex();
3877 HPROPSHEETPAGE
GetPage(int nPageIndex
) const
3879 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
3880 return (HPROPSHEETPAGE
)m_arrPages
[nPageIndex
];
3883 int GetPageIndex(HPROPSHEETPAGE hPage
) const
3885 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
3886 return m_arrPages
.Find((HPROPSHEETPAGE
&)hPage
);
3889 BOOL
SetActivePage(int nPageIndex
)
3891 if(m_hWnd
== NULL
) // not created yet
3893 ATLASSERT(nPageIndex
>= 0 && nPageIndex
< m_arrPages
.GetSize());
3894 m_psh
.nStartPage
= nPageIndex
;
3897 return TBase::SetActivePage(nPageIndex
);
3900 BOOL
SetActivePage(HPROPSHEETPAGE hPage
)
3902 ATLASSERT(hPage
!= NULL
);
3903 if (m_hWnd
== NULL
) // not created yet
3905 int nPageIndex
= GetPageIndex(hPage
);
3906 if(nPageIndex
== -1)
3909 return SetActivePage(nPageIndex
);
3911 return TBase::SetActivePage(hPage
);
3915 void SetTitle(LPCTSTR lpszText
, UINT nStyle
= 0)
3917 ATLASSERT((nStyle
& ~PSH_PROPTITLE
) == 0); // only PSH_PROPTITLE is valid
3918 ATLASSERT(lpszText
!= NULL
);
3922 // set internal state
3923 m_psh
.pszCaption
= lpszText
; // must exist until sheet is created
3924 m_psh
.dwFlags
&= ~PSH_PROPTITLE
;
3925 m_psh
.dwFlags
|= nStyle
;
3929 // set external state
3930 TBase::SetTitle(lpszText
, nStyle
);
3934 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC specific Link field
3935 void SetLinkText(LPCTSTR lpszText
)
3937 ATLASSERT(lpszText
!= NULL
);
3938 ATLASSERT(lstrlen(lpszText
) < PROPSHEET_LINK_SIZE
);
3939 lstrcpy(m_szLink
, lpszText
);
3941 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
3943 void SetWizardMode()
3945 m_psh
.dwFlags
|= PSH_WIZARD
;
3950 m_psh
.dwFlags
|= PSH_HASHELP
;
3954 BOOL
AddPage(HPROPSHEETPAGE hPage
)
3956 ATLASSERT(hPage
!= NULL
);
3959 bRet
= TBase::AddPage(hPage
);
3960 else // sheet not created yet, use internal data
3961 bRet
= m_arrPages
.Add((HPROPSHEETPAGE
&)hPage
);
3965 BOOL
AddPage(LPCPROPSHEETPAGE pPage
)
3967 ATLASSERT(pPage
!= NULL
);
3968 HPROPSHEETPAGE hPage
= ::CreatePropertySheetPage(pPage
);
3971 BOOL bRet
= AddPage(hPage
);
3973 ::DestroyPropertySheetPage(hPage
);
3977 BOOL
RemovePage(HPROPSHEETPAGE hPage
)
3979 ATLASSERT(hPage
!= NULL
);
3980 if (m_hWnd
== NULL
) // not created yet
3982 int nPage
= GetPageIndex(hPage
);
3985 return RemovePage(nPage
);
3987 TBase::RemovePage(hPage
);
3992 BOOL
RemovePage(int nPageIndex
)
3996 TBase::RemovePage(nPageIndex
);
3997 else // sheet not created yet, use internal data
3998 bRet
= m_arrPages
.RemoveAt(nPageIndex
);
4002 #if (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4003 void SetHeader(LPCTSTR szbmHeader
)
4005 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4007 m_psh
.dwFlags
&= ~PSH_WIZARD
;
4008 m_psh
.dwFlags
|= (PSH_HEADER
| PSH_WIZARD97
);
4009 m_psh
.pszbmHeader
= szbmHeader
;
4012 void SetHeader(HBITMAP hbmHeader
)
4014 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4016 m_psh
.dwFlags
&= ~PSH_WIZARD
;
4017 m_psh
.dwFlags
|= (PSH_HEADER
| PSH_USEHBMHEADER
| PSH_WIZARD97
);
4018 m_psh
.hbmHeader
= hbmHeader
;
4021 void SetWatermark(LPCTSTR szbmWatermark
, HPALETTE hplWatermark
= NULL
)
4023 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4025 m_psh
.dwFlags
&= ~PSH_WIZARD
;
4026 m_psh
.dwFlags
|= PSH_WATERMARK
| PSH_WIZARD97
;
4027 m_psh
.pszbmWatermark
= szbmWatermark
;
4029 if (hplWatermark
!= NULL
)
4031 m_psh
.dwFlags
|= PSH_USEHPLWATERMARK
;
4032 m_psh
.hplWatermark
= hplWatermark
;
4036 void SetWatermark(HBITMAP hbmWatermark
, HPALETTE hplWatermark
= NULL
)
4038 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4040 m_psh
.dwFlags
&= ~PSH_WIZARD
;
4041 m_psh
.dwFlags
|= (PSH_WATERMARK
| PSH_USEHBMWATERMARK
| PSH_WIZARD97
);
4042 m_psh
.hbmWatermark
= hbmWatermark
;
4044 if (hplWatermark
!= NULL
)
4046 m_psh
.dwFlags
|= PSH_USEHPLWATERMARK
;
4047 m_psh
.hplWatermark
= hplWatermark
;
4051 void StretchWatermark(bool bStretchWatermark
)
4053 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4054 if (bStretchWatermark
)
4055 m_psh
.dwFlags
|= PSH_STRETCHWATERMARK
;
4057 m_psh
.dwFlags
&= ~PSH_STRETCHWATERMARK
;
4059 #endif // (_WIN32_IE >= 0x0400) && !defined(_WIN32_WCE)
4061 // Message map and handlers
4062 BEGIN_MSG_MAP(CPropertySheetImpl
)
4063 MESSAGE_HANDLER(WM_COMMAND
, OnCommand
)
4064 MESSAGE_HANDLER(WM_SYSCOMMAND
, OnSysCommand
)
4067 LRESULT
OnCommand(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
& /*bHandled*/)
4069 LRESULT lRet
= DefWindowProc(uMsg
, wParam
, lParam
);
4070 if(HIWORD(wParam
) == BN_CLICKED
&& (LOWORD(wParam
) == IDOK
|| LOWORD(wParam
) == IDCANCEL
) &&
4071 ((m_psh
.dwFlags
& PSH_MODELESS
) != 0) && (GetActivePage() == NULL
))
4076 LRESULT
OnSysCommand(UINT
/*uMsg*/, WPARAM wParam
, LPARAM
/*lParam*/, BOOL
& bHandled
)
4078 if(((m_psh
.dwFlags
& PSH_MODELESS
) == PSH_MODELESS
) && ((wParam
& 0xFFF0) == SC_CLOSE
))
4079 SendMessage(WM_CLOSE
);
4086 #if defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__) // PPC static pointers
4087 template < class T
, class TBase
>
4088 LPCWSTR CPropertySheetImpl
<T
,TBase
>::m_pszTitle
= NULL
;
4089 template < class T
, class TBase
>
4090 LPCWSTR CPropertySheetImpl
<T
,TBase
>::m_pszLink
= NULL
;
4091 #endif // defined(_AYGSHELL_H_) || defined(__AYGSHELL_H__)
4093 // for non-customized sheets
4094 class CPropertySheet
: public CPropertySheetImpl
<CPropertySheet
>
4097 CPropertySheet(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
, UINT uStartPage
= 0, HWND hWndParent
= NULL
)
4098 : CPropertySheetImpl
<CPropertySheet
>(title
, uStartPage
, hWndParent
)
4103 ///////////////////////////////////////////////////////////////////////////////
4104 // CPropertyPageWindow - client side for a property page
4106 class CPropertyPageWindow
: public ATL::CWindow
4110 CPropertyPageWindow(HWND hWnd
= NULL
) : ATL::CWindow(hWnd
)
4113 CPropertyPageWindow
& operator =(HWND hWnd
)
4120 CPropertySheetWindow
GetPropertySheet() const
4122 ATLASSERT(::IsWindow(m_hWnd
));
4123 return CPropertySheetWindow(GetParent());
4129 ATLASSERT(::IsWindow(m_hWnd
));
4130 ATLASSERT(GetParent() != NULL
);
4131 return GetPropertySheet().Apply();
4134 void CancelToClose()
4136 ATLASSERT(::IsWindow(m_hWnd
));
4137 ATLASSERT(GetParent() != NULL
);
4138 GetPropertySheet().CancelToClose();
4141 void SetModified(BOOL bChanged
= TRUE
)
4143 ATLASSERT(::IsWindow(m_hWnd
));
4144 ATLASSERT(GetParent() != NULL
);
4145 GetPropertySheet().SetModified(m_hWnd
, bChanged
);
4148 LRESULT
QuerySiblings(WPARAM wParam
, LPARAM lParam
)
4150 ATLASSERT(::IsWindow(m_hWnd
));
4151 ATLASSERT(GetParent() != NULL
);
4152 return GetPropertySheet().QuerySiblings(wParam
, lParam
);
4157 ATLASSERT(::IsWindow(m_hWnd
));
4158 ATLASSERT(GetParent() != NULL
);
4159 GetPropertySheet().RebootSystem();
4162 void RestartWindows()
4164 ATLASSERT(::IsWindow(m_hWnd
));
4165 ATLASSERT(GetParent() != NULL
);
4166 GetPropertySheet().RestartWindows();
4169 void SetWizardButtons(DWORD dwFlags
)
4171 ATLASSERT(::IsWindow(m_hWnd
));
4172 ATLASSERT(GetParent() != NULL
);
4173 GetPropertySheet().SetWizardButtons(dwFlags
);
4176 // Implementation - overrides to prevent usage
4177 HWND
Create(LPCTSTR
, HWND
, ATL::_U_RECT
= NULL
, LPCTSTR
= NULL
, DWORD
= 0, DWORD
= 0, ATL::_U_MENUorID
= 0U, LPVOID
= NULL
)
4184 ///////////////////////////////////////////////////////////////////////////////
4185 // CPropertyPageImpl - implements a property page
4187 template <class T
, class TBase
= CPropertyPageWindow
>
4188 class ATL_NO_VTABLE CPropertyPageImpl
: public ATL::CDialogImplBaseT
< TBase
>
4191 PROPSHEETPAGE m_psp
;
4193 operator PROPSHEETPAGE
*() { return &m_psp
; }
4196 CPropertyPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
)
4198 // initialize PROPSHEETPAGE struct
4199 memset(&m_psp
, 0, sizeof(PROPSHEETPAGE
));
4200 m_psp
.dwSize
= sizeof(PROPSHEETPAGE
);
4201 m_psp
.dwFlags
= PSP_USECALLBACK
;
4202 m_psp
.hInstance
= ModuleHelper::GetResourceInstance();
4203 T
* pT
= static_cast<T
*>(this);
4204 m_psp
.pszTemplate
= MAKEINTRESOURCE(pT
->IDD
);
4205 m_psp
.pfnDlgProc
= (DLGPROC
)T::StartDialogProc
;
4206 m_psp
.pfnCallback
= T::PropPageCallback
;
4207 m_psp
.lParam
= (LPARAM
)pT
;
4209 if(title
.m_lpstr
!= NULL
)
4213 // Callback function and overrideables
4214 static UINT CALLBACK
PropPageCallback(HWND hWnd
, UINT uMsg
, LPPROPSHEETPAGE ppsp
)
4216 hWnd
; // avoid level 4 warning
4217 ATLASSERT(hWnd
== NULL
);
4218 T
* pT
= (T
*)ppsp
->lParam
;
4225 ATL::CDialogImplBaseT
< TBase
>* pPage
= (ATL::CDialogImplBaseT
< TBase
>*)pT
;
4226 ModuleHelper::AddCreateWndData(&pPage
->m_thunk
.cd
, pPage
);
4227 uRet
= pT
->OnPageCreate() ? 1 : 0;
4230 #if (_WIN32_IE >= 0x0500)
4234 #endif // (_WIN32_IE >= 0x0500)
4236 pT
->OnPageRelease();
4247 return true; // true - allow page to be created, false - prevent creation
4250 #if (_WIN32_IE >= 0x0500)
4254 #endif // (_WIN32_IE >= 0x0500)
4256 void OnPageRelease()
4261 HPROPSHEETPAGE
Create()
4263 return ::CreatePropertySheetPage(&m_psp
);
4267 void SetTitle(ATL::_U_STRINGorID title
)
4269 m_psp
.pszTitle
= title
.m_lpstr
;
4270 m_psp
.dwFlags
|= PSP_USETITLE
;
4273 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4274 void SetHeaderTitle(LPCTSTR lpstrHeaderTitle
)
4276 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4277 m_psp
.dwFlags
|= PSP_USEHEADERTITLE
;
4278 m_psp
.pszHeaderTitle
= lpstrHeaderTitle
;
4281 void SetHeaderSubTitle(LPCTSTR lpstrHeaderSubTitle
)
4283 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
4284 m_psp
.dwFlags
|= PSP_USEHEADERSUBTITLE
;
4285 m_psp
.pszHeaderSubTitle
= lpstrHeaderSubTitle
;
4287 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4292 m_psp
.dwFlags
|= PSP_HASHELP
;
4295 // Message map and handlers
4296 BEGIN_MSG_MAP(CPropertyPageImpl
)
4297 MESSAGE_HANDLER(WM_NOTIFY
, OnNotify
)
4300 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
4301 // handlers that return direct values without any restrictions
4302 LRESULT
OnNotify(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM lParam
, BOOL
& bHandled
)
4305 // This notification is sometimes received on Windows CE after the window is already destroyed
4306 ATLASSERT(::IsWindow(m_hWnd
));
4308 NMHDR
* pNMHDR
= (NMHDR
*)lParam
;
4310 // don't handle messages not from the page/sheet itself
4311 if(pNMHDR
->hwndFrom
!= m_hWnd
&& pNMHDR
->hwndFrom
!= ::GetParent(m_hWnd
))
4317 ATLASSERT(::IsWindow(m_hWnd
));
4320 T
* pT
= static_cast<T
*>(this);
4321 LRESULT lResult
= 0;
4322 switch(pNMHDR
->code
)
4324 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
4326 lResult
= pT
->OnSetActive();
4328 case PSN_KILLACTIVE
:
4329 lResult
= pT
->OnKillActive();
4332 lResult
= pT
->OnApply();
4337 case PSN_QUERYCANCEL
:
4338 lResult
= pT
->OnQueryCancel();
4341 lResult
= pT
->OnWizardNext();
4344 lResult
= pT
->OnWizardBack();
4347 lResult
= pT
->OnWizardFinish();
4353 #if (_WIN32_IE >= 0x0400)
4355 if(!pT
->OnGetObject((LPNMOBJECTNOTIFY
)lParam
))
4358 #endif // (_WIN32_IE >= 0x0400)
4359 #if (_WIN32_IE >= 0x0500)
4360 case PSN_TRANSLATEACCELERATOR
:
4362 LPPSHNOTIFY lpPSHNotify
= (LPPSHNOTIFY
)lParam
;
4363 lResult
= pT
->OnTranslateAccelerator((LPMSG
)lpPSHNotify
->lParam
);
4366 case PSN_QUERYINITIALFOCUS
:
4368 LPPSHNOTIFY lpPSHNotify
= (LPPSHNOTIFY
)lParam
;
4369 lResult
= (LRESULT
)pT
->OnQueryInitialFocus((HWND
)lpPSHNotify
->lParam
);
4372 #endif // (_WIN32_IE >= 0x0500)
4373 #endif // !_WIN32_WCE
4375 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4377 lResult
= pT
->OnSetActive() ? 0 : -1;
4379 case PSN_KILLACTIVE
:
4380 lResult
= !pT
->OnKillActive();
4383 lResult
= pT
->OnApply() ? PSNRET_NOERROR
: PSNRET_INVALID_NOCHANGEPAGE
;
4388 case PSN_QUERYCANCEL
:
4389 lResult
= !pT
->OnQueryCancel();
4392 lResult
= pT
->OnWizardNext();
4395 lResult
= pT
->OnWizardBack();
4398 lResult
= !pT
->OnWizardFinish();
4404 #if (_WIN32_IE >= 0x0400)
4406 if(!pT
->OnGetObject((LPNMOBJECTNOTIFY
)lParam
))
4409 #endif // (_WIN32_IE >= 0x0400)
4410 #if (_WIN32_IE >= 0x0500)
4411 case PSN_TRANSLATEACCELERATOR
:
4413 LPPSHNOTIFY lpPSHNotify
= (LPPSHNOTIFY
)lParam
;
4414 lResult
= pT
->OnTranslateAccelerator((LPMSG
)lpPSHNotify
->lParam
) ? PSNRET_MESSAGEHANDLED
: PSNRET_NOERROR
;
4417 case PSN_QUERYINITIALFOCUS
:
4419 LPPSHNOTIFY lpPSHNotify
= (LPPSHNOTIFY
)lParam
;
4420 lResult
= (LRESULT
)pT
->OnQueryInitialFocus((HWND
)lpPSHNotify
->lParam
);
4423 #endif // (_WIN32_IE >= 0x0500)
4424 #endif // !_WIN32_WCE
4426 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4428 bHandled
= FALSE
; // not handled
4435 // NOTE: Define _WTL_NEW_PAGE_NOTIFY_HANDLERS to use new notification
4436 // handlers that return direct values without any restrictions
4437 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
4440 // 0 = allow activate
4441 // -1 = go back that was active
4442 // page ID = jump to page
4448 // FALSE = allow deactivate
4449 // TRUE = prevent deactivation
4455 // PSNRET_NOERROR = apply OK
4456 // PSNRET_INVALID = apply not OK, return to this page
4457 // PSNRET_INVALID_NOCHANGEPAGE = apply not OK, don't change focus
4458 return PSNRET_NOERROR
;
4465 BOOL
OnQueryCancel()
4467 // FALSE = allow cancel
4468 // TRUE = prevent cancel
4474 // 0 = goto previous page
4475 // -1 = prevent page change
4476 // >0 = jump to page by dlg ID
4482 // 0 = goto next page
4483 // -1 = prevent page change
4484 // >0 = jump to page by dlg ID
4488 INT_PTR
OnWizardFinish()
4490 // FALSE = allow finish
4491 // TRUE = prevent finish
4492 // HWND = prevent finish and set focus to HWND (CommCtrl 5.80 only)
4501 #if (_WIN32_IE >= 0x0400)
4502 BOOL
OnGetObject(LPNMOBJECTNOTIFY
/*lpObjectNotify*/)
4504 return FALSE
; // not processed
4506 #endif // (_WIN32_IE >= 0x0400)
4508 #if (_WIN32_IE >= 0x0500)
4509 int OnTranslateAccelerator(LPMSG
/*lpMsg*/)
4511 // PSNRET_NOERROR - message not handled
4512 // PSNRET_MESSAGEHANDLED - message handled
4513 return PSNRET_NOERROR
;
4516 HWND
OnQueryInitialFocus(HWND
/*hWndFocus*/)
4518 // NULL = set focus to default control
4519 // HWND = set focus to HWND
4522 #endif // (_WIN32_IE >= 0x0500)
4523 #endif // !_WIN32_WCE
4525 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4545 BOOL
OnQueryCancel()
4547 return TRUE
; // ok to cancel
4552 // 0 = goto previous page
4553 // -1 = prevent page change
4554 // >0 = jump to page by dlg ID
4560 // 0 = goto next page
4561 // -1 = prevent page change
4562 // >0 = jump to page by dlg ID
4566 BOOL
OnWizardFinish()
4576 #if (_WIN32_IE >= 0x0400)
4577 BOOL
OnGetObject(LPNMOBJECTNOTIFY
/*lpObjectNotify*/)
4579 return FALSE
; // not processed
4581 #endif // (_WIN32_IE >= 0x0400)
4583 #if (_WIN32_IE >= 0x0500)
4584 BOOL
OnTranslateAccelerator(LPMSG
/*lpMsg*/)
4586 return FALSE
; // not translated
4589 HWND
OnQueryInitialFocus(HWND
/*hWndFocus*/)
4591 return NULL
; // default
4593 #endif // (_WIN32_IE >= 0x0500)
4594 #endif // !_WIN32_WCE
4596 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4599 // for non-customized pages
4600 template <WORD t_wDlgTemplateID
>
4601 class CPropertyPage
: public CPropertyPageImpl
<CPropertyPage
<t_wDlgTemplateID
> >
4604 enum { IDD
= t_wDlgTemplateID
};
4606 CPropertyPage(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CPropertyPageImpl
<CPropertyPage
>(title
)
4609 DECLARE_EMPTY_MSG_MAP()
4612 ///////////////////////////////////////////////////////////////////////////////
4613 // CAxPropertyPageImpl - property page that hosts ActiveX controls
4615 #ifndef _ATL_NO_HOSTING
4617 // Note: You must #include <atlhost.h> to use these classes
4619 template <class T
, class TBase
= CPropertyPageWindow
>
4620 class ATL_NO_VTABLE CAxPropertyPageImpl
: public CPropertyPageImpl
< T
, TBase
>
4624 HGLOBAL m_hInitData
;
4626 HGLOBAL m_hDlgResSplit
;
4628 // Constructor/destructor
4629 CAxPropertyPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) :
4630 CPropertyPageImpl
< T
, TBase
>(title
),
4631 m_hInitData(NULL
), m_hDlgRes(NULL
), m_hDlgResSplit(NULL
)
4633 T
* pT
= static_cast<T
*>(this);
4634 pT
; // avoid level 4 warning
4636 // initialize ActiveX hosting and modify dialog template
4637 ATL::AtlAxWinInit();
4639 HINSTANCE hInstance
= ModuleHelper::GetResourceInstance();
4640 LPCTSTR lpTemplateName
= MAKEINTRESOURCE(pT
->IDD
);
4641 HRSRC hDlg
= ::FindResource(hInstance
, lpTemplateName
, (LPTSTR
)RT_DIALOG
);
4644 HRSRC hDlgInit
= ::FindResource(hInstance
, lpTemplateName
, (LPTSTR
)_ATL_RT_DLGINIT
);
4646 BYTE
* pInitData
= NULL
;
4647 if(hDlgInit
!= NULL
)
4649 m_hInitData
= ::LoadResource(hInstance
, hDlgInit
);
4650 pInitData
= (BYTE
*)::LockResource(m_hInitData
);
4653 m_hDlgRes
= ::LoadResource(hInstance
, hDlg
);
4654 DLGTEMPLATE
* pDlg
= (DLGTEMPLATE
*)::LockResource(m_hDlgRes
);
4655 LPCDLGTEMPLATE lpDialogTemplate
= ATL::_DialogSplitHelper::SplitDialogTemplate(pDlg
, pInitData
);
4656 if(lpDialogTemplate
!= pDlg
)
4657 m_hDlgResSplit
= GlobalHandle(lpDialogTemplate
);
4659 // set up property page to use in-memory dialog template
4660 if(lpDialogTemplate
!= NULL
)
4662 m_psp
.dwFlags
|= PSP_DLGINDIRECT
;
4663 m_psp
.pResource
= lpDialogTemplate
;
4667 ATLASSERT(FALSE
&& _T("CAxPropertyPageImpl - ActiveX initializtion failed!"));
4672 ATLASSERT(FALSE
&& _T("CAxPropertyPageImpl - Cannot find dialog template!"));
4676 ~CAxPropertyPageImpl()
4678 if(m_hInitData
!= NULL
)
4680 UnlockResource(m_hInitData
);
4681 FreeResource(m_hInitData
);
4683 if(m_hDlgRes
!= NULL
)
4685 UnlockResource(m_hDlgRes
);
4686 FreeResource(m_hDlgRes
);
4688 if(m_hDlgResSplit
!= NULL
)
4690 ::GlobalFree(m_hDlgResSplit
);
4695 // call this one to handle keyboard message for ActiveX controls
4696 BOOL
PreTranslateMessage(LPMSG pMsg
)
4698 if ((pMsg
->message
< WM_KEYFIRST
|| pMsg
->message
> WM_KEYLAST
) &&
4699 (pMsg
->message
< WM_MOUSEFIRST
|| pMsg
->message
> WM_MOUSELAST
))
4701 // find a direct child of the dialog from the window that has focus
4702 HWND hWndCtl
= ::GetFocus();
4703 if (IsChild(hWndCtl
) && ::GetParent(hWndCtl
) != m_hWnd
)
4707 hWndCtl
= ::GetParent(hWndCtl
);
4709 while (::GetParent(hWndCtl
) != m_hWnd
);
4711 // give controls a chance to translate this message
4712 return (BOOL
)::SendMessage(hWndCtl
, WM_FORWARDMSG
, 0, (LPARAM
)pMsg
);
4716 #if (_WIN32_IE >= 0x0500)
4717 // new default implementation for ActiveX hosting pages
4718 #ifdef _WTL_NEW_PAGE_NOTIFY_HANDLERS
4719 int OnTranslateAccelerator(LPMSG lpMsg
)
4721 T
* pT
= static_cast<T
*>(this);
4722 return (pT
->PreTranslateMessage(lpMsg
) != FALSE
) ? PSNRET_MESSAGEHANDLED
: PSNRET_NOERROR
;
4724 #else // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4725 BOOL
OnTranslateAccelerator(LPMSG lpMsg
)
4727 T
* pT
= static_cast<T
*>(this);
4728 return pT
->PreTranslateMessage(lpMsg
);
4730 #endif // !_WTL_NEW_PAGE_NOTIFY_HANDLERS
4731 #endif // (_WIN32_IE >= 0x0500)
4733 // Support for new stuff in ATL7
4734 #if (_ATL_VER >= 0x0700)
4737 return( static_cast<T
*>(this)->IDD
);
4740 virtual DLGPROC
GetDialogProc()
4745 static INT_PTR CALLBACK
DialogProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
4747 CAxPropertyPageImpl
< T
, TBase
>* pThis
= (CAxPropertyPageImpl
< T
, TBase
>*)hWnd
;
4748 if (uMsg
== WM_INITDIALOG
)
4751 if (FAILED(hr
= pThis
->CreateActiveXControls(pThis
->GetIDD())))
4757 return CPropertyPageImpl
< T
, TBase
>::DialogProc(hWnd
, uMsg
, wParam
, lParam
);
4760 // ActiveX controls creation
4761 virtual HRESULT
CreateActiveXControls(UINT nID
)
4763 // Load dialog template and InitData
4764 HRSRC hDlgInit
= ::FindResource(ATL::_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(nID
), (LPTSTR
)_ATL_RT_DLGINIT
);
4765 BYTE
* pInitData
= NULL
;
4766 HGLOBAL hData
= NULL
;
4768 if (hDlgInit
!= NULL
)
4770 hData
= ::LoadResource(ATL::_AtlBaseModule
.GetResourceInstance(), hDlgInit
);
4772 pInitData
= (BYTE
*) ::LockResource(hData
);
4775 HRSRC hDlg
= ::FindResource(ATL::_AtlBaseModule
.GetResourceInstance(), MAKEINTRESOURCE(nID
), (LPTSTR
)RT_DIALOG
);
4778 HGLOBAL hResource
= ::LoadResource(ATL::_AtlBaseModule
.GetResourceInstance(), hDlg
);
4779 DLGTEMPLATE
* pDlg
= NULL
;
4780 if (hResource
!= NULL
)
4782 pDlg
= (DLGTEMPLATE
*) ::LockResource(hResource
);
4785 // Get first control on the template
4786 BOOL bDialogEx
= ATL::_DialogSplitHelper::IsDialogEx(pDlg
);
4787 WORD nItems
= ATL::_DialogSplitHelper::DlgTemplateItemCount(pDlg
);
4789 // Get first control on the dialog
4790 DLGITEMTEMPLATE
* pItem
= ATL::_DialogSplitHelper::FindFirstDlgItem(pDlg
);
4791 HWND hWndPrev
= GetWindow(GW_CHILD
);
4793 // Create all ActiveX cotnrols in the dialog template and place them in the correct tab order (z-order)
4794 for (WORD nItem
= 0; nItem
< nItems
; nItem
++)
4796 DWORD wID
= bDialogEx
? ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->id
: pItem
->id
;
4797 if (ATL::_DialogSplitHelper::IsActiveXControl(pItem
, bDialogEx
))
4800 DWORD dwLen
= ATL::_DialogSplitHelper::FindCreateData(wID
, pInitData
, &pData
);
4801 ATL::CComPtr
<IStream
> spStream
;
4804 HGLOBAL h
= GlobalAlloc(GHND
, dwLen
);
4807 BYTE
* pBytes
= (BYTE
*) GlobalLock(h
);
4808 BYTE
* pSource
= pData
;
4809 SecureHelper::memcpy_x(pBytes
, dwLen
, pSource
, dwLen
);
4811 CreateStreamOnHGlobal(h
, TRUE
, &spStream
);
4820 ATL::CComBSTR bstrLicKey
;
4821 hr
= ATL::_DialogSplitHelper::ParseInitData(spStream
, &bstrLicKey
.m_str
);
4824 ATL::CAxWindow2 wnd
;
4825 // Get control caption.
4826 LPWSTR pszClassName
=
4828 (LPWSTR
)(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
) + 1) :
4829 (LPWSTR
)(pItem
+ 1);
4830 // Get control rect.
4834 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->x
:
4838 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->y
:
4840 rect
.right
= rect
.left
+
4842 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->cx
:
4844 rect
.bottom
= rect
.top
+
4846 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->cy
:
4849 // Convert from dialog units to screen units
4850 MapDialogRect(&rect
);
4852 // Create AxWindow with a NULL caption.
4857 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->style
:
4858 pItem
->style
) | WS_TABSTOP
,
4860 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->exStyle
:
4863 ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->id
:
4871 if (bDialogEx
&& ((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->helpID
!= 0)
4872 wnd
.SetWindowContextHelpId(((ATL::_DialogSplitHelper::DLGITEMTEMPLATEEX
*)pItem
)->helpID
);
4873 #endif // !_WIN32_WCE
4874 // Try to create the ActiveX control.
4875 hr
= wnd
.CreateControlLic(pszClassName
, spStream
, NULL
, bstrLicKey
);
4878 // Set the correct tab position.
4880 hWndPrev
= HWND_TOP
;
4881 wnd
.SetWindowPos(hWndPrev
, 0,0,0,0,SWP_NOACTIVATE
| SWP_NOMOVE
| SWP_NOSIZE
);
4886 hr
= ATL::AtlHresultFromLastError();
4893 hWndPrev
= ::GetWindow(hWndPrev
, GW_HWNDNEXT
);
4895 pItem
= ATL::_DialogSplitHelper::FindNextDlgItem(pItem
, bDialogEx
);
4899 hr
= ATL::AtlHresultFromLastError();
4902 hr
= ATL::AtlHresultFromLastError();
4907 // Event handling support
4908 HRESULT
AdviseSinkMap(bool bAdvise
)
4910 if(!bAdvise
&& m_hWnd
== NULL
)
4912 // window is gone, controls are already unadvised
4913 ATLTRACE2(atlTraceUI
, 0, _T("CAxPropertyPageImpl::AdviseSinkMap called after the window was destroyed\n"));
4916 HRESULT hRet
= E_NOTIMPL
;
4917 __if_exists(T::_GetSinkMapFinder
)
4919 T
* pT
= static_cast<T
*>(this);
4920 hRet
= AtlAdviseSinkMap(pT
, bAdvise
);
4925 // Message map and handlers
4926 typedef CPropertyPageImpl
< T
, TBase
> _baseClass
;
4927 BEGIN_MSG_MAP(CAxPropertyPageImpl
)
4928 MESSAGE_HANDLER(WM_INITDIALOG
, OnInitDialog
)
4929 MESSAGE_HANDLER(WM_DESTROY
, OnDestroy
)
4930 CHAIN_MSG_MAP(_baseClass
)
4933 LRESULT
OnInitDialog(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
4935 // initialize controls in dialog with DLGINIT resource section
4936 ExecuteDlgInit(static_cast<T
*>(this)->IDD
);
4937 AdviseSinkMap(true);
4942 LRESULT
OnDestroy(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
4944 AdviseSinkMap(false);
4948 #endif // (_ATL_VER >= 0x0700)
4951 // for non-customized pages
4952 template <WORD t_wDlgTemplateID
>
4953 class CAxPropertyPage
: public CAxPropertyPageImpl
<CAxPropertyPage
<t_wDlgTemplateID
> >
4956 enum { IDD
= t_wDlgTemplateID
};
4958 CAxPropertyPage(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CAxPropertyPageImpl
<CAxPropertyPage
>(title
)
4961 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
4962 // not empty so we handle accelerators/create controls
4963 BEGIN_MSG_MAP(CAxPropertyPage
)
4964 CHAIN_MSG_MAP(CAxPropertyPageImpl
<CAxPropertyPage
<t_wDlgTemplateID
> >)
4966 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
4967 DECLARE_EMPTY_MSG_MAP()
4968 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
4971 #endif // _ATL_NO_HOSTING
4974 ///////////////////////////////////////////////////////////////////////////////
4977 #if (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
4979 // Sample wizard dialog resources:
4981 // IDD_WIZ97_INTERIOR_BLANK DIALOG 0, 0, 317, 143
4982 // STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION
4983 // CAPTION "Wizard97 Property Page - Interior"
4984 // FONT 8, "MS Shell Dlg"
4988 // IDD_WIZ97_EXTERIOR_BLANK DIALOGEX 0, 0, 317, 193
4989 // STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_DISABLED | WS_CAPTION
4990 // CAPTION "Wizard97 Property Page - Welcome/Complete"
4991 // FONT 8, "MS Shell Dlg", 0, 0, 0x0
4993 // LTEXT "Welcome to the X Wizard",IDC_WIZ97_EXTERIOR_TITLE,115,8,
4995 // LTEXT "Wizard Explanation\r\n(The height of the static text should be in multiples of 8 dlus)",
4996 // IDC_STATIC,115,40,195,16
4997 // LTEXT "h",IDC_WIZ97_BULLET1,118,64,8,8
4998 // LTEXT "List Item 1 (the h is turned into a bullet)",IDC_STATIC,
5000 // LTEXT "h",IDC_WIZ97_BULLET2,118,79,8,8
5001 // LTEXT "List Item 2. Keep 7 dlus between paragraphs",IDC_STATIC,
5003 // CONTROL "&Do not show this Welcome page again",
5004 // IDC_WIZ97_WELCOME_NOTAGAIN,"Button",BS_AUTOCHECKBOX |
5005 // WS_TABSTOP,115,169,138,10
5008 // GUIDELINES DESIGNINFO
5010 // IDD_WIZ97_INTERIOR_BLANK, DIALOG
5019 // BOTTOMMARGIN, 136
5023 // IDD_WIZ97_EXTERIOR_BLANK, DIALOG
5030 // BOTTOMMARGIN, 186
5038 ///////////////////////////////////////////////////////////////////////////////
5039 // CWizard97SheetWindow - client side for a Wizard 97 style wizard sheet
5041 class CWizard97SheetWindow
: public CPropertySheetWindow
5045 CWizard97SheetWindow(HWND hWnd
= NULL
) : CPropertySheetWindow(hWnd
)
5048 CWizard97SheetWindow
& operator =(HWND hWnd
)
5055 HFONT
GetExteriorPageTitleFont(void)
5057 ATLASSERT(::IsWindow(m_hWnd
));
5058 return (HFONT
)::SendMessage(m_hWnd
, GetMessage_GetExteriorPageTitleFont(), 0, 0L);
5061 HFONT
GetBulletFont(void)
5063 ATLASSERT(::IsWindow(m_hWnd
));
5064 return (HFONT
)::SendMessage(m_hWnd
, GetMessage_GetBulletFont(), 0, 0L);
5068 static UINT
GetMessage_GetExteriorPageTitleFont()
5070 static UINT uGetExteriorPageTitleFont
= 0;
5071 if(uGetExteriorPageTitleFont
== 0)
5073 CStaticDataInitCriticalSectionLock lock
;
5074 if(FAILED(lock
.Lock()))
5076 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont().\n"));
5081 if(uGetExteriorPageTitleFont
== 0)
5082 uGetExteriorPageTitleFont
= ::RegisterWindowMessage(_T("GetExteriorPageTitleFont_531AF056-B8BE-4c4c-B786-AC608DF0DF12"));
5086 ATLASSERT(uGetExteriorPageTitleFont
!= 0);
5087 return uGetExteriorPageTitleFont
;
5090 static UINT
GetMessage_GetBulletFont()
5092 static UINT uGetBulletFont
= 0;
5093 if(uGetBulletFont
== 0)
5095 CStaticDataInitCriticalSectionLock lock
;
5096 if(FAILED(lock
.Lock()))
5098 ATLTRACE2(atlTraceUI
, 0, _T("ERROR : Unable to lock critical section in CWizard97SheetWindow::GetMessage_GetBulletFont().\n"));
5103 if(uGetBulletFont
== 0)
5104 uGetBulletFont
= ::RegisterWindowMessage(_T("GetBulletFont_AD347D08-8F65-45ef-982E-6352E8218AD5"));
5108 ATLASSERT(uGetBulletFont
!= 0);
5109 return uGetBulletFont
;
5112 // Implementation - override to prevent usage
5113 HWND
Create(LPCTSTR
, HWND
, ATL::_U_RECT
= NULL
, LPCTSTR
= NULL
, DWORD
= 0, DWORD
= 0, ATL::_U_MENUorID
= 0U, LPVOID
= NULL
)
5121 ///////////////////////////////////////////////////////////////////////////////
5122 // CWizard97SheetImpl - implements a Wizard 97 style wizard sheet
5124 template <class T
, class TBase
= CWizard97SheetWindow
>
5125 class ATL_NO_VTABLE CWizard97SheetImpl
: public CPropertySheetImpl
< T
, TBase
>
5129 typedef CWizard97SheetImpl
< T
, TBase
> thisClass
;
5130 typedef CPropertySheetImpl
< T
, TBase
> baseClass
;
5133 CFont m_fontExteriorPageTitle
; // Welcome and Completion page title font
5134 CFont m_fontBullet
; // Bullet font (used on static text 'h' to produce a small bullet)
5135 bool m_bReceivedFirstSizeMessage
;
5138 CWizard97SheetImpl(ATL::_U_STRINGorID title
, ATL::_U_STRINGorID headerBitmap
, ATL::_U_STRINGorID watermarkBitmap
, UINT uStartPage
= 0, HWND hWndParent
= NULL
) :
5139 baseClass(title
, uStartPage
, hWndParent
),
5140 m_bReceivedFirstSizeMessage(false)
5142 m_psh
.dwFlags
&= ~(PSH_NOCONTEXTHELP
);
5143 m_psh
.dwFlags
&= ~(PSH_WIZARD
| PSH_WIZARD_LITE
);
5145 m_psh
.dwFlags
|= (PSH_HASHELP
| PSH_WIZARDCONTEXTHELP
);
5146 m_psh
.dwFlags
|= PSH_WIZARD97
;
5148 baseClass::SetHeader(headerBitmap
.m_lpstr
);
5149 baseClass::SetWatermark(watermarkBitmap
.m_lpstr
);
5152 // Overrides from base class
5153 void OnSheetInitialized()
5155 T
* pT
= static_cast<T
*>(this);
5156 pT
->_InitializeFonts();
5158 // We'd like to center the wizard here, but its too early.
5159 // Instead, we'll do CenterWindow upon our first WM_SIZE message
5163 void _InitializeFonts()
5165 // Setup the Title and Bullet Font
5166 // (Property pages can send the "get external page title font" and "get bullet font" messages)
5167 // The derived class needs to do the actual SetFont for the dialog items)
5169 CFontHandle fontThisDialog
= this->GetFont();
5170 CClientDC
dcScreen(NULL
);
5172 LOGFONT titleLogFont
= {0};
5173 LOGFONT bulletLogFont
= {0};
5174 fontThisDialog
.GetLogFont(&titleLogFont
);
5175 fontThisDialog
.GetLogFont(&bulletLogFont
);
5177 // The Wizard 97 Spec recommends to do the Title Font
5178 // as Verdana Bold, 12pt.
5179 titleLogFont
.lfCharSet
= DEFAULT_CHARSET
;
5180 titleLogFont
.lfWeight
= FW_BOLD
;
5181 SecureHelper::strcpy_x(titleLogFont
.lfFaceName
, _countof(titleLogFont
.lfFaceName
), _T("Verdana Bold"));
5182 INT titleFontPointSize
= 12;
5183 titleLogFont
.lfHeight
= -::MulDiv(titleFontPointSize
, dcScreen
.GetDeviceCaps(LOGPIXELSY
), 72);
5184 m_fontExteriorPageTitle
.CreateFontIndirect(&titleLogFont
);
5186 // The Wizard 97 Spec recommends to do Bullets by having
5187 // static text of "h" in the Marlett font.
5188 bulletLogFont
.lfCharSet
= DEFAULT_CHARSET
;
5189 bulletLogFont
.lfWeight
= FW_NORMAL
;
5190 SecureHelper::strcpy_x(bulletLogFont
.lfFaceName
, _countof(bulletLogFont
.lfFaceName
), _T("Marlett"));
5191 INT bulletFontSize
= 8;
5192 bulletLogFont
.lfHeight
= -::MulDiv(bulletFontSize
, dcScreen
.GetDeviceCaps(LOGPIXELSY
), 72);
5193 m_fontBullet
.CreateFontIndirect(&bulletLogFont
);
5197 BEGIN_MSG_MAP(thisClass
)
5198 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetExteriorPageTitleFont(), OnGetExteriorPageTitleFont
)
5199 MESSAGE_HANDLER(CWizard97SheetWindow::GetMessage_GetBulletFont(), OnGetBulletFont
)
5200 MESSAGE_HANDLER(WM_SIZE
, OnSize
)
5201 CHAIN_MSG_MAP(baseClass
)
5204 LRESULT
OnGetExteriorPageTitleFont(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
5206 return (LRESULT
)(HFONT
)m_fontExteriorPageTitle
;
5209 LRESULT
OnGetBulletFont(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& /*bHandled*/)
5211 return (LRESULT
)(HFONT
)m_fontBullet
;
5214 LRESULT
OnSize(UINT
/*uMsg*/, WPARAM
/*wParam*/, LPARAM
/*lParam*/, BOOL
& bHandled
)
5216 if(!m_bReceivedFirstSizeMessage
)
5218 m_bReceivedFirstSizeMessage
= true;
5219 this->CenterWindow();
5227 // for non-customized sheets
5228 class CWizard97Sheet
: public CWizard97SheetImpl
<CWizard97Sheet
>
5232 typedef CWizard97Sheet thisClass
;
5233 typedef CWizard97SheetImpl
<CWizard97Sheet
> baseClass
;
5236 CWizard97Sheet(ATL::_U_STRINGorID title
, ATL::_U_STRINGorID headerBitmap
, ATL::_U_STRINGorID watermarkBitmap
, UINT uStartPage
= 0, HWND hWndParent
= NULL
) :
5237 baseClass(title
, headerBitmap
, watermarkBitmap
, uStartPage
, hWndParent
)
5240 BEGIN_MSG_MAP(thisClass
)
5241 CHAIN_MSG_MAP(baseClass
)
5246 ///////////////////////////////////////////////////////////////////////////////
5247 // CWizard97PageWindow - client side for a Wizard 97 style wizard page
5249 #define WIZARD97_EXTERIOR_CXDLG 317
5250 #define WIZARD97_EXTERIOR_CYDLG 193
5252 #define WIZARD97_INTERIOR_CXDLG 317
5253 #define WIZARD97_INTERIOR_CYDLG 143
5255 class CWizard97PageWindow
: public CPropertyPageWindow
5259 CWizard97PageWindow(HWND hWnd
= NULL
) : CPropertyPageWindow(hWnd
)
5262 CWizard97PageWindow
& operator =(HWND hWnd
)
5269 CWizard97SheetWindow
GetPropertySheet() const
5271 ATLASSERT(::IsWindow(m_hWnd
));
5272 return CWizard97SheetWindow(GetParent());
5276 HFONT
GetExteriorPageTitleFont(void)
5278 ATLASSERT(::IsWindow(m_hWnd
));
5279 return GetPropertySheet().GetExteriorPageTitleFont();
5282 HFONT
GetBulletFont(void)
5284 ATLASSERT(::IsWindow(m_hWnd
));
5285 return GetPropertySheet().GetBulletFont();
5288 // Implementation - overrides to prevent usage
5289 HWND
Create(LPCTSTR
, HWND
, ATL::_U_RECT
= NULL
, LPCTSTR
= NULL
, DWORD
= 0, DWORD
= 0, ATL::_U_MENUorID
= 0U, LPVOID
= NULL
)
5298 ///////////////////////////////////////////////////////////////////////////////
5299 // CWizard97PageImpl - implements a Wizard 97 style wizard page
5301 template <class T
, class TBase
= CWizard97PageWindow
>
5302 class ATL_NO_VTABLE CWizard97PageImpl
: public CPropertyPageImpl
< T
, TBase
>
5306 typedef CWizard97PageImpl
< T
, TBase
> thisClass
;
5307 typedef CPropertyPageImpl
< T
, TBase
> baseClass
;
5310 CWizard97PageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : baseClass(title
)
5314 BEGIN_MSG_MAP(thisClass
)
5315 CHAIN_MSG_MAP(baseClass
)
5320 ///////////////////////////////////////////////////////////////////////////////
5321 // CWizard97ExteriorPageImpl - implements a Wizard 97 style exterior wizard page
5323 template <class T
, class TBase
= CWizard97PageWindow
>
5324 class ATL_NO_VTABLE CWizard97ExteriorPageImpl
: public CPropertyPageImpl
< T
, TBase
>
5328 typedef CWizard97ExteriorPageImpl
< T
, TBase
> thisClass
;
5329 typedef CPropertyPageImpl
< T
, TBase
> baseClass
;
5333 CWizard97ExteriorPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : baseClass(title
)
5335 m_psp
.dwFlags
|= PSP_HASHELP
;
5336 m_psp
.dwFlags
|= PSP_HIDEHEADER
;
5340 BEGIN_MSG_MAP(thisClass
)
5341 CHAIN_MSG_MAP(baseClass
)
5346 ///////////////////////////////////////////////////////////////////////////////
5347 // CWizard97InteriorPageImpl - implements a Wizard 97 style interior wizard page
5349 template <class T
, class TBase
= CWizard97PageWindow
>
5350 class ATL_NO_VTABLE CWizard97InteriorPageImpl
: public CPropertyPageImpl
< T
, TBase
>
5354 typedef CWizard97InteriorPageImpl
< T
, TBase
> thisClass
;
5355 typedef CPropertyPageImpl
< T
, TBase
> baseClass
;
5359 CWizard97InteriorPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : baseClass(title
)
5361 m_psp
.dwFlags
|= PSP_HASHELP
;
5362 m_psp
.dwFlags
&= ~PSP_HIDEHEADER
;
5363 m_psp
.dwFlags
|= PSP_USEHEADERTITLE
| PSP_USEHEADERSUBTITLE
;
5365 // Be sure to have the derived class define this in the constructor.
5366 // We'll default it to something obvious in case its forgotten.
5367 baseClass::SetHeaderTitle(_T("Call SetHeaderTitle in Derived Class"));
5368 baseClass::SetHeaderSubTitle(_T("Call SetHeaderSubTitle in the constructor of the Derived Class."));
5372 BEGIN_MSG_MAP(thisClass
)
5373 CHAIN_MSG_MAP(baseClass
)
5377 #endif // (_WIN32_IE >= 0x0500) && !defined(_WIN32_WCE)
5380 ///////////////////////////////////////////////////////////////////////////////
5381 // Aero Wizard support
5383 #if (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
5385 ///////////////////////////////////////////////////////////////////////////////
5386 // CAeroWizardFrameWindow - client side for an Aero Wizard frame window
5388 class CAeroWizardFrameWindow
: public CPropertySheetWindow
5392 CAeroWizardFrameWindow(HWND hWnd
= NULL
) : CPropertySheetWindow(hWnd
)
5395 CAeroWizardFrameWindow
& operator =(HWND hWnd
)
5401 // Operations - new, Aero Wizard only
5402 void SetNextText(LPCWSTR lpszText
)
5404 ATLASSERT(::IsWindow(m_hWnd
));
5405 ::SendMessage(m_hWnd
, PSM_SETNEXTTEXT
, 0, (LPARAM
)lpszText
);
5408 void ShowWizardButtons(DWORD dwButtons
, DWORD dwStates
)
5410 ATLASSERT(::IsWindow(m_hWnd
));
5411 ::PostMessage(m_hWnd
, PSM_SHOWWIZBUTTONS
, (WPARAM
)dwStates
, (LPARAM
)dwButtons
);
5414 void EnableWizardButtons(DWORD dwButtons
, DWORD dwStates
)
5416 ATLASSERT(::IsWindow(m_hWnd
));
5417 ::PostMessage(m_hWnd
, PSM_ENABLEWIZBUTTONS
, (WPARAM
)dwStates
, (LPARAM
)dwButtons
);
5420 void SetButtonText(DWORD dwButton
, LPCWSTR lpszText
)
5422 ATLASSERT(::IsWindow(m_hWnd
));
5423 ::SendMessage(m_hWnd
, PSM_SETBUTTONTEXT
, (WPARAM
)dwButton
, (LPARAM
)lpszText
);
5428 ///////////////////////////////////////////////////////////////////////////////
5429 // CAeroWizardFrameImpl - implements an Aero Wizard frame
5431 template <class T
, class TBase
= CAeroWizardFrameWindow
>
5432 class ATL_NO_VTABLE CAeroWizardFrameImpl
: public CPropertySheetImpl
<T
, TBase
>
5436 CAeroWizardFrameImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
, UINT uStartPage
= 0, HWND hWndParent
= NULL
) :
5437 CPropertySheetImpl
<T
, TBase
>(title
, uStartPage
, hWndParent
)
5439 m_psh
.dwFlags
|= PSH_WIZARD
| PSH_AEROWIZARD
;
5443 void EnableResizing()
5445 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
5446 m_psh
.dwFlags
|= PSH_RESIZABLE
;
5449 void UseHeaderBitmap()
5451 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
5452 m_psh
.dwFlags
|= PSH_HEADERBITMAP
;
5457 ATLASSERT(m_hWnd
== NULL
); // can't do this after it's created
5458 m_psh
.dwFlags
|= PSH_NOMARGIN
;
5461 // Override to prevent use
5462 HWND
Create(HWND
/*hWndParent*/ = NULL
)
5464 ATLASSERT(FALSE
); // not supported for Aero Wizard
5470 ///////////////////////////////////////////////////////////////////////////////
5471 // CAeroWizardFrame - for non-customized frames
5473 class CAeroWizardFrame
: public CAeroWizardFrameImpl
<CAeroWizardFrame
>
5476 CAeroWizardFrame(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
, UINT uStartPage
= 0, HWND hWndParent
= NULL
)
5477 : CAeroWizardFrameImpl
<CAeroWizardFrame
>(title
, uStartPage
, hWndParent
)
5480 BEGIN_MSG_MAP(CAeroWizardFrame
)
5481 MESSAGE_HANDLER(WM_COMMAND
, CAeroWizardFrameImpl
<CAeroWizardFrame
>::OnCommand
)
5486 ///////////////////////////////////////////////////////////////////////////////
5487 // CAeroWizardPageWindow - client side for an Aero Wizard page
5489 class CAeroWizardPageWindow
: public CPropertyPageWindow
5493 CAeroWizardPageWindow(HWND hWnd
= NULL
) : CPropertyPageWindow(hWnd
)
5496 CAeroWizardPageWindow
& operator =(HWND hWnd
)
5503 CAeroWizardFrameWindow
GetAeroWizardFrame() const
5505 ATLASSERT(::IsWindow(m_hWnd
));
5506 // This is not really top-level frame window, but it processes all frame messages
5507 return CAeroWizardFrameWindow(GetParent());
5510 // Operations - new, Aero Wizard only
5511 void SetNextText(LPCWSTR lpszText
)
5513 ATLASSERT(::IsWindow(m_hWnd
));
5514 ATLASSERT(GetParent() != NULL
);
5515 GetAeroWizardFrame().SetNextText(lpszText
);
5518 void ShowWizardButtons(DWORD dwButtons
, DWORD dwStates
)
5520 ATLASSERT(::IsWindow(m_hWnd
));
5521 ATLASSERT(GetParent() != NULL
);
5522 GetAeroWizardFrame().ShowWizardButtons(dwButtons
, dwStates
);
5525 void EnableWizardButtons(DWORD dwButtons
, DWORD dwStates
)
5527 ATLASSERT(::IsWindow(m_hWnd
));
5528 ATLASSERT(GetParent() != NULL
);
5529 GetAeroWizardFrame().EnableWizardButtons(dwButtons
, dwStates
);
5532 void SetButtonText(DWORD dwButton
, LPCWSTR lpszText
)
5534 ATLASSERT(::IsWindow(m_hWnd
));
5535 ATLASSERT(GetParent() != NULL
);
5536 GetAeroWizardFrame().SetButtonText(dwButton
, lpszText
);
5541 ///////////////////////////////////////////////////////////////////////////////
5542 // CAeroWizardPageImpl - implements an Aero Wizard page
5544 template <class T
, class TBase
= CAeroWizardPageWindow
>
5545 class ATL_NO_VTABLE CAeroWizardPageImpl
: public CPropertyPageImpl
<T
, TBase
>
5548 CAeroWizardPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CPropertyPageImpl
<T
, TBase
>(title
)
5553 ///////////////////////////////////////////////////////////////////////////////
5554 // CAeroWizardPage - for non-customized pages
5556 template <WORD t_wDlgTemplateID
>
5557 class CAeroWizardPage
: public CAeroWizardPageImpl
<CAeroWizardPage
<t_wDlgTemplateID
> >
5560 enum { IDD
= t_wDlgTemplateID
};
5562 CAeroWizardPage(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CAeroWizardPageImpl
<CAeroWizardPage
>(title
)
5565 DECLARE_EMPTY_MSG_MAP()
5569 #ifndef _ATL_NO_HOSTING
5571 // Note: You must #include <atlhost.h> to use these classes
5573 ///////////////////////////////////////////////////////////////////////////////
5574 // CAeroWizardAxPageImpl - Aero Wizard page that hosts ActiveX controls
5576 template <class T
, class TBase
= CAeroWizardPageWindow
>
5577 class ATL_NO_VTABLE CAeroWizardAxPageImpl
: public CAxPropertyPageImpl
< T
, TBase
>
5580 CAeroWizardAxPageImpl(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CAxPropertyPageImpl
< T
, TBase
>(title
)
5585 ///////////////////////////////////////////////////////////////////////////////
5586 // CAeroWizardAxPage - for non-customized pages
5588 template <WORD t_wDlgTemplateID
>
5589 class CAeroWizardAxPage
: public CAeroWizardAxPageImpl
<CAeroWizardAxPage
<t_wDlgTemplateID
> >
5592 enum { IDD
= t_wDlgTemplateID
};
5594 CAeroWizardAxPage(ATL::_U_STRINGorID title
= (LPCTSTR
)NULL
) : CAeroWizardAxPageImpl
<CAeroWizardAxPage
>(title
)
5597 #if (_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700)
5598 // not empty so we handle accelerators/create controls
5599 BEGIN_MSG_MAP(CAeroWizardAxPage
)
5600 CHAIN_MSG_MAP(CAeroWizardAxPageImpl
<CAeroWizardAxPage
<t_wDlgTemplateID
> >)
5602 #else // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5603 DECLARE_EMPTY_MSG_MAP()
5604 #endif // !((_WIN32_IE >= 0x0500) || (_ATL_VER >= 0x0700))
5607 #endif // _ATL_NO_HOSTING
5609 #endif // (_WIN32_WINNT >= 0x0600) && !defined(_WIN32_WCE)
5612 ///////////////////////////////////////////////////////////////////////////////
5613 // TaskDialog support
5615 #if ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
5617 ///////////////////////////////////////////////////////////////////////////////
5618 // AtlTaskDialog - support for TaskDialog() function
5620 inline int AtlTaskDialog(HWND hWndParent
,
5621 ATL::_U_STRINGorID WindowTitle
, ATL::_U_STRINGorID MainInstructionText
, ATL::_U_STRINGorID ContentText
,
5622 TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons
= 0U, ATL::_U_STRINGorID Icon
= (LPCTSTR
)NULL
)
5626 #ifdef _WTL_TASKDIALOG_DIRECT
5628 HRESULT hRet
= ::TaskDialog(hWndParent
, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle
.m_lpstr
), T2CW(MainInstructionText
.m_lpstr
), T2CW(ContentText
.m_lpstr
), dwCommonButtons
, T2CW(Icon
.m_lpstr
), &nRet
);
5629 ATLVERIFY(SUCCEEDED(hRet
));
5631 // This allows apps to run on older versions of Windows
5632 typedef HRESULT (STDAPICALLTYPE
*PFN_TaskDialog
)(HWND hwndParent
, HINSTANCE hInstance
, PCWSTR pszWindowTitle
, PCWSTR pszMainInstruction
, PCWSTR pszContent
, TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons
, PCWSTR pszIcon
, int* pnButton
);
5634 HMODULE m_hCommCtrlDLL
= ::LoadLibrary(_T("comctl32.dll"));
5635 if(m_hCommCtrlDLL
!= NULL
)
5637 PFN_TaskDialog pfnTaskDialog
= (PFN_TaskDialog
)::GetProcAddress(m_hCommCtrlDLL
, "TaskDialog");
5638 if(pfnTaskDialog
!= NULL
)
5641 HRESULT hRet
= pfnTaskDialog(hWndParent
, ModuleHelper::GetResourceInstance(), T2CW(WindowTitle
.m_lpstr
), T2CW(MainInstructionText
.m_lpstr
), T2CW(ContentText
.m_lpstr
), dwCommonButtons
, T2CW(Icon
.m_lpstr
), &nRet
);
5642 ATLVERIFY(SUCCEEDED(hRet
));
5645 ::FreeLibrary(m_hCommCtrlDLL
);
5653 ///////////////////////////////////////////////////////////////////////////////
5654 // CTaskDialogConfig - TASKDIALOGCONFIG wrapper
5656 class CTaskDialogConfig
: public TASKDIALOGCONFIG
5667 memset(this, 0, sizeof(TASKDIALOGCONFIG
)); // initialize structure to 0/NULL
5668 this->cbSize
= sizeof(TASKDIALOGCONFIG
);
5669 this->hInstance
= ModuleHelper::GetResourceInstance();
5672 // Operations - setting values
5674 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons
)
5676 this->dwCommonButtons
= dwCommonButtons
;
5679 // window title text
5680 void SetWindowTitle(UINT nID
)
5682 this->pszWindowTitle
= MAKEINTRESOURCEW(nID
);
5685 void SetWindowTitle(LPCWSTR lpstrWindowTitle
)
5687 this->pszWindowTitle
= lpstrWindowTitle
;
5691 void SetMainIcon(HICON hIcon
)
5693 this->dwFlags
|= TDF_USE_HICON_MAIN
;
5694 this->hMainIcon
= hIcon
;
5697 void SetMainIcon(UINT nID
)
5699 this->dwFlags
&= ~TDF_USE_HICON_MAIN
;
5700 this->pszMainIcon
= MAKEINTRESOURCEW(nID
);
5703 void SetMainIcon(LPCWSTR lpstrMainIcon
)
5705 this->dwFlags
&= ~TDF_USE_HICON_MAIN
;
5706 this->pszMainIcon
= lpstrMainIcon
;
5709 // main instruction text
5710 void SetMainInstructionText(UINT nID
)
5712 this->pszMainInstruction
= MAKEINTRESOURCEW(nID
);
5715 void SetMainInstructionText(LPCWSTR lpstrMainInstruction
)
5717 this->pszMainInstruction
= lpstrMainInstruction
;
5721 void SetContentText(UINT nID
)
5723 this->pszContent
= MAKEINTRESOURCEW(nID
);
5726 void SetContentText(LPCWSTR lpstrContent
)
5728 this->pszContent
= lpstrContent
;
5732 void SetButtons(const TASKDIALOG_BUTTON
* pButtons
, UINT cButtons
, int nDefaultButton
= 0)
5734 this->pButtons
= pButtons
;
5735 this->cButtons
= cButtons
;
5736 if(nDefaultButton
!= 0)
5737 this->nDefaultButton
= nDefaultButton
;
5740 void SetDefaultButton(int nDefaultButton
)
5742 this->nDefaultButton
= nDefaultButton
;
5746 void SetRadioButtons(const TASKDIALOG_BUTTON
* pRadioButtons
, UINT cRadioButtons
, int nDefaultRadioButton
= 0)
5748 this->pRadioButtons
= pRadioButtons
;
5749 this->cRadioButtons
= cRadioButtons
;
5750 if(nDefaultRadioButton
!= 0)
5751 this->nDefaultRadioButton
= nDefaultRadioButton
;
5754 void SetDefaultRadioButton(int nDefaultRadioButton
)
5756 this->nDefaultRadioButton
= nDefaultRadioButton
;
5759 // verification text
5760 void SetVerificationText(UINT nID
)
5762 this->pszVerificationText
= MAKEINTRESOURCEW(nID
);
5765 void SetVerificationText(LPCWSTR lpstrVerificationText
)
5767 this->pszVerificationText
= lpstrVerificationText
;
5770 // expanded information text
5771 void SetExpandedInformationText(UINT nID
)
5773 this->pszExpandedInformation
= MAKEINTRESOURCEW(nID
);
5776 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation
)
5778 this->pszExpandedInformation
= lpstrExpandedInformation
;
5781 // expanded control text
5782 void SetExpandedControlText(UINT nID
)
5784 this->pszExpandedControlText
= MAKEINTRESOURCEW(nID
);
5787 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText
)
5789 this->pszExpandedControlText
= lpstrExpandedControlText
;
5792 // collapsed control text
5793 void SetCollapsedControlText(UINT nID
)
5795 this->pszCollapsedControlText
= MAKEINTRESOURCEW(nID
);
5798 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText
)
5800 this->pszCollapsedControlText
= lpstrCollapsedControlText
;
5804 void SetFooterIcon(HICON hIcon
)
5806 this->dwFlags
|= TDF_USE_HICON_FOOTER
;
5807 this->hFooterIcon
= hIcon
;
5810 void SetFooterIcon(UINT nID
)
5812 this->dwFlags
&= ~TDF_USE_HICON_FOOTER
;
5813 this->pszFooterIcon
= MAKEINTRESOURCEW(nID
);
5816 void SetFooterIcon(LPCWSTR lpstrFooterIcon
)
5818 this->dwFlags
&= ~TDF_USE_HICON_FOOTER
;
5819 this->pszFooterIcon
= lpstrFooterIcon
;
5823 void SetFooterText(UINT nID
)
5825 this->pszFooter
= MAKEINTRESOURCEW(nID
);
5828 void SetFooterText(LPCWSTR lpstrFooterText
)
5830 this->pszFooter
= lpstrFooterText
;
5834 void SetWidth(UINT cxWidth
)
5836 this->cxWidth
= cxWidth
;
5840 void ModifyFlags(DWORD dwRemove
, DWORD dwAdd
)
5842 this->dwFlags
= (this->dwFlags
& ~dwRemove
) | dwAdd
;
5847 ///////////////////////////////////////////////////////////////////////////////
5848 // CTaskDialogImpl - implements a Task Dialog
5851 class ATL_NO_VTABLE CTaskDialogImpl
5854 CTaskDialogConfig m_tdc
;
5855 HWND m_hWnd
; // used only in callback functions
5858 CTaskDialogImpl(HWND hWndParent
= NULL
) : m_hWnd(NULL
)
5860 m_tdc
.hwndParent
= hWndParent
;
5861 m_tdc
.pfCallback
= T::TaskDialogCallback
;
5862 m_tdc
.lpCallbackData
= (LONG_PTR
)static_cast<T
*>(this);
5866 HRESULT
DoModal(HWND hWndParent
= ::GetActiveWindow(), int* pnButton
= NULL
, int* pnRadioButton
= NULL
, BOOL
* pfVerificationFlagChecked
= NULL
)
5868 if(m_tdc
.hwndParent
== NULL
)
5869 m_tdc
.hwndParent
= hWndParent
;
5871 #ifdef _WTL_TASKDIALOG_DIRECT
5872 return ::TaskDialogIndirect(&m_tdc
, pnButton
, pnRadioButton
, pfVerificationFlagChecked
);
5875 // This allows apps to run on older versions of Windows
5876 typedef HRESULT (STDAPICALLTYPE
*PFN_TaskDialogIndirect
)(const TASKDIALOGCONFIG
* pTaskConfig
, int* pnButton
, int* pnRadioButton
, BOOL
* pfVerificationFlagChecked
);
5878 HRESULT hRet
= E_UNEXPECTED
;
5879 HMODULE m_hCommCtrlDLL
= ::LoadLibrary(_T("comctl32.dll"));
5880 if(m_hCommCtrlDLL
!= NULL
)
5882 PFN_TaskDialogIndirect pfnTaskDialogIndirect
= (PFN_TaskDialogIndirect
)::GetProcAddress(m_hCommCtrlDLL
, "TaskDialogIndirect");
5883 if(pfnTaskDialogIndirect
!= NULL
)
5884 hRet
= pfnTaskDialogIndirect(&m_tdc
, pnButton
, pnRadioButton
, pfVerificationFlagChecked
);
5886 ::FreeLibrary(m_hCommCtrlDLL
);
5893 // Operations - setting values of TASKDIALOGCONFIG
5895 void SetCommonButtons(TASKDIALOG_COMMON_BUTTON_FLAGS dwCommonButtons
)
5896 { m_tdc
.SetCommonButtons(dwCommonButtons
); }
5897 // window title text
5898 void SetWindowTitle(UINT nID
)
5899 { m_tdc
.SetWindowTitle(nID
); }
5900 void SetWindowTitle(LPCWSTR lpstrWindowTitle
)
5901 { m_tdc
.SetWindowTitle(lpstrWindowTitle
); }
5903 void SetMainIcon(HICON hIcon
)
5904 { m_tdc
.SetMainIcon(hIcon
); }
5905 void SetMainIcon(UINT nID
)
5906 { m_tdc
.SetMainIcon(nID
); }
5907 void SetMainIcon(LPCWSTR lpstrMainIcon
)
5908 { m_tdc
.SetMainIcon(lpstrMainIcon
); }
5909 // main instruction text
5910 void SetMainInstructionText(UINT nID
)
5911 { m_tdc
.SetMainInstructionText(nID
); }
5912 void SetMainInstructionText(LPCWSTR lpstrMainInstruction
)
5913 { m_tdc
.SetMainInstructionText(lpstrMainInstruction
); }
5915 void SetContentText(UINT nID
)
5916 { m_tdc
.SetContentText(nID
); }
5917 void SetContentText(LPCWSTR lpstrContent
)
5918 { m_tdc
.SetContentText(lpstrContent
); }
5920 void SetButtons(const TASKDIALOG_BUTTON
* pButtons
, UINT cButtons
, int nDefaultButton
= 0)
5921 { m_tdc
.SetButtons(pButtons
, cButtons
, nDefaultButton
); }
5922 void SetDefaultButton(int nDefaultButton
)
5923 { m_tdc
.SetDefaultButton(nDefaultButton
); }
5925 void SetRadioButtons(const TASKDIALOG_BUTTON
* pRadioButtons
, UINT cRadioButtons
, int nDefaultRadioButton
= 0)
5926 { m_tdc
.SetRadioButtons(pRadioButtons
, cRadioButtons
, nDefaultRadioButton
); }
5927 void SetDefaultRadioButton(int nDefaultRadioButton
)
5928 { m_tdc
.SetDefaultRadioButton(nDefaultRadioButton
); }
5929 // verification text
5930 void SetVerificationText(UINT nID
)
5931 { m_tdc
.SetVerificationText(nID
); }
5932 void SetVerificationText(LPCWSTR lpstrVerificationText
)
5933 { m_tdc
.SetVerificationText(lpstrVerificationText
); }
5934 // expanded information text
5935 void SetExpandedInformationText(UINT nID
)
5936 { m_tdc
.SetExpandedInformationText(nID
); }
5937 void SetExpandedInformationText(LPCWSTR lpstrExpandedInformation
)
5938 { m_tdc
.SetExpandedInformationText(lpstrExpandedInformation
); }
5939 // expanded control text
5940 void SetExpandedControlText(UINT nID
)
5941 { m_tdc
.SetExpandedControlText(nID
); }
5942 void SetExpandedControlText(LPCWSTR lpstrExpandedControlText
)
5943 { m_tdc
.SetExpandedControlText(lpstrExpandedControlText
); }
5944 // collapsed control text
5945 void SetCollapsedControlText(UINT nID
)
5946 { m_tdc
.SetCollapsedControlText(nID
); }
5947 void SetCollapsedControlText(LPCWSTR lpstrCollapsedControlText
)
5948 { m_tdc
.SetCollapsedControlText(lpstrCollapsedControlText
); }
5950 void SetFooterIcon(HICON hIcon
)
5951 { m_tdc
.SetFooterIcon(hIcon
); }
5952 void SetFooterIcon(UINT nID
)
5953 { m_tdc
.SetFooterIcon(nID
); }
5954 void SetFooterIcon(LPCWSTR lpstrFooterIcon
)
5955 { m_tdc
.SetFooterIcon(lpstrFooterIcon
); }
5957 void SetFooterText(UINT nID
)
5958 { m_tdc
.SetFooterText(nID
); }
5959 void SetFooterText(LPCWSTR lpstrFooterText
)
5960 { m_tdc
.SetFooterText(lpstrFooterText
); }
5962 void SetWidth(UINT cxWidth
)
5963 { m_tdc
.SetWidth(cxWidth
); }
5965 void ModifyFlags(DWORD dwRemove
, DWORD dwAdd
)
5966 { m_tdc
.ModifyFlags(dwRemove
, dwAdd
); }
5969 static HRESULT CALLBACK
TaskDialogCallback(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LONG_PTR lpRefData
)
5971 T
* pT
= (T
*)lpRefData
;
5972 ATLASSERT(pT
->m_hWnd
== NULL
|| pT
->m_hWnd
== hWnd
);
5977 case TDN_DIALOG_CONSTRUCTED
:
5979 pT
->OnDialogConstructed();
5984 case TDN_BUTTON_CLICKED
:
5985 bRet
= pT
->OnButtonClicked((int)wParam
);
5987 case TDN_RADIO_BUTTON_CLICKED
:
5988 pT
->OnRadioButtonClicked((int)wParam
);
5990 case TDN_HYPERLINK_CLICKED
:
5991 pT
->OnHyperlinkClicked((LPCWSTR
)lParam
);
5993 case TDN_EXPANDO_BUTTON_CLICKED
:
5994 pT
->OnExpandoButtonClicked((wParam
!= 0));
5996 case TDN_VERIFICATION_CLICKED
:
5997 pT
->OnVerificationClicked((wParam
!= 0));
6003 bRet
= pT
->OnTimer((DWORD
)wParam
);
6013 ATLTRACE2(atlTraceUI
, 0, _T("Unknown notification received in CTaskDialogImpl::TaskDialogCallback\n"));
6017 return (HRESULT
)bRet
;
6020 // Overrideables - notification handlers
6021 void OnDialogConstructed()
6029 BOOL
OnButtonClicked(int /*nButton*/)
6031 return FALSE
; // don't prevent dialog to close
6034 void OnRadioButtonClicked(int /*nRadioButton*/)
6038 void OnHyperlinkClicked(LPCWSTR
/*pszHREF*/)
6042 void OnExpandoButtonClicked(bool /*bExpanded*/)
6046 void OnVerificationClicked(bool /*bChecked*/)
6054 BOOL
OnTimer(DWORD
/*dwTickCount*/)
6056 return FALSE
; // don't reset counter
6067 // Commands - valid to call only from handlers
6068 void NavigatePage(TASKDIALOGCONFIG
& tdc
)
6070 ATLASSERT(m_hWnd
!= NULL
);
6072 tdc
.cbSize
= sizeof(TASKDIALOGCONFIG
);
6073 if(tdc
.hwndParent
== NULL
)
6074 tdc
.hwndParent
= m_tdc
.hwndParent
;
6075 tdc
.pfCallback
= m_tdc
.pfCallback
;
6076 tdc
.lpCallbackData
= m_tdc
.lpCallbackData
;
6077 (TASKDIALOGCONFIG
)m_tdc
= tdc
;
6079 ::SendMessage(m_hWnd
, TDM_NAVIGATE_PAGE
, 0, (LPARAM
)&tdc
);
6082 // modify TASKDIALOGCONFIG values, then call this to update task dialog
6085 ATLASSERT(m_hWnd
!= NULL
);
6086 ::SendMessage(m_hWnd
, TDM_NAVIGATE_PAGE
, 0, (LPARAM
)&m_tdc
);
6089 void ClickButton(int nButton
)
6091 ATLASSERT(m_hWnd
!= NULL
);
6092 ::SendMessage(m_hWnd
, TDM_CLICK_BUTTON
, nButton
, 0L);
6095 void SetMarqueeProgressBar(BOOL bMarquee
)
6097 ATLASSERT(m_hWnd
!= NULL
);
6098 ::SendMessage(m_hWnd
, TDM_SET_MARQUEE_PROGRESS_BAR
, bMarquee
, 0L);
6101 BOOL
SetProgressBarState(int nNewState
)
6103 ATLASSERT(m_hWnd
!= NULL
);
6104 return (BOOL
)::SendMessage(m_hWnd
, TDM_SET_PROGRESS_BAR_STATE
, nNewState
, 0L);
6107 DWORD
SetProgressBarRange(int nMinRange
, int nMaxRange
)
6109 ATLASSERT(m_hWnd
!= NULL
);
6110 return (DWORD
)::SendMessage(m_hWnd
, TDM_SET_PROGRESS_BAR_RANGE
, 0, MAKELPARAM(nMinRange
, nMaxRange
));
6113 int SetProgressBarPos(int nNewPos
)
6115 ATLASSERT(m_hWnd
!= NULL
);
6116 return (int)::SendMessage(m_hWnd
, TDM_SET_PROGRESS_BAR_POS
, nNewPos
, 0L);
6119 BOOL
SetProgressBarMarquee(BOOL bMarquee
, UINT uSpeed
)
6121 ATLASSERT(m_hWnd
!= NULL
);
6122 return (BOOL
)::SendMessage(m_hWnd
, TDM_SET_PROGRESS_BAR_MARQUEE
, bMarquee
, uSpeed
);
6125 void SetElementText(TASKDIALOG_ELEMENTS element
, LPCWSTR lpstrText
)
6127 ATLASSERT(m_hWnd
!= NULL
);
6128 ::SendMessage(m_hWnd
, TDM_SET_ELEMENT_TEXT
, element
, (LPARAM
)lpstrText
);
6131 void ClickRadioButton(int nRadioButton
)
6133 ATLASSERT(m_hWnd
!= NULL
);
6134 ::SendMessage(m_hWnd
, TDM_CLICK_RADIO_BUTTON
, nRadioButton
, 0L);
6137 void EnableButton(int nButton
, BOOL bEnable
)
6139 ATLASSERT(m_hWnd
!= NULL
);
6140 ::SendMessage(m_hWnd
, TDM_ENABLE_BUTTON
, nButton
, bEnable
);
6143 void EnableRadioButton(int nButton
, BOOL bEnable
)
6145 ATLASSERT(m_hWnd
!= NULL
);
6146 ::SendMessage(m_hWnd
, TDM_ENABLE_RADIO_BUTTON
, nButton
, bEnable
);
6149 void ClickVerification(BOOL bCheck
, BOOL bFocus
)
6151 ATLASSERT(m_hWnd
!= NULL
);
6152 ::SendMessage(m_hWnd
, TDM_CLICK_VERIFICATION
, bCheck
, bFocus
);
6155 void UpdateElementText(TASKDIALOG_ELEMENTS element
, LPCWSTR lpstrText
)
6157 ATLASSERT(m_hWnd
!= NULL
);
6158 ::SendMessage(m_hWnd
, TDM_UPDATE_ELEMENT_TEXT
, element
, (LPARAM
)lpstrText
);
6161 void SetButtonElevationRequiredState(int nButton
, BOOL bElevation
)
6163 ATLASSERT(m_hWnd
!= NULL
);
6164 ::SendMessage(m_hWnd
, TDM_SET_BUTTON_ELEVATION_REQUIRED_STATE
, nButton
, bElevation
);
6167 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element
, HICON hIcon
)
6169 ATLASSERT(m_hWnd
!= NULL
);
6171 if(element
== TDIE_ICON_MAIN
)
6172 ATLASSERT((m_tdc
.dwFlags
& TDF_USE_HICON_MAIN
) != 0);
6173 else if(element
== TDIE_ICON_FOOTER
)
6174 ATLASSERT((m_tdc
.dwFlags
& TDF_USE_HICON_FOOTER
) != 0);
6176 ::SendMessage(m_hWnd
, TDM_UPDATE_ICON
, element
, (LPARAM
)hIcon
);
6179 void UpdateIcon(TASKDIALOG_ICON_ELEMENTS element
, LPCWSTR lpstrIcon
)
6181 ATLASSERT(m_hWnd
!= NULL
);
6183 if(element
== TDIE_ICON_MAIN
)
6184 ATLASSERT((m_tdc
.dwFlags
& TDF_USE_HICON_MAIN
) == 0);
6185 else if(element
== TDIE_ICON_FOOTER
)
6186 ATLASSERT((m_tdc
.dwFlags
& TDF_USE_HICON_FOOTER
) == 0);
6188 ::SendMessage(m_hWnd
, TDM_UPDATE_ICON
, element
, (LPARAM
)lpstrIcon
);
6193 ///////////////////////////////////////////////////////////////////////////////
6194 // CTaskDialog - for non-customized task dialogs
6196 class CTaskDialog
: public CTaskDialogImpl
<CTaskDialog
>
6199 CTaskDialog(HWND hWndParent
= NULL
) : CTaskDialogImpl
<CTaskDialog
>(hWndParent
)
6201 m_tdc
.pfCallback
= NULL
;
6205 #endif // ((_WIN32_WINNT >= 0x0600) || defined(_WTL_TASKDIALOG)) && !defined(_WIN32_WCE)
6209 #endif // __ATLDLGS_H__