Leaked source code of windows server 2003
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.

631 lines
18 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 2000
  4. Module Name:
  5. pathslct.cxx
  6. Abstract:
  7. This module contains the methods and message handlers for the dialog
  8. that is used to select the redirection destination. This dialog is
  9. used as a child dialog by both the basic and the advanced settings.
  10. Author:
  11. Rahul Thombre (RahulTh) 3/1/2000
  12. Revision History:
  13. 3/1/2000 RahulTh Created this module.
  14. --*/
  15. #include "precomp.hxx"
  16. BEGIN_MESSAGE_MAP (CEditNoVars, CEdit)
  17. ON_WM_CHAR()
  18. END_MESSAGE_MAP()
  19. //+--------------------------------------------------------------------------
  20. //
  21. // Member: CEditNoVars::OnChar
  22. //
  23. // Synopsis: Customized edit control behavior. Prevents users from
  24. // entering variables.
  25. //
  26. // Arguments: see MFC documentation
  27. //
  28. // Returns: nothing
  29. //
  30. // History: 3/2/2000 RahulTh created
  31. //
  32. // Notes:
  33. //
  34. //---------------------------------------------------------------------------
  35. void CEditNoVars::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
  36. {
  37. // Ignore the * symbol. Do not allow users to type it in.
  38. if ('*' != nChar)
  39. {
  40. CEdit::OnChar (nChar, nRepCnt, nFlags);
  41. }
  42. else
  43. {
  44. // Indicate to the user that % is not permitted in the path.
  45. ::MessageBeep (-1);
  46. }
  47. }
  48. // Mapping between control IDs and Help IDs for the path chooser
  49. const DWORD g_aHelpIDMap_IDD_PATHCHOOSER[] =
  50. {
  51. IDC_DESTTYPE, IDH_DESTTYPE,
  52. IDC_ROOT_DESC, IDH_DISABLEHELP,
  53. IDC_ROOT_PATH, IDH_ROOT_PATH,
  54. IDC_BROWSE, IDH_BROWSE,
  55. IDC_SAMPLE_PATH, IDH_DISABLEHELP,
  56. 0, 0
  57. };
  58. CPathChooser::CPathChooser(CWnd* pParent /*=NULL*/)
  59. : CDialog(CPathChooser::IDD, pParent), m_pParent (pParent)
  60. {
  61. //{{AFX_DATA_INIT(CPathChooser)
  62. // NOTE: the ClassWizard will add member initialization here
  63. //}}AFX_DATA_INIT
  64. m_iCurrType = 0;
  65. }
  66. void CPathChooser::GetRoot (CString & szRoot)
  67. {
  68. m_rootPath.GetWindowText (szRoot);
  69. szRoot.TrimLeft();
  70. szRoot.TrimRight();
  71. szRoot.TrimRight(L'\\');
  72. // When redirecting to the root of a drive, redirect to X:\ rather than X:
  73. if (2 == szRoot.GetLength() && L':' == ((LPCTSTR)szRoot)[1])
  74. szRoot += L'\\';
  75. }
  76. UINT CPathChooser::GetType (void)
  77. {
  78. return m_iCurrType + m_iTypeStart;
  79. }
  80. void
  81. CPathChooser::Instantiate (IN UINT cookie,
  82. IN CWnd * pParent,
  83. IN CWnd * pwndInsertAt,
  84. IN const CRedirPath * pRedirPath,
  85. IN UINT nFlags // = SWP_HIDEWINDOW
  86. )
  87. {
  88. RECT rc;
  89. RECT rc_ctrl;
  90. //
  91. // Now initialize the member variables.
  92. // Note: it is important to set the parent before the making the call to
  93. // Create so that CPathChooser's OnInitDialog is able to set the right
  94. // parent. Otherwise, the window positioning won't work as expected.
  95. //
  96. m_pParent = pParent;
  97. m_cookie = cookie;
  98. m_pRedirPath = pRedirPath;
  99. // First create the modeless window.
  100. this->Create (IDD, pParent);
  101. //
  102. // Set a limit on the number of characters that can be entered into
  103. // into the edit control
  104. //
  105. m_rootPath.SetLimitText (TARGETPATHLIMIT);
  106. // Now adjust the dimensions and place the window that the right location.
  107. pwndInsertAt->ShowWindow (SW_HIDE);
  108. pwndInsertAt->GetWindowRect (&rc);
  109. pParent->ScreenToClient (&rc);
  110. this->SetWindowPos (pwndInsertAt,
  111. rc.left,
  112. rc.top,
  113. rc.right - rc.left,
  114. rc.bottom - rc.top,
  115. nFlags
  116. );
  117. //
  118. // Now resize and move the controls within this dialog to fit the new size
  119. // Widen the dest. type combo box.
  120. //
  121. m_destType.GetClientRect (&rc_ctrl);
  122. m_destType.SetWindowPos (NULL,
  123. -1,
  124. -1,
  125. rc.right - rc.left,
  126. rc_ctrl.bottom,
  127. SWP_NOZORDER | SWP_NOMOVE
  128. );
  129. //
  130. // Widen the edit control -- set the height to be the same as the
  131. // combo box above
  132. //
  133. m_rootPath.SetWindowPos (NULL,
  134. -1,
  135. -1,
  136. rc.right - rc.left,
  137. rc_ctrl.bottom,
  138. SWP_NOZORDER | SWP_NOMOVE
  139. );
  140. //
  141. // Move the browse button so that it is aligned with the right
  142. // edge of the edit control
  143. //
  144. m_rootPath.GetWindowRect (&rc);
  145. this->ScreenToClient (&rc);
  146. m_browse.GetWindowRect (&rc_ctrl);
  147. this->ScreenToClient (&rc_ctrl);
  148. m_browse.SetWindowPos (NULL,
  149. rc_ctrl.left + rc.right - rc_ctrl.right,
  150. rc_ctrl.top,
  151. -1,
  152. -1,
  153. SWP_NOZORDER | SWP_NOSIZE
  154. );
  155. //
  156. // Change the height and width of the static control used to display
  157. // example per user paths so that it is as wide as the dialog and is
  158. // aligned with the bottom of the control
  159. //
  160. this->GetClientRect (&rc);
  161. m_peruserPathDesc.GetWindowRect (&rc_ctrl);
  162. this->ScreenToClient (&rc_ctrl);
  163. m_iPathDescWidth = rc.right;
  164. m_peruserPathDesc.SetWindowPos (NULL,
  165. -1,
  166. -1,
  167. m_iPathDescWidth,
  168. rc.bottom - rc_ctrl.top,
  169. SWP_NOZORDER | SWP_NOMOVE
  170. );
  171. // Load the values into the controls
  172. PopulateControls ();
  173. }
  174. // Populates the controls based on the values passed into the dialog
  175. void
  176. CPathChooser::PopulateControls (void)
  177. {
  178. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  179. LONG i;
  180. CString szText;
  181. m_iCurrType = 0;
  182. switch (m_cookie)
  183. {
  184. case IDS_MYDOCS:
  185. m_iTypeStart = IDS_MYDOCS_DESTTYPE_START;
  186. break;
  187. case IDS_STARTMENU:
  188. m_iTypeStart = IDS_SMENU_DESTTYPE_START;
  189. break;
  190. default:
  191. m_iTypeStart = IDS_DESTTYPE_START;
  192. break;
  193. }
  194. // Now populate the destination type combo box based on the settings
  195. for (i = m_iTypeStart; i < IDS_DESTTYPE_END; i++)
  196. {
  197. szText.LoadString (i);
  198. m_destType.AddString ((LPCTSTR) szText);
  199. }
  200. // Put data in the controls.
  201. if (m_pRedirPath->IsPathValid())
  202. {
  203. m_iCurrType = m_pRedirPath->GetType() - m_iTypeStart;
  204. m_pRedirPath->GetPrefix (szText);
  205. m_rootPath.SetWindowText (szText);
  206. m_rootPath.SetModify (TRUE);
  207. }
  208. else
  209. {
  210. //
  211. // Use the first choice for all but the MyDocs folder.
  212. // because the first choice for MyDocs is the HOMEDIR option
  213. // and we want to encourage users to specify the path through
  214. // group policy rather than use the HOMEDIR path set on the user
  215. // object
  216. //
  217. if (IDS_MYDOCS == m_cookie)
  218. m_iCurrType = IDS_PERUSER_PATH - m_iTypeStart;
  219. else
  220. m_iCurrType = 0;
  221. m_rootPath.SetWindowText (L"");
  222. m_rootPath.SetModify (TRUE);
  223. }
  224. // Set the current type
  225. m_destType.SetCurSel (m_iCurrType);
  226. // Make sure that some of the controls are hidden if required
  227. ShowControls ();
  228. //
  229. // Notify the parent that the path has been tweaked so that it can
  230. // update any controls that on it that might depend on the contents of
  231. // this dialog
  232. //
  233. TweakPathNotify ();
  234. }
  235. void CPathChooser::DoDataExchange(CDataExchange* pDX)
  236. {
  237. CDialog::DoDataExchange(pDX);
  238. //{{AFX_DATA_MAP(CPathChooser)
  239. DDX_Control(pDX, IDC_DESTTYPE, m_destType);
  240. DDX_Control(pDX, IDC_ROOT_DESC, m_rootDesc);
  241. DDX_Control(pDX, IDC_ROOT_PATH, m_rootPath);
  242. DDX_Control(pDX, IDC_SAMPLE_PATH, m_peruserPathDesc);
  243. DDX_Control(pDX, IDC_BROWSE, m_browse);
  244. //}}AFX_DATA_MAP
  245. }
  246. BEGIN_MESSAGE_MAP(CPathChooser, CDialog)
  247. //{{AFX_MSG_MAP(CPathChooser)
  248. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  249. ON_CBN_SELCHANGE (IDC_DESTTYPE, OnDestTypeChange)
  250. ON_EN_CHANGE (IDC_ROOT_PATH, OnChangeRoot)
  251. ON_EN_KILLFOCUS (IDC_ROOT_PATH, OnRootKillFocus)
  252. ON_MESSAGE (WM_HELP, OnHelp)
  253. ON_MESSAGE (WM_CONTEXTMENU, OnContextMenu)
  254. //}}AFX_MSG_MAP
  255. END_MESSAGE_MAP()
  256. /////////////////////////////////////////////////////////////////////////////
  257. // CPathChooser message handlers
  258. BOOL CPathChooser::OnInitDialog()
  259. {
  260. CDialog::OnInitDialog();
  261. //
  262. // Always hide by default. Actual visible state will be determined
  263. // later in the instantiate method.
  264. //
  265. this->ShowWindow (SW_HIDE);
  266. this->SetParent (m_pParent);
  267. // Subclass the edit control to modify behavior
  268. m_rootPath.SubclassDlgItem (IDC_ROOT_PATH, this);
  269. return TRUE; // return TRUE unless you set the focus to a control
  270. // EXCEPTION: OCX Property Pages should return FALSE
  271. }
  272. void CPathChooser::OnCancel()
  273. {
  274. DestroyWindow ();
  275. }
  276. void CPathChooser::OnBrowse()
  277. {
  278. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  279. BROWSEINFO browseInfo;
  280. CString szInstructions;
  281. TCHAR pszSelectedFolder[MAX_PATH];
  282. LPITEMIDLIST lpItemIDList;
  283. LPMALLOC pMalloc;
  284. CError error(this);
  285. DWORD dwError;
  286. CString szSelectedPath;
  287. CString szUNC;
  288. szSelectedPath.Empty();
  289. szInstructions.LoadString (IDS_FOLDERBROWSE_DESC);
  290. browseInfo.hwndOwner = m_hWnd;
  291. browseInfo.pidlRoot = NULL;
  292. browseInfo.pszDisplayName = pszSelectedFolder;
  293. browseInfo.lpszTitle = (LPCTSTR)szInstructions;
  294. browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;
  295. browseInfo.lpfn = BrowseCallbackProc;
  296. browseInfo.lParam = (LPARAM) (&szSelectedPath);
  297. if (NULL != (lpItemIDList = SHBrowseForFolder (&browseInfo)))
  298. {
  299. //try to get the path from the item id list
  300. dwError = GetUNCPath (szSelectedPath, szUNC);
  301. if (NO_ERROR != dwError) //then do the best you can
  302. szUNC = szSelectedPath;
  303. if (TARGETPATHLIMIT < szUNC.GetLength())
  304. error.ShowMessage (IDS_PATHTOOLONG_ERROR, TARGETPATHLIMIT);
  305. else
  306. {
  307. m_rootPath.SetWindowText (szUNC);
  308. m_rootPath.SetModify(TRUE);
  309. // Notify the parent that the path has been modified
  310. TweakPathNotify();
  311. }
  312. if (SUCCEEDED(SHGetMalloc(&pMalloc)))
  313. {
  314. pMalloc->Free (lpItemIDList);
  315. pMalloc->Release();
  316. }
  317. }
  318. }
  319. void CPathChooser::OnDestTypeChange (void)
  320. {
  321. int Sel;
  322. Sel = m_destType.GetCurSel();
  323. if (Sel == m_iCurrType)
  324. return; // The choice has not changed
  325. // Update the current choice.
  326. m_iCurrType = Sel;
  327. ShowControls();
  328. // Notify the parent of the change
  329. TweakPathNotify ();
  330. }
  331. void CPathChooser::ShowControls (void)
  332. {
  333. int nCmdShow;
  334. switch (m_iCurrType + m_iTypeStart)
  335. {
  336. case IDS_SPECIFIC_PATH:
  337. case IDS_PERUSER_PATH:
  338. nCmdShow = SW_SHOW;
  339. break;
  340. case IDS_USERPROFILE_PATH:
  341. case IDS_HOMEDIR_PATH:
  342. nCmdShow = SW_HIDE;
  343. break;
  344. }
  345. m_browse.ShowWindow (nCmdShow);
  346. m_rootPath.ShowWindow (nCmdShow);
  347. m_rootDesc.ShowWindow (nCmdShow);
  348. }
  349. void CPathChooser::OnChangeRoot()
  350. {
  351. // Notify the parent that the path has changed.
  352. TweakPathNotify ();
  353. }
  354. void CPathChooser::OnRootKillFocus()
  355. {
  356. CString szUNC;
  357. CString szCurr;
  358. m_rootPath.GetWindowText (szCurr);
  359. szCurr.TrimLeft();
  360. szCurr.TrimRight();
  361. szCurr.TrimRight(L'\\');
  362. if (szCurr.IsEmpty() || PathIsUNC ((LPCTSTR)szCurr))
  363. {
  364. return;
  365. }
  366. if (NO_ERROR == GetUNCPath (szCurr, szUNC))
  367. {
  368. if (TARGETPATHLIMIT < szUNC.GetLength())
  369. return;
  370. }
  371. else
  372. {
  373. szUNC = szCurr;
  374. }
  375. //
  376. // if the path is of the form X: change it to X:\ (so that
  377. // the redirection at the client does not run into problems
  378. //
  379. if (2 == szUNC.GetLength() && L':' == ((LPCTSTR)szUNC)[1])
  380. szUNC += L'\\';
  381. m_rootPath.SetWindowText (szUNC);
  382. }
  383. LONG CPathChooser::OnHelp (WPARAM wParam, LPARAM lParam)
  384. {
  385. LONG lResult = 0;
  386. CString szHelpFile;
  387. szHelpFile.LoadString(IDS_HELP_FILE);
  388. ::WinHelp((HWND)(((LPHELPINFO)lParam)->hItemHandle),
  389. (LPCTSTR) szHelpFile,
  390. HELP_WM_HELP,
  391. (ULONG_PTR)(LPTSTR)g_aHelpIDMap_IDD_PATHCHOOSER);
  392. return lResult;
  393. }
  394. LONG CPathChooser::OnContextMenu (WPARAM wParam, LPARAM lParam)
  395. {
  396. AFX_MANAGE_STATE (AfxGetStaticModuleState());
  397. LONG lResult = 0;
  398. CString szHelpFile;
  399. szHelpFile.LoadString(IDS_HELP_FILE);
  400. ::WinHelp((HWND)wParam,
  401. (LPCTSTR)szHelpFile,
  402. HELP_CONTEXTMENU,
  403. (ULONG_PTR)(LPVOID)g_aHelpIDMap_IDD_PATHCHOOSER);
  404. return lResult;
  405. }
  406. //+--------------------------------------------------------------------------
  407. //
  408. // Member: CPathChooser::TweakPathNotify
  409. //
  410. // Synopsis: Notifies the parent that the path has been tweaked.
  411. //
  412. // Arguments:
  413. //
  414. // Returns:
  415. //
  416. // History: 3/3/2000 RahulTh created
  417. //
  418. // Notes:
  419. //
  420. //---------------------------------------------------------------------------
  421. void
  422. CPathChooser::TweakPathNotify (void)
  423. {
  424. LPARAM lParam;
  425. WPARAM wParam;
  426. CString szRootPath;
  427. WCHAR szCompactPath[MAX_PATH];
  428. static CString szUser = TEXT("");
  429. static CString szPathDesc = TEXT("");
  430. lParam = (LPARAM) (m_iCurrType + m_iTypeStart);
  431. if (-1 == m_iCurrType)
  432. {
  433. wParam = (WPARAM) FALSE;
  434. }
  435. else
  436. {
  437. switch (m_iCurrType + m_iTypeStart)
  438. {
  439. case IDS_PERUSER_PATH:
  440. if (IDS_STARTMENU == m_cookie)
  441. {
  442. wParam = (WPARAM) FALSE;
  443. }
  444. else
  445. {
  446. m_rootPath.GetWindowText (szRootPath);
  447. szRootPath.TrimLeft();
  448. szRootPath.TrimRight();
  449. szRootPath.TrimRight (L'\\');
  450. if (szRootPath.IsEmpty() ||
  451. ! IsValidPrefix (IDS_PERUSER_PATH, (LPCTSTR) szRootPath))
  452. {
  453. wParam = (WPARAM) FALSE;
  454. m_peruserPathDesc.ShowWindow (SW_HIDE);
  455. }
  456. else
  457. {
  458. wParam = (WPARAM) TRUE;
  459. if (szUser.IsEmpty())
  460. szUser.LoadString (IDS_SAMPLE_USER);
  461. if (szPathDesc.IsEmpty())
  462. szPathDesc.LoadString (IDS_SAMPLE_PATHDESC);
  463. CString szTmp;
  464. CString szPath;
  465. BOOL bShowPath;
  466. // Check if the path has changed
  467. if (m_pRedirPath->IsPathDifferent (IDS_PERUSER_PATH, szRootPath))
  468. {
  469. CRedirPath displayPath (m_cookie);
  470. displayPath.GenerateSuffix (szTmp, m_cookie, IDS_PERUSER_PATH);
  471. bShowPath = displayPath.Load (IDS_PERUSER_PATH, szRootPath, szTmp);
  472. if (bShowPath)
  473. {
  474. bShowPath = displayPath.GeneratePath (szPath, szUser);
  475. }
  476. }
  477. else
  478. {
  479. bShowPath = m_pRedirPath->GeneratePath (szPath, szUser);
  480. }
  481. if (bShowPath)
  482. bShowPath = (MAX_PATH > szPath.GetLength());
  483. if (bShowPath)
  484. {
  485. HRESULT hr;
  486. hr = StringCchCopy (szCompactPath, sizeof(szCompactPath)/sizeof(szCompactPath[0]), (LPCTSTR) szPath);
  487. if (FAILED(hr))
  488. {
  489. wParam = FALSE;
  490. break;
  491. }
  492. bShowPath = PathCompactPath (NULL, szCompactPath, m_iPathDescWidth);
  493. if (bShowPath)
  494. szTmp.Format (szPathDesc, szUser, szCompactPath);
  495. }
  496. if (bShowPath)
  497. {
  498. m_peruserPathDesc.SetWindowText (szTmp);
  499. m_peruserPathDesc.ShowWindow (SW_SHOW);
  500. }
  501. else
  502. {
  503. m_peruserPathDesc.ShowWindow (SW_HIDE);
  504. }
  505. }
  506. }
  507. break;
  508. case IDS_SPECIFIC_PATH:
  509. m_peruserPathDesc.ShowWindow (SW_HIDE);
  510. m_rootPath.GetWindowText(szRootPath);
  511. szRootPath.TrimLeft();
  512. szRootPath.TrimRight();
  513. szRootPath.TrimRight ('\\');
  514. if (! IsValidPrefix (IDS_SPECIFIC_PATH, (LPCTSTR) szRootPath))
  515. wParam = (WPARAM) FALSE;
  516. else
  517. wParam = (WPARAM) TRUE;
  518. break;
  519. case IDS_HOMEDIR_PATH:
  520. {
  521. CString szTmp;
  522. szTmp.LoadString (IDS_HOMEDIR_WARNING);
  523. m_peruserPathDesc.SetWindowText (szTmp);
  524. m_peruserPathDesc.ShowWindow (SW_SHOW);
  525. wParam = (WPARAM) (m_cookie == IDS_MYDOCS ? TRUE : FALSE);
  526. break;
  527. }
  528. case IDS_USERPROFILE_PATH:
  529. m_peruserPathDesc.ShowWindow (SW_HIDE);
  530. wParam = (WPARAM) TRUE;
  531. break;
  532. default:
  533. m_peruserPathDesc.ShowWindow (SW_HIDE);
  534. wParam = (WPARAM) FALSE;
  535. break;
  536. }
  537. }
  538. m_pParent->SendMessage (WM_PATH_TWEAKED, wParam, lParam);
  539. }