Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: third_party/wtl/include/atldlgs.h

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

Powered by Google App Engine
This is Rietveld 408576698