FS2_Open
Open source remastering of the Freespace 2 engine
folderdlg.cpp
Go to the documentation of this file.
1 /*
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 */
22 
23 #include "FolderDlg.h"
24 
26 
27 #ifndef BFFM_VALIDATEFAILED
28  #ifndef UNICODE
29  #define BFFM_VALIDATEFAILED 3
30  #else
31  #define BFFM_VALIDATEFAILED 4
32  #endif
33 #endif
34 
35 #ifndef BFFM_IUNKNOWN
36  #define BFFM_IUNKNOWN 5
37 #endif
38 
40 // CFolderDialog
41 
42 IMPLEMENT_DYNAMIC( CFolderDialog, CDialog )
43 
44 CFolderDialog::CFolderDialog( IN LPCTSTR pszTitle /*NULL*/,
45  IN LPCTSTR pszSelPath /*NULL*/,
46  IN CWnd* pWndParent /*NULL*/,
47  IN UINT uFlags /*BIF_RETURNONLYFSDIRS*/ )
48  : CCommonDialog( pWndParent )
49  , m_hWnd( NULL )
50 {
51  ::ZeroMemory( &m_bi, sizeof( BROWSEINFO ) );
52  ::ZeroMemory( m_szFolPath, MAX_PATH );
53  ::ZeroMemory( m_szSelPath, MAX_PATH );
54 
55  // Fill data
56 
57  m_bi.hwndOwner = pWndParent->GetSafeHwnd();
58  m_bi.pidlRoot = NULL;
59  m_bi.lpszTitle = pszTitle;
60  m_bi.ulFlags = uFlags;
61  m_bi.lpfn = (BFFCALLBACK)&BrowseCallbackProc;
62  m_bi.lParam = (LPARAM)this;
63 
64  // The size of this buffer is assumed to be MAX_PATH bytes:
65 
66  m_bi.pszDisplayName = new TCHAR[ MAX_PATH ];
67  ASSERT( m_bi.pszDisplayName != NULL );
68 
70  m_bi.pszDisplayName, ( MAX_PATH * sizeof( TCHAR ) )
71  );
72 
73  if( pszSelPath )
74  SetSelectedFolder( pszSelPath );
75 }
76 
78 {
79  SAFE_COTASKMEMFREE( m_bi.pidlRoot );
80  SAFE_DELETE2( m_bi.pszDisplayName );
81 
82  ::ZeroMemory( &m_bi, sizeof( BROWSEINFO ) );
83 }
84 
85 BEGIN_MESSAGE_MAP( CFolderDialog, CCommonDialog )
86 END_MESSAGE_MAP()
87 
89 // CFolderDialog message handlers
90 
91 // SetRootFolder By Jose Insa
92 // Microsoft knowledge Base Article
93 // ID Q132750: Convert a File Path to an ITEMIDLIST
94 
95 BOOL CFolderDialog::SetRootFolder( IN LPCTSTR pszPath )
96 {
97  ASSERT_VALID( this );
98 
99  if( !pszPath )
100  {
101  SAFE_COTASKMEMFREE( m_bi.pidlRoot );
102  return TRUE;
103  }
104 
105  ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
106 
107  HRESULT hResult = S_FALSE;
108  IShellFolder* pDeskFolder = NULL;
109 
110  hResult = ::SHGetDesktopFolder( &pDeskFolder );
111  if ( hResult == S_OK )
112  {
113  LPITEMIDLIST pidlRoot = NULL;
114  LPTSTR pszRoot = const_cast< LPTSTR >( pszPath );
115 
116  // Convert the path to an ITEMIDLIST:
117 
118  USES_CONVERSION;
119 
120  hResult = pDeskFolder->ParseDisplayName(
121  NULL, NULL, T2W( pszRoot ), NULL, &pidlRoot, NULL
122  );
123 
124  if( hResult == S_OK )
125  {
126  SAFE_COTASKMEMFREE( m_bi.pidlRoot );
127  m_bi.pidlRoot = pidlRoot;
128  }
129 
130  SAFE_RELEASE( pDeskFolder );
131  }
132 
133  return ( hResult == S_OK );
134 }
135 
136 // NOTE: pszPath buffer must be at least
137 // MAX_PATH characters in size:
138 
139 BOOL CFolderDialog::GetRootFolder( IN OUT LPTSTR pszPath )
140 {
141  ASSERT_VALID( this );
142  ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
143 
144  return ::SHGetPathFromIDList( m_bi.pidlRoot, pszPath );
145 }
146 
148 {
149  ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
150  return (BOOL)::lstrcpy( m_szSelPath, pszPath );
151 }
152 
154 
155 #if ( _MFC_VER >= 0x0700 )
156  INT_PTR CFolderDialog::DoModal( VOID )
157 #else
159 #endif
160 {
161  ASSERT_VALID( this );
162  ASSERT( m_bi.lpfn != NULL );
163 
164  INT_PTR nRet = -1;
165  m_bi.hwndOwner = PreModal();
166 
167  LPITEMIDLIST pItemIDList = ::SHBrowseForFolder( &m_bi );
168  if( pItemIDList )
169  {
170  if( ::SHGetPathFromIDList( pItemIDList, m_szFolPath ) )
171  nRet = IDOK;
172 
173  SAFE_COTASKMEMFREE( pItemIDList );
174  }
175  else
176  nRet = IDCANCEL;
177 
178 
179  PostModal();
180  return ( nRet );
181 }
182 
184 // Overridables:
185 
187 {
188  if( ::lstrlen( m_szSelPath ) > 0 ) //-V805
190 }
191 
192 VOID CFolderDialog::OnSelChanged( IN LPITEMIDLIST pItemIDList )
193 {
194  if( m_bi.ulFlags & BIF_STATUSTEXT )
195  {
196  TCHAR szSelFol[ MAX_PATH ] = { 0 };
197  if( ::SHGetPathFromIDList( pItemIDList, szSelFol ) )
198  SetStatusText( szSelFol );
199  }
200 }
201 
202 INT CFolderDialog::OnValidateFailed( IN LPCTSTR /*pszPath*/ )
203 {
204  ::MessageBeep( MB_ICONHAND );
205  return 1; // Return 1 to leave dialog open, 0 - to end one
206 }
207 
209 {
210 }
211 
213 // Callback function used with the SHBrowseForFolder function.
214 
215 INT CALLBACK CFolderDialog::BrowseCallbackProc( IN HWND hWnd,
216  IN UINT uMsg,
217  IN LPARAM lParam,
218  IN LPARAM lpData )
219 {
220  CFolderDialog* pThis = (CFolderDialog*)lpData;
221  ASSERT( pThis != NULL );
222 
223  INT nRet = 0;
224  pThis->m_hWnd = hWnd;
225 
226  switch( uMsg )
227  {
228  case BFFM_INITIALIZED:
229  pThis->OnInitialized();
230  break;
231  case BFFM_SELCHANGED:
232  pThis->OnSelChanged( (LPITEMIDLIST)lParam );
233  break;
234  case BFFM_VALIDATEFAILED:
235  nRet = pThis->OnValidateFailed( (LPCTSTR)lParam );
236  break;
237  case BFFM_IUNKNOWN:
238  pThis->OnIUnknown( (IUnknown*)lParam );
239  break;
240  default:
241  ASSERT( FALSE );
242  break;
243  }
244 
245  pThis->m_hWnd = NULL;
246  return nRet;
247 }
248 
250 // Commands, valid to call only from handlers
251 
252 VOID CFolderDialog::SetExpanded( IN LPCTSTR pszPath )
253 {
254  USES_CONVERSION;
255 
256  ASSERT( m_hWnd != NULL );
257  ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
258 
259  ::SendMessage(
260  m_hWnd, BFFM_SETEXPANDED,
261  (WPARAM)TRUE, (LPARAM)T2CW( pszPath )
262  );
263 }
264 
265 VOID CFolderDialog::SetOKText( IN LPCTSTR pszText )
266 {
267  USES_CONVERSION;
268 
269  ASSERT( m_hWnd != NULL );
270 
271  ::SendMessage(
272  m_hWnd, BFFM_SETOKTEXT,
273  (WPARAM)0, (LPARAM)T2CW( pszText )
274  );
275 }
276 
277 VOID CFolderDialog::EnableOK( IN BOOL bEnable /*TRUE*/ )
278 {
279  ASSERT( m_hWnd != NULL );
280 
281  ::SendMessage(
282  m_hWnd, BFFM_ENABLEOK, (WPARAM)bEnable, 0L
283  );
284 }
285 
286 VOID CFolderDialog::SetSelection( IN LPITEMIDLIST pItemIDList )
287 {
288  ASSERT( m_hWnd != NULL );
289 
290  ::SendMessage(
291  m_hWnd, BFFM_SETSELECTION,
292  (WPARAM)FALSE, (LPARAM)pItemIDList
293  );
294 }
295 
296 VOID CFolderDialog::SetSelection( IN LPCTSTR pszPath )
297 {
298  ASSERT( m_hWnd != NULL );
299  ASSERT( AfxIsValidString( pszPath, MAX_PATH ) );
300 
301  ::SendMessage(
302  m_hWnd, BFFM_SETSELECTION,
303  (WPARAM)TRUE, (LPARAM)pszPath
304  );
305 }
306 
307 VOID CFolderDialog::SetStatusText( IN LPCTSTR pszText )
308 {
309  ASSERT( m_hWnd != NULL );
310 
311  ::SendMessage(
312  m_hWnd, BFFM_SETSTATUSTEXT,
313  (WPARAM)0, (LPARAM)pszText
314  );
315 }
316 
317 // Shell version 5.0 or later:
318 
319 VOID CFolderDialog::SetExpanded( IN LPITEMIDLIST pItemIDList )
320 {
321  ASSERT( m_hWnd != NULL );
322 
323  ::SendMessage(
324  m_hWnd, BFFM_SETEXPANDED,
325  (WPARAM)FALSE, (LPARAM)pItemIDList
326  );
327 }
328 
VOID SetExpanded(IN LPCTSTR pszPath)
Definition: folderdlg.cpp:252
void * HWND
Definition: config.h:104
#define BFFM_VALIDATEFAILED
Definition: folderdlg.cpp:29
#define MAX_PATH
VOID EnableOK(IN BOOL bEnable=TRUE)
Definition: folderdlg.cpp:277
#define BFFM_SETOKTEXT
Definition: folderdlg.h:86
virtual VOID OnSelChanged(IN LPITEMIDLIST pItemIDList)
Definition: folderdlg.cpp:192
#define BFFM_SETEXPANDED
Definition: folderdlg.h:87
#define TRUE
Definition: pstypes.h:399
virtual VOID OnInitialized(VOID)
Definition: folderdlg.cpp:186
UINT WPARAM LPARAM lParam
Definition: msacm.h:1064
unsigned int UINT
Definition: config.h:82
long LPARAM
Definition: config.h:101
virtual ~CFolderDialog(VOID)
Definition: folderdlg.cpp:77
DWORD LPCVOID lpData
Definition: vdplobby.h:104
#define SAFE_DELETE2(p)
Definition: folderdlg.h:54
VOID SetSelection(IN LPITEMIDLIST pItemIDList)
Definition: folderdlg.cpp:286
BROWSEINFO m_bi
Definition: folderdlg.h:134
#define BFFM_IUNKNOWN
Definition: folderdlg.cpp:36
virtual INT DoModal(VOID)
Definition: folderdlg.cpp:158
BOOL GetRootFolder(IN OUT LPTSTR pszPath)
Definition: folderdlg.cpp:139
VOID SetOKText(IN LPCTSTR pszText)
Definition: folderdlg.cpp:265
#define MB_ICONHAND
Definition: config.h:191
DWORD UINT uFlags
Definition: wglext.h:728
long HRESULT
Definition: vddraw.h:115
UINT uMsg
Definition: msacm.h:1064
typedef INT(WINAPI *PFNWGLGETGPUINFOAMDPROC)(UINT id
#define CALLBACK
Definition: config.h:75
#define SAFE_RELEASE(p)
Definition: folderdlg.h:68
#define IUnknown
Definition: vddraw.h:28
typedef VOID(WINAPI *PFNWGLDELETEBUFFERREGIONARBPROC)(HANDLE hRegion)
int BOOL
Definition: config.h:80
TCHAR m_szSelPath[MAX_PATH]
Definition: folderdlg.h:136
HWND hWnd
Definition: vddraw.h:425
VOID SetStatusText(IN LPCTSTR pszText)
Definition: folderdlg.cpp:307
virtual VOID OnIUnknown(IN IUnknown *)
Definition: folderdlg.cpp:208
virtual INT OnValidateFailed(IN LPCTSTR)
Definition: folderdlg.cpp:202
#define SAFE_COTASKMEMFREE(p)
Definition: folderdlg.h:74
#define FALSE
Definition: pstypes.h:400
#define SAFE_ZEROMEMORY(p, size)
Definition: folderdlg.h:59
BOOL SetSelectedFolder(IN LPCTSTR pszPath)
Definition: folderdlg.cpp:147