////////////////////////////////////////////////////////////////////////// //PathDialog.h file // //Written by Nguyen Tan Hung <tanhung@yahoo.com> ////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "PathDialog.h" #include <io.h> #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define IDC_FOLDERTREE 0x3741 #define IDC_TITLE 0x3742 #define IDC_STATUSTEXT 0x3743 #define IDC_NEW_EDIT_PATH 0x3744 // Class CDlgWnd BEGIN_MESSAGE_MAP(CPathDialogSub, CWnd) ON_BN_CLICKED(IDOK, OnOK) ON_EN_CHANGE(IDC_NEW_EDIT_PATH, OnChangeEditPath) END_MESSAGE_MAP() void CPathDialogSub::OnOK() { ::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH), m_pPathDialog->m_szPathName, MAX_PATH); if(CPathDialog::MakeSurePathExists(m_pPathDialog->m_szPathName)==0) { m_pPathDialog->m_bGetSuccess=TRUE; ::EndDialog(m_pPathDialog->m_hWnd, IDOK); } else { ::SetFocus(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH)); } } void CPathDialogSub::OnChangeEditPath() { ::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH), m_pPathDialog->m_szPathName, MAX_PATH); BOOL bEnableOKButton = (_tcslen(m_pPathDialog->m_szPathName)>0); SendMessage(BFFM_ENABLEOK, 0, bEnableOKButton); } ///////////////////////////////////////////////////////////////////////////// // CPathDialog dialog CPathDialog::CPathDialog(LPCTSTR lpszCaption, LPCTSTR lpszTitle, LPCTSTR lpszInitialPath, CWnd* pParent) { m_hWnd=NULL; m_PathDialogSub.m_pPathDialog= this; m_bParentDisabled = FALSE; // Get the true parent of the dialog m_pParentWnd = CWnd::GetSafeOwner(pParent); m_lpszCaption = lpszCaption; m_lpszInitialPath = lpszInitialPath; memset(&m_bi, 0, sizeof(BROWSEINFO) ); m_bi.hwndOwner = (m_pParentWnd==NULL)?NULL:m_pParentWnd->GetSafeHwnd(); m_bi.pszDisplayName = 0; m_bi.pidlRoot = 0; m_bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; m_bi.lpfn = BrowseCallbackProc; m_bi.lpszTitle = lpszTitle; } ///////////////////////////////////////////////////////////////////////////// // CPathDialog message handlers CString CPathDialog::GetPathName() { return CString(m_szPathName); } int CALLBACK CPathDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData) { CPathDialog* pDlg = (CPathDialog*)pData; switch(uMsg) { case BFFM_INITIALIZED: { RECT rc; HWND hEdit; HFONT hFont; pDlg->m_hWnd = hwnd; if(pDlg->m_lpszCaption!=NULL) { ::SetWindowText(hwnd, pDlg->m_lpszCaption); } VERIFY(pDlg->m_PathDialogSub.SubclassWindow(hwnd)); ::ShowWindow(::GetDlgItem(hwnd, IDC_STATUSTEXT), SW_HIDE); ::GetWindowRect(::GetDlgItem(hwnd, IDC_FOLDERTREE), &rc); rc.bottom = rc.top - 4; rc.top = rc.bottom - 23; ::ScreenToClient(hwnd, (LPPOINT)&rc); ::ScreenToClient(hwnd, ((LPPOINT)&rc)+1); hEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_CHILD|WS_TABSTOP|WS_VISIBLE|ES_AUTOHSCROLL, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hwnd, NULL, NULL, NULL); ::SetWindowLong(hEdit, GWL_ID, IDC_NEW_EDIT_PATH); ::ShowWindow(hEdit, SW_SHOW); hFont = (HFONT)::SendMessage(hwnd, WM_GETFONT, 0, 0); ::SendMessage(hEdit, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(TRUE, 0)); LPCTSTR lpszPath = pDlg->m_lpszInitialPath; TCHAR szTemp[MAX_PATH]; if(lpszPath==NULL) { ::GetCurrentDirectory(MAX_PATH, szTemp ); lpszPath = szTemp; } // WParam is TRUE since you are passing a path. // It would be FALSE if you were passing a pidl. ::SendMessage(hwnd,BFFM_SETSELECTION,TRUE, (LPARAM)lpszPath); break; } case BFFM_SELCHANGED: { char szSelection[MAX_PATH]; if(!::SHGetPathFromIDList((LPITEMIDLIST)lParam, szSelection) || (szSelection[1] !=':' && szSelection[1] != '\\')) { szSelection[0] = '\0'; ::SendMessage(hwnd, BFFM_ENABLEOK, 0, FALSE); } else { ::SendMessage(hwnd, BFFM_ENABLEOK, 0, TRUE); } ::SendMessage(hwnd,BFFM_SETSTATUSTEXT,0,(LPARAM)szSelection); ::SetWindowText(::GetDlgItem(hwnd, IDC_NEW_EDIT_PATH), szSelection); break; } default: break; } return 0; } int CPathDialog::DoModal() { ///////////////////////////////////////////////////////// TCHAR szPathTemp[MAX_PATH]; m_bi.lpfn = BrowseCallbackProc; // address of callback function m_bi.lParam = (LPARAM)this; // pass address of object to callback function m_bi.pszDisplayName = szPathTemp; LPITEMIDLIST pidl; LPMALLOC pMalloc; int iResult=-1; if(SUCCEEDED(SHGetMalloc(&pMalloc))) { m_bGetSuccess = FALSE; pidl = SHBrowseForFolder(&m_bi); if (pidl!=NULL) { //not need do this because OnOK function did //bSucceeded = SHGetPathFromIDList(pidl, m_szPathName); // In C++: pMalloc->Free(pidl); //In C: //pMalloc->lpVtbl->Free(pMalloc,pidl); //pMalloc->lpVtbl->Release(pMalloc); } if(m_bGetSuccess) { iResult = IDOK; } pMalloc->Release(); } if(m_bParentDisabled && (m_pParentWnd!=NULL)) { m_pParentWnd->EnableWindow(TRUE); } m_bParentDisabled=FALSE; return iResult; } BOOL CPathDialog::IsFileNameValid(LPCTSTR lpFileName) { return TRUE; } const TCHAR c_FolderDoesNotExist[] = _T( "The folder:\n\n" "%s\n\n" "does not exist. Do you want the folder to be created?"); const TCHAR c_szErrInvalidPath[] = _T( "The folder:" "\n\n" "%s\n\n" "is invalid. Please reenter."); const TCHAR c_szErrCreatePath[] = _T( "The folder:" "\n\n" "%s" "\n\ncan not be created. Please double check."); //return -1: user break; //return 0: no error //return 1: lpPath is invalid //return 2: can not create lpPath int CPathDialog::MakeSurePathExists(LPCTSTR lpPath) { CString strMsg; int iRet; try { //validate path iRet=Touch(lpPath, TRUE); if(iRet!=0) { throw iRet; } if(_taccess(lpPath, 0)==0) { return (int)0; } strMsg.Format(c_FolderDoesNotExist, lpPath); if(AfxMessageBox(strMsg, MB_YESNO|MB_ICONQUESTION) != IDYES) { return (int)-1; } //create path iRet=Touch(lpPath, FALSE); if(iRet!=0) { throw iRet; } return 0; } catch(int nErrCode) { switch(nErrCode) { case 1: strMsg.Format(c_szErrInvalidPath, lpPath); break; case 2: default: strMsg.Format(c_szErrCreatePath, lpPath); break; } AfxMessageBox(strMsg, MB_OK|MB_ICONEXCLAMATION); } return iRet; } //return 0: no error //return 1: lpPath is invalid //return 2: lpPath can not be created(bValidate==FALSE) int CPathDialog::Touch(LPCTSTR lpPath, BOOL bValidate) { if(lpPath==NULL) { return 1; } TCHAR szPath[MAX_PATH]; _tcscpy(szPath, lpPath); size_t nLen = _tcslen(szPath); int i; if(nLen==3) { if(!bValidate) { if(_access(szPath, 0)!=0) { return 2; } } return 0; } i = 3; BOOL bLastOne=TRUE; LPTSTR lpCurrentName; while(szPath[i]!=0) { lpCurrentName = &szPath[i]; while( (szPath[i]!=0) && (szPath[i]!=_T('\\')) ) { i++; } bLastOne =(szPath[i]==0); szPath[i] = 0; if(!bValidate) { CreateDirectory(szPath, NULL); if(_taccess(szPath, 0)!=0) { return 2; } } if(bLastOne) { break; //it's done } else { szPath[i] = _T('\\'); } i++; } return (bLastOne?0:1); } //return 0: ok //return 1: error int CPathDialog::ConcatPath(LPTSTR lpRoot, LPCTSTR lpMorePath) { if(lpRoot==NULL) { return 1; } size_t nLen = _tcslen(lpRoot); if(nLen<3) { return 1; } if(lpMorePath==NULL) { return 0; } if(nLen==3) { _tcscat(lpRoot, lpMorePath); return 0; } _tcscat(lpRoot, _T("\\")); _tcscat(lpRoot, lpMorePath); return 0; }