Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

319 lines
6.5 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. dirbrows.cpp
  5. Abstract:
  6. Directory Browser Dialog. Allow browsing for directories only.
  7. optionally allows UNC conversions for remote paths.
  8. Author:
  9. Ronald Meijer (ronaldm)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. //
  15. // Include Files
  16. //
  17. #include "stdafx.h"
  18. #include "common.h"
  19. #include "dirbrows.h"
  20. #include <dlgs.h>
  21. #ifdef _DEBUG
  22. #undef THIS_FILE
  23. static char BASED_CODE THIS_FILE[] = __FILE__;
  24. #endif
  25. extern HINSTANCE hDLLInstance;
  26. static
  27. int
  28. BrowseCallbackProc(
  29. IN HWND hwnd,
  30. IN UINT uMsg,
  31. IN LPARAM lParam,
  32. IN LPARAM lpData
  33. )
  34. /*++
  35. Routine Description:
  36. Callback function for the folder browser
  37. Arguments:
  38. hwnd : Handle to the browse dialog box. The callback function can
  39. send the following messages to this window:
  40. BFFM_ENABLEOK Enables the OK button if the wParam parameter
  41. is nonzero or disables it if wParam is zero.
  42. BFFM_SETSELECTION Selects the specified folder. The lParam
  43. parameter is the PIDL of the folder to select
  44. if wParam is FALSE, or it is the path of the
  45. folder otherwise.
  46. BFFM_SETSTATUSTEXT Sets the status text to the null-terminated
  47. string specified by the lParam parameter.
  48. uMsg : Value identifying the event. This parameter can be one of the
  49. following values:
  50. 0 Initialize dir path. lParam is the path.
  51. BFFM_INITIALIZED The browse dialog box has finished
  52. initializing. lpData is NULL.
  53. BFFM_SELCHANGED The selection has changed. lpData
  54. is a pointer to the item identifier list for
  55. the newly selected folder.
  56. lParam : Message-specific value. For more information, see the
  57. description of uMsg.
  58. lpData : Application-defined value that was specified in the lParam
  59. member of the BROWSEINFO structure.
  60. Return Value:
  61. 0
  62. --*/
  63. {
  64. lpData;
  65. static LPCTSTR lpstrDir = NULL;
  66. switch(uMsg)
  67. {
  68. case 0:
  69. lpstrDir = (LPCTSTR)lParam;
  70. break;
  71. case BFFM_INITIALIZED:
  72. //
  73. // Dialog initialized -- select desired folder
  74. //
  75. if (lpstrDir != NULL)
  76. {
  77. ::SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)lpstrDir);
  78. }
  79. break;
  80. }
  81. return 0;
  82. }
  83. CDirBrowseDlg::CDirBrowseDlg(
  84. IN CWnd * pParent OPTIONAL,
  85. IN LPCTSTR lpszInitialDir OPTIONAL
  86. )
  87. /*++
  88. Routine Description:
  89. Constructor for directory browser dialog
  90. Arguments:
  91. CWnd * pParent : Parent window or NULL
  92. LPCTSTR lpszInitialDir : Initial directory, or NULL for current directory
  93. Return Value:
  94. N/A
  95. --*/
  96. : m_strInitialDir(lpszInitialDir)
  97. {
  98. VERIFY(m_bstrTitle.LoadString(hDLLInstance, IDS_BROWSE_DIRECTORY));
  99. m_bi.pidlRoot = NULL;
  100. m_bi.hwndOwner = pParent ? pParent->m_hWnd : NULL;
  101. m_bi.pszDisplayName = m_szBuffer;
  102. m_bi.lpszTitle = m_bstrTitle;
  103. m_bi.ulFlags = BIF_RETURNFSANCESTORS | BIF_RETURNONLYFSDIRS,
  104. m_bi.lpfn = BrowseCallbackProc;
  105. m_bi.lParam = 0;
  106. //
  107. // Let the callback function know the default dir is
  108. //
  109. lpszInitialDir = !m_strInitialDir.IsEmpty()
  110. ? (LPCTSTR)m_strInitialDir : NULL;
  111. BrowseCallbackProc(m_bi.hwndOwner, 0, (LPARAM)lpszInitialDir, NULL);
  112. }
  113. CDirBrowseDlg::~CDirBrowseDlg()
  114. /*++
  115. Routine Description:
  116. Destructor for directory browser dialog
  117. Arguments:
  118. N/A
  119. Return Value:
  120. N/A
  121. --*/
  122. {
  123. if (m_bi.pidlRoot != NULL)
  124. {
  125. LPITEMIDLIST pidl = (LPITEMIDLIST)m_bi.pidlRoot;
  126. //
  127. // Free using shell allocator
  128. //
  129. LPMALLOC pMalloc;
  130. if (::SHGetMalloc(&pMalloc) == NOERROR)
  131. {
  132. pMalloc->Free(pidl);
  133. pMalloc->Release();
  134. }
  135. }
  136. }
  137. /* virtual */
  138. int
  139. CDirBrowseDlg::DoModal()
  140. /*++
  141. Routine Description:
  142. Display the browser dialog, and fill in the selected directory path.
  143. Arguments:
  144. None
  145. Return Value:
  146. IDOK if the OK button was pressed, IDCANCEL otherwise.
  147. --*/
  148. {
  149. BOOL fSelectionMade = FALSE;
  150. //
  151. // Get the Shell's default allocator
  152. //
  153. LPMALLOC pMalloc;
  154. if (::SHGetMalloc(&pMalloc) == NOERROR)
  155. {
  156. LPITEMIDLIST pidl;
  157. if ((pidl = ::SHBrowseForFolder(&m_bi)) != NULL)
  158. {
  159. if (::SHGetPathFromIDList(pidl, m_szBuffer))
  160. {
  161. fSelectionMade = TRUE;
  162. }
  163. else
  164. {
  165. //
  166. // OK Pressed, but no path found
  167. //
  168. ::AfxMessageBox(IDS_BAD_BROWSE);
  169. }
  170. //
  171. // Free the PIDL allocated by SHBrowseForFolder.
  172. //
  173. pMalloc->Free(pidl);
  174. }
  175. //
  176. // Release the shell's allocator.
  177. //
  178. pMalloc->Release();
  179. }
  180. return fSelectionMade ? IDOK : IDCANCEL;
  181. }
  182. LPCTSTR
  183. CDirBrowseDlg::GetFullPath(
  184. OUT CString & strName,
  185. IN BOOL fConvertToUNC
  186. ) const
  187. /*++
  188. Routine Description:
  189. Get the full path selected. Optionally allow a remote path to be
  190. converted to a UNC path.
  191. Arguments:
  192. CString & strName : String in which to return the directory path
  193. BOOL fConvertToUNC : If TRUE, then if the drive selected is a network
  194. drive, convert the path to a UNC path.
  195. Return Value:
  196. A pointer to the directory path string or NULL in case of error.
  197. Notes:
  198. This function should be called only after the dialog has been dismissed.
  199. --*/
  200. {
  201. LPCTSTR lp = NULL;
  202. try
  203. {
  204. strName = m_szBuffer;
  205. lp = strName;
  206. if (fConvertToUNC && lp != NULL)
  207. {
  208. //
  209. // If it's network drive, convert it to a UNC path
  210. //
  211. CString strDrive, strUNC;
  212. if (IsNetworkPath(strName, &strDrive, &strUNC))
  213. {
  214. strUNC += (lp + 2);
  215. strName = strUNC;
  216. }
  217. lp = strName;
  218. }
  219. }
  220. catch(CMemoryException * e)
  221. {
  222. TRACEEOLID("!!!exception getting path");
  223. strName.Empty();
  224. e->ReportError();
  225. e->Delete();
  226. }
  227. return lp;
  228. }