1 /////////////////////////////////////////////////////////////////////////////
2 /*
3 DESCRIPTION:
4 	CFolderDialog  - Folder Selection Dialog Class
5 	Copyright(C) Armen Hakobyan, 2002 - 2005
6 	http://www.codeproject.com/dialog/cfolderdialog.asp
7 
8 VERSION HISTORY:
9 	24 Mar 2002 - First release
10 	30 Mar 2003 - Some minor changes
11 				- Added missing in old Platform SDK new flag definitions
12 				- Added support for both MFC 6.0 and 7.0
13 				- Added OnIUnknown handler for Windows XP folder filtration
14 				- Added SetExpanded and SetOKText and GetSelectedFolder functions
15 	24 May 2003 - Added OnSelChanged implementation
16 	14 Jul 2003 - Added custom filtration for Windows XP, thanks to Arik Poznanski
17 	29 Nov 2003 - Added SetRootFolder, thanks to Eckhard Schwabe ( and Jose Insa )
18 	02 Jan 2004 - Added GetRootFolder, uncomment if needed
19 	15 Feb 2005 - Small bug fix in DoModal, thanks to WindSeven
20 */
21 /////////////////////////////////////////////////////////////////////////////
22 
23 #ifndef __FOLDERDLG_H__
24 #define __FOLDERDLG_H__
25 
26 #if defined( _MSC_VER ) && ( _MSC_VER >= 1020 )
27 	#pragma once
28 #endif
29 
30 /////////////////////////////////////////////////////////////////////////////
31 
32 #ifndef __AFXDLGS_H__
33 	#include < AfxDlgs.h >
34 #endif
35 
36 // Goober5000 - dunno why this wasn't included in the first place
37 #ifndef _INC_SHLOBJ
38 	#include <shlobj.h>
39 #endif
40 
41 #ifndef __ATLCONV_H__
42 	#include < AtlConv.h >	// MBCS/Unicode Conversion Macros
43 #endif
44 
45 // Uncomment if using GetRootFolder
46 //#ifndef _INC_SHLWAPI
47 //	#include < shlwapi.h >
48 //#endif
49 //#pragma comment( lib, "shlwapi.lib" )
50 
51 /////////////////////////////////////////////////////////////////////////////
52 
53 #ifndef		SAFE_DELETE2
54 	#define SAFE_DELETE2( p ) \
55 		if( p ){ delete[] p; p = NULL; }
56 #endif
57 
58 #ifndef		SAFE_ZEROMEMORY
59 	#define SAFE_ZEROMEMORY( p, size ) \
60 		if( p ){ ZeroMemory( p, size ); }
61 #endif
62 
63 #ifndef	SAFE_RELEASE
64 	#if defined( __cplusplus )
65 		#define SAFE_RELEASE( p ) \
66 			if( p ){ p->Release(); p = NULL; }
67 	#else
68 		#define SAFE_RELEASE( p ) \
69 			if( p ){ p->lpVtbl->Release( p ); p = NULL; }
70 	#endif
71 #endif
72 
73 #ifndef		SAFE_COTASKMEMFREE
74 	#define SAFE_COTASKMEMFREE( p ) \
75 		if( p ){ CoTaskMemFree( (LPVOID)p ); p = NULL; }
76 #endif
77 
78 #ifndef		_countof
79 	#define _countof( x ) \
80 		( sizeof( x ) / sizeof( x[ 0 ] ) )
81 #endif
82 
83 /////////////////////////////////////////////////////////////////////////////
84 
85 #ifndef BFFM_SETOKTEXT					// Version 5.0 or later
86 	#define BFFM_SETOKTEXT				( WM_USER + 105 )	// Unicode only, req. BIF_USENEWUI
87 	#define BFFM_SETEXPANDED			( WM_USER + 106 )	// Unicode only, req. BIF_USENEWUI
88 #endif
89 
90 #ifndef BIF_NEWDIALOGSTYLE				// Version 5.0 or later
91 	#define BIF_NEWDIALOGSTYLE			0x0040
92 	#define BIF_BROWSEINCLUDEURLS		0x0080
93 	#define BIF_UAHINT					0x0100				// Req. BIF_NEWDIALOGSTYLE
94 	#define BIF_NONEWFOLDERBUTTON		0x0200
95 	#define BIF_NOTRANSLATETARGETS		0x0400
96 	#define BIF_SHAREABLE				0x8000				// Req. BIF_USENEWUI
97 	#define BIF_USENEWUI				( BIF_NEWDIALOGSTYLE | BIF_EDITBOX )
98 #endif
99 
100 /////////////////////////////////////////////////////////////////////////////
101 
102 class CFolderDialog : public CCommonDialog
103 {
104 	DECLARE_DYNAMIC( CFolderDialog )
105 
106 public:
107 	CFolderDialog(	IN LPCTSTR	pszTitle	= NULL,
108 					IN LPCTSTR	pszSelPath	= NULL,
109 					IN CWnd*	pWndParent	= NULL,
110 					IN UINT		uFlags		= BIF_RETURNONLYFSDIRS );
111 	virtual ~CFolderDialog( VOID );
112 
113 public:
114 	#if ( _MFC_VER >= 0x0700 )	// VC++ 2002 (7.0)
115 		virtual INT_PTR		DoModal( VOID );
116 	#else
117 		virtual INT			DoModal( VOID );
118 	#endif
119 
120 	BOOL	SetRootFolder( IN LPCTSTR pszPath );
121 	BOOL	GetRootFolder( IN OUT LPTSTR pszPath );
122 	BOOL	SetSelectedFolder( IN LPCTSTR pszPath );
123 
124 public:
125 	AFX_INLINE LPCTSTR	GetFolderPath( VOID )  const;
126 	AFX_INLINE LPCTSTR	GetFolderName( VOID )  const;
127 	AFX_INLINE INT		GetFolderImage( VOID ) const;
128 	AFX_INLINE LPCTSTR	GetSelectedFolder( VOID ) const;
129 
130 	AFX_INLINE BROWSEINFO&		 GetBI( VOID );
131 	AFX_INLINE const BROWSEINFO& GetBI( VOID ) const;
132 
133 protected:
134 	BROWSEINFO	m_bi;
135 
136 	TCHAR	m_szSelPath[ MAX_PATH ];
137 	TCHAR	m_szFolPath[ MAX_PATH ];
138 
139 protected:
140 	DECLARE_MESSAGE_MAP()
141 
142 protected: // Overridables
143 
144 	virtual VOID OnInitialized( VOID );
145 	virtual VOID OnSelChanged( IN LPITEMIDLIST  pItemIDList );
146 	virtual INT	 OnValidateFailed( IN LPCTSTR /*pszPath*/ );
147 
148 protected: // Windows XP or later
149 	virtual VOID OnIUnknown( IN IUnknown* /*pIUnknown*/ );
150 
151 protected: // Valid to call only from the above handlers
152 
153 	VOID EnableOK( IN BOOL bEnable = TRUE );
154 	VOID SetSelection( IN LPITEMIDLIST pItemIDList );
155 	VOID SetSelection( IN LPCTSTR pszPath );
156 	VOID SetStatusText( IN LPCTSTR pszText );
157 
158 protected: // Shell version 5.0 or later:
159 	VOID SetExpanded( IN LPCTSTR pszPath );
160 	VOID SetExpanded( IN LPITEMIDLIST pItemIDList );
161 	VOID SetOKText( IN LPCTSTR pszText );
162 
163 private:
164 	HWND m_hWnd; // used only in the callback function
165 
166 private:
167 	static INT CALLBACK BrowseCallbackProc(
168 		IN HWND hWnd, IN UINT uMsg, IN LPARAM lParam, IN LPARAM lpData
169 	);
170 };
171 
172 /////////////////////////////////////////////////////////////////////////////
173 
GetSelectedFolder(VOID)174 AFX_INLINE LPCTSTR CFolderDialog::GetSelectedFolder( VOID ) const
175 	{ return m_szSelPath; }
176 
GetBI(VOID)177 AFX_INLINE BROWSEINFO& CFolderDialog::GetBI( VOID )
178 	{ return m_bi; }
179 
GetBI(VOID)180 AFX_INLINE const BROWSEINFO& CFolderDialog::GetBI( VOID ) const
181 	{ return m_bi; }
182 
183 /////////////////////////////////////////////////////////////////////////////
184 // Filled after a call to DoModal
185 
GetFolderPath(VOID)186 AFX_INLINE LPCTSTR CFolderDialog::GetFolderPath( VOID ) const
187 	{ return m_szFolPath; }
188 
GetFolderName(VOID)189 AFX_INLINE LPCTSTR CFolderDialog::GetFolderName( VOID ) const
190 	{ return m_bi.pszDisplayName; }
191 
GetFolderImage(VOID)192 AFX_INLINE INT CFolderDialog::GetFolderImage( VOID ) const
193 	{ return m_bi.iImage; }
194 
195 /////////////////////////////////////////////////////////////////////////////
196 #endif // __FOLDERDLG_H__
197 /////////////////////////////////////////////////////////////////////////////
198