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.
 
 
 
 
 
 

621 lines
17 KiB

/*++
Microsoft Windows
Copyright (C) Microsoft Corporation, 1981 - 2000
Module Name:
pathslct.cxx
Abstract:
This module contains the methods and message handlers for the dialog
that is used to select the redirection destination. This dialog is
used as a child dialog by both the basic and the advanced settings.
Author:
Rahul Thombre (RahulTh) 3/1/2000
Revision History:
3/1/2000 RahulTh Created this module.
--*/
#include "precomp.hxx"
BEGIN_MESSAGE_MAP (CEditNoVars, CEdit)
ON_WM_CHAR()
END_MESSAGE_MAP()
//+--------------------------------------------------------------------------
//
// Member: CEditNoVars::OnChar
//
// Synopsis: Customized edit control behavior. Prevents users from
// entering variables.
//
// Arguments: see MFC documentation
//
// Returns: nothing
//
// History: 3/2/2000 RahulTh created
//
// Notes:
//
//---------------------------------------------------------------------------
void CEditNoVars::OnChar (UINT nChar, UINT nRepCnt, UINT nFlags)
{
// Ignore the * symbol. Do not allow users to type it in.
if ('*' != nChar)
{
CEdit::OnChar (nChar, nRepCnt, nFlags);
}
else
{
// Indicate to the user that % is not permitted in the path.
::MessageBeep (-1);
}
}
// Mapping between control IDs and Help IDs for the path chooser
const DWORD g_aHelpIDMap_IDD_PATHCHOOSER[] =
{
IDC_DESTTYPE, IDH_DESTTYPE,
IDC_ROOT_DESC, IDH_DISABLEHELP,
IDC_ROOT_PATH, IDH_ROOT_PATH,
IDC_BROWSE, IDH_BROWSE,
IDC_SAMPLE_PATH, IDH_DISABLEHELP,
0, 0
};
CPathChooser::CPathChooser(CWnd* pParent /*=NULL*/)
: CDialog(CPathChooser::IDD, pParent), m_pParent (pParent)
{
//{{AFX_DATA_INIT(CPathChooser)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_iCurrType = 0;
}
void CPathChooser::GetRoot (CString & szRoot)
{
m_rootPath.GetWindowText (szRoot);
szRoot.TrimLeft();
szRoot.TrimRight();
szRoot.TrimRight(L'\\');
// When redirecting to the root of a drive, redirect to X:\ rather than X:
if (2 == szRoot.GetLength() && L':' == ((LPCTSTR)szRoot)[1])
szRoot += L'\\';
}
UINT CPathChooser::GetType (void)
{
return m_iCurrType + m_iTypeStart;
}
void
CPathChooser::Instantiate (IN UINT cookie,
IN CWnd * pParent,
IN CWnd * pwndInsertAt,
IN const CRedirPath * pRedirPath,
IN UINT nFlags // = SWP_HIDEWINDOW
)
{
RECT rc;
RECT rc_ctrl;
//
// Now initialize the member variables.
// Note: it is important to set the parent before the making the call to
// Create so that CPathChooser's OnInitDialog is able to set the right
// parent. Otherwise, the window positioning won't work as expected.
//
m_pParent = pParent;
m_cookie = cookie;
m_pRedirPath = pRedirPath;
// First create the modeless window.
this->Create (IDD, pParent);
//
// Set a limit on the number of characters that can be entered into
// into the edit control
//
m_rootPath.SetLimitText (TARGETPATHLIMIT);
// Now adjust the dimensions and place the window that the right location.
pwndInsertAt->ShowWindow (SW_HIDE);
pwndInsertAt->GetWindowRect (&rc);
pParent->ScreenToClient (&rc);
this->SetWindowPos (pwndInsertAt,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
nFlags
);
//
// Now resize and move the controls within this dialog to fit the new size
// Widen the dest. type combo box.
//
m_destType.GetClientRect (&rc_ctrl);
m_destType.SetWindowPos (NULL,
-1,
-1,
rc.right - rc.left,
rc_ctrl.bottom,
SWP_NOZORDER | SWP_NOMOVE
);
//
// Widen the edit control -- set the height to be the same as the
// combo box above
//
m_rootPath.SetWindowPos (NULL,
-1,
-1,
rc.right - rc.left,
rc_ctrl.bottom,
SWP_NOZORDER | SWP_NOMOVE
);
//
// Move the browse button so that it is aligned with the right
// edge of the edit control
//
m_rootPath.GetWindowRect (&rc);
this->ScreenToClient (&rc);
m_browse.GetWindowRect (&rc_ctrl);
this->ScreenToClient (&rc_ctrl);
m_browse.SetWindowPos (NULL,
rc_ctrl.left + rc.right - rc_ctrl.right,
rc_ctrl.top,
-1,
-1,
SWP_NOZORDER | SWP_NOSIZE
);
//
// Change the height and width of the static control used to display
// example per user paths so that it is as wide as the dialog and is
// aligned with the bottom of the control
//
this->GetClientRect (&rc);
m_peruserPathDesc.GetWindowRect (&rc_ctrl);
this->ScreenToClient (&rc_ctrl);
m_iPathDescWidth = rc.right;
m_peruserPathDesc.SetWindowPos (NULL,
-1,
-1,
m_iPathDescWidth,
rc.bottom - rc_ctrl.top,
SWP_NOZORDER | SWP_NOMOVE
);
// Load the values into the controls
PopulateControls ();
}
// Populates the controls based on the values passed into the dialog
void
CPathChooser::PopulateControls (void)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
LONG i;
CString szText;
m_iCurrType = 0;
switch (m_cookie)
{
case IDS_MYDOCS:
m_iTypeStart = IDS_MYDOCS_DESTTYPE_START;
break;
case IDS_STARTMENU:
m_iTypeStart = IDS_SMENU_DESTTYPE_START;
break;
default:
m_iTypeStart = IDS_DESTTYPE_START;
break;
}
// Now populate the destination type combo box based on the settings
for (i = m_iTypeStart; i < IDS_DESTTYPE_END; i++)
{
szText.LoadString (i);
m_destType.AddString ((LPCTSTR) szText);
}
// Put data in the controls.
if (m_pRedirPath->IsPathValid())
{
m_iCurrType = m_pRedirPath->GetType() - m_iTypeStart;
m_pRedirPath->GetPrefix (szText);
m_rootPath.SetWindowText (szText);
m_rootPath.SetModify (TRUE);
}
else
{
//
// Use the first choice for all but the MyDocs folder.
// because the first choice for MyDocs is the HOMEDIR option
// and we want to encourage users to specify the path through
// group policy rather than use the HOMEDIR path set on the user
// object
//
if (IDS_MYDOCS == m_cookie)
m_iCurrType = IDS_PERUSER_PATH - m_iTypeStart;
else
m_iCurrType = 0;
m_rootPath.SetWindowText (L"");
m_rootPath.SetModify (TRUE);
}
// Set the current type
m_destType.SetCurSel (m_iCurrType);
// Make sure that some of the controls are hidden if required
ShowControls ();
//
// Notify the parent that the path has been tweaked so that it can
// update any controls that on it that might depend on the contents of
// this dialog
//
TweakPathNotify ();
}
void CPathChooser::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CPathChooser)
DDX_Control(pDX, IDC_DESTTYPE, m_destType);
DDX_Control(pDX, IDC_ROOT_DESC, m_rootDesc);
DDX_Control(pDX, IDC_ROOT_PATH, m_rootPath);
DDX_Control(pDX, IDC_SAMPLE_PATH, m_peruserPathDesc);
DDX_Control(pDX, IDC_BROWSE, m_browse);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CPathChooser, CDialog)
//{{AFX_MSG_MAP(CPathChooser)
ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
ON_CBN_SELCHANGE (IDC_DESTTYPE, OnDestTypeChange)
ON_EN_CHANGE (IDC_ROOT_PATH, OnChangeRoot)
ON_EN_KILLFOCUS (IDC_ROOT_PATH, OnRootKillFocus)
ON_MESSAGE (WM_HELP, OnHelp)
ON_MESSAGE (WM_CONTEXTMENU, OnContextMenu)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CPathChooser message handlers
BOOL CPathChooser::OnInitDialog()
{
CDialog::OnInitDialog();
//
// Always hide by default. Actual visible state will be determined
// later in the instantiate method.
//
this->ShowWindow (SW_HIDE);
this->SetParent (m_pParent);
// Subclass the edit control to modify behavior
m_rootPath.SubclassDlgItem (IDC_ROOT_PATH, this);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CPathChooser::OnCancel()
{
DestroyWindow ();
}
void CPathChooser::OnBrowse()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
BROWSEINFO browseInfo;
CString szInstructions;
TCHAR pszSelectedFolder[MAX_PATH];
LPITEMIDLIST lpItemIDList;
LPMALLOC pMalloc;
CError error(this);
DWORD dwError;
CString szSelectedPath;
CString szUNC;
szSelectedPath.Empty();
szInstructions.LoadString (IDS_FOLDERBROWSE_DESC);
browseInfo.hwndOwner = m_hWnd;
browseInfo.pidlRoot = NULL;
browseInfo.pszDisplayName = pszSelectedFolder;
browseInfo.lpszTitle = (LPCTSTR)szInstructions;
browseInfo.ulFlags = BIF_RETURNONLYFSDIRS;
browseInfo.lpfn = BrowseCallbackProc;
browseInfo.lParam = (LPARAM) (&szSelectedPath);
if (NULL != (lpItemIDList = SHBrowseForFolder (&browseInfo)))
{
//try to get the path from the item id list
dwError = GetUNCPath (szSelectedPath, szUNC);
if (NO_ERROR != dwError) //then do the best you can
szUNC = szSelectedPath;
if (TARGETPATHLIMIT < szUNC.GetLength())
error.ShowMessage (IDS_PATHTOOLONG_ERROR, TARGETPATHLIMIT);
else
{
m_rootPath.SetWindowText (szUNC);
m_rootPath.SetModify(TRUE);
// Notify the parent that the path has been modified
TweakPathNotify();
}
SHGetMalloc(&pMalloc);
pMalloc->Free (lpItemIDList);
pMalloc->Release();
}
}
void CPathChooser::OnDestTypeChange (void)
{
int Sel;
Sel = m_destType.GetCurSel();
if (Sel == m_iCurrType)
return; // The choice has not changed
// Update the current choice.
m_iCurrType = Sel;
ShowControls();
// Notify the parent of the change
TweakPathNotify ();
}
void CPathChooser::ShowControls (void)
{
int nCmdShow;
switch (m_iCurrType + m_iTypeStart)
{
case IDS_SPECIFIC_PATH:
case IDS_PERUSER_PATH:
nCmdShow = SW_SHOW;
break;
case IDS_USERPROFILE_PATH:
case IDS_HOMEDIR_PATH:
nCmdShow = SW_HIDE;
break;
}
m_browse.ShowWindow (nCmdShow);
m_rootPath.ShowWindow (nCmdShow);
m_rootDesc.ShowWindow (nCmdShow);
}
void CPathChooser::OnChangeRoot()
{
// Notify the parent that the path has changed.
TweakPathNotify ();
}
void CPathChooser::OnRootKillFocus()
{
CString szUNC;
CString szCurr;
m_rootPath.GetWindowText (szCurr);
szCurr.TrimLeft();
szCurr.TrimRight();
szCurr.TrimRight(L'\\');
if (szCurr.IsEmpty() || PathIsUNC ((LPCTSTR)szCurr))
{
return;
}
if (NO_ERROR == GetUNCPath (szCurr, szUNC))
{
if (TARGETPATHLIMIT < szUNC.GetLength())
return;
}
else
{
szUNC = szCurr;
}
//
// if the path is of the form X: change it to X:\ (so that
// the redirection at the client does not run into problems
//
if (2 == szUNC.GetLength() && L':' == ((LPCTSTR)szUNC)[1])
szUNC += L'\\';
m_rootPath.SetWindowText (szUNC);
}
LONG CPathChooser::OnHelp (WPARAM wParam, LPARAM lParam)
{
LONG lResult = 0;
CString szHelpFile;
szHelpFile.LoadString(IDS_HELP_FILE);
::WinHelp((HWND)(((LPHELPINFO)lParam)->hItemHandle),
(LPCTSTR) szHelpFile,
HELP_WM_HELP,
(ULONG_PTR)(LPTSTR)g_aHelpIDMap_IDD_PATHCHOOSER);
return lResult;
}
LONG CPathChooser::OnContextMenu (WPARAM wParam, LPARAM lParam)
{
AFX_MANAGE_STATE (AfxGetStaticModuleState());
LONG lResult = 0;
CString szHelpFile;
szHelpFile.LoadString(IDS_HELP_FILE);
::WinHelp((HWND)wParam,
(LPCTSTR)szHelpFile,
HELP_CONTEXTMENU,
(ULONG_PTR)(LPVOID)g_aHelpIDMap_IDD_PATHCHOOSER);
return lResult;
}
//+--------------------------------------------------------------------------
//
// Member: CPathChooser::TweakPathNotify
//
// Synopsis: Notifies the parent that the path has been tweaked.
//
// Arguments:
//
// Returns:
//
// History: 3/3/2000 RahulTh created
//
// Notes:
//
//---------------------------------------------------------------------------
void
CPathChooser::TweakPathNotify (void)
{
LPARAM lParam;
WPARAM wParam;
CString szRootPath;
WCHAR szCompactPath[MAX_PATH];
static CString szUser = TEXT("");
static CString szPathDesc = TEXT("");
lParam = (LPARAM) (m_iCurrType + m_iTypeStart);
if (-1 == m_iCurrType)
{
wParam = (WPARAM) FALSE;
}
else
{
switch (m_iCurrType + m_iTypeStart)
{
case IDS_PERUSER_PATH:
if (IDS_STARTMENU == m_cookie)
{
wParam = (WPARAM) FALSE;
}
else
{
m_rootPath.GetWindowText (szRootPath);
szRootPath.TrimLeft();
szRootPath.TrimRight();
szRootPath.TrimRight (L'\\');
if (szRootPath.IsEmpty() ||
! IsValidPrefix (IDS_PERUSER_PATH, (LPCTSTR) szRootPath))
{
wParam = (WPARAM) FALSE;
m_peruserPathDesc.ShowWindow (SW_HIDE);
}
else
{
wParam = (WPARAM) TRUE;
if (szUser.IsEmpty())
szUser.LoadString (IDS_SAMPLE_USER);
if (szPathDesc.IsEmpty())
szPathDesc.LoadString (IDS_SAMPLE_PATHDESC);
CString szTmp;
CString szPath;
BOOL bShowPath;
// Check if the path has changed
if (m_pRedirPath->IsPathDifferent (IDS_PERUSER_PATH, szRootPath))
{
CRedirPath displayPath (m_cookie);
displayPath.GenerateSuffix (szTmp, m_cookie, IDS_PERUSER_PATH);
bShowPath = displayPath.Load (IDS_PERUSER_PATH, szRootPath, szTmp);
if (bShowPath)
{
bShowPath = displayPath.GeneratePath (szPath, szUser);
}
}
else
{
bShowPath = m_pRedirPath->GeneratePath (szPath, szUser);
}
if (bShowPath)
bShowPath = (MAX_PATH > szPath.GetLength());
if (bShowPath)
{
lstrcpy (szCompactPath, (LPCTSTR) szPath);
bShowPath = PathCompactPath (NULL, szCompactPath, m_iPathDescWidth);
if (bShowPath)
szTmp.Format (szPathDesc, szUser, szCompactPath);
}
if (bShowPath)
{
m_peruserPathDesc.SetWindowText (szTmp);
m_peruserPathDesc.ShowWindow (SW_SHOW);
}
else
{
m_peruserPathDesc.ShowWindow (SW_HIDE);
}
}
}
break;
case IDS_SPECIFIC_PATH:
m_peruserPathDesc.ShowWindow (SW_HIDE);
m_rootPath.GetWindowText(szRootPath);
szRootPath.TrimLeft();
szRootPath.TrimRight();
szRootPath.TrimRight ('\\');
if (! IsValidPrefix (IDS_SPECIFIC_PATH, (LPCTSTR) szRootPath))
wParam = (WPARAM) FALSE;
else
wParam = (WPARAM) TRUE;
break;
case IDS_HOMEDIR_PATH:
{
CString szTmp;
szTmp.LoadString (IDS_HOMEDIR_WARNING);
m_peruserPathDesc.SetWindowText (szTmp);
m_peruserPathDesc.ShowWindow (SW_SHOW);
wParam = (WPARAM) (m_cookie == IDS_MYDOCS ? TRUE : FALSE);
break;
}
case IDS_USERPROFILE_PATH:
m_peruserPathDesc.ShowWindow (SW_HIDE);
wParam = (WPARAM) TRUE;
break;
default:
m_peruserPathDesc.ShowWindow (SW_HIDE);
wParam = (WPARAM) FALSE;
break;
}
}
m_pParent->SendMessage (WM_PATH_TWEAKED, wParam, lParam);
}