#include "stdafx.h" #include "PathDialog.h" #include #include #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 #define IDC_NEW_EDIT_PATH 0xFFFF // 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_pdlg->m_szPathName, MAX_PATH); if (CPathDialog::MakeSurePathExists(m_pdlg->m_szPathName) == 0) { m_pdlg->m_bSuccess = TRUE; ::EndDialog(m_pdlg->m_hWnd, IDOK); } else { ::SetFocus(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH)); } } void CPathDialogSub::OnChangeEditPath() { ::GetWindowText(::GetDlgItem(m_hWnd, IDC_NEW_EDIT_PATH), m_pdlg->m_szPathName, MAX_PATH); SendMessage(BFFM_ENABLEOK, 0, _tcslen(m_pdlg->m_szPathName) > 0); } ///////////////////////////////////////////////////////////////////////////// // CPathDialog dialog CPathDialog::CPathDialog(LPCTSTR pszCaption, LPCTSTR pszTitle, LPCTSTR pszInitialPath, CWnd* pParent) { m_dlg.m_pdlg = this; m_hWnd = NULL; // Get the true parent of the dialog m_pwndParent = CWnd::GetSafeOwner(pParent); m_pszCaption = pszCaption; m_pszInitialPath = pszInitialPath; memset(&m_bi, 0, sizeof(m_bi)); m_bi.hwndOwner = !m_pwndParent ? NULL : m_pwndParent->GetSafeHwnd(); m_bi.pszDisplayName = 0; m_bi.pidlRoot = 0; // m_bi.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT; m_bi.ulFlags = BIF_NEWDIALOGSTYLE; m_bi.lpfn = BrowseCallbackProc; m_bi.lpszTitle = pszTitle; // m_bi.lParam = (LPARAM)pszInitialPath; } ///////////////////////////////////////////////////////////////////////////// // CPathDialog message handlers CString CPathDialog::GetPathName() { return m_szPathName; } int CALLBACK CPathDialog::BrowseCallbackProc(HWND hwnd,UINT uMsg,LPARAM lParam, LPARAM pData) { CPathDialog* pdlg = (CPathDialog*)pData; switch (uMsg) { case BFFM_INITIALIZED: { pdlg->m_hWnd = hwnd; if (pdlg->m_pszCaption != NULL) ::SetWindowText(hwnd, pdlg->m_pszCaption); VERIFY(pdlg->m_dlg.SubclassWindow(hwnd)); ::ShowWindow(::GetDlgItem(hwnd, IDC_STATUSTEXT), SW_HIDE); RECT rc; ::GetWindowRect(::GetDlgItem(hwnd, IDC_FOLDERTREE), &rc); rc.bottom = rc.top - 2; rc.top = rc.bottom - 23; rc.left = rc.left + 2; ::ScreenToClient(hwnd, (LPPOINT)&rc); ::ScreenToClient(hwnd, ((LPPOINT)&rc) + 1); HWND hwndEdit = ::CreateWindowEx(WS_EX_CLIENTEDGE, _T("EDIT"), _T(""), WS_VISIBLE | WS_CHILD | WS_TABSTOP, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, hwnd, NULL, NULL, NULL); ::SetWindowLong(hwndEdit, GWL_ID, IDC_NEW_EDIT_PATH); ::ShowWindow(hwndEdit, SW_SHOW); HFONT hfont = (HFONT)::SendMessage(hwnd, WM_GETFONT, 0, 0); ::SendMessage(hwndEdit, WM_SETFONT, (WPARAM)hfont, MAKELPARAM(TRUE, 0)); LPCTSTR lpszPath = pdlg->m_pszInitialPath; TCHAR szPath[MAX_PATH]; if (lpszPath == NULL) { ::GetCurrentDirectory(MAX_PATH, szPath); lpszPath = szPath; } if (GetFileAttributes(lpszPath) == INVALID_FILE_ATTRIBUTES && GetLastError() == ERROR_FILE_NOT_FOUND) { SHGetSpecialFolderPath(hwnd, szPath, CSIDL_PERSONAL, 0); lpszPath = szPath; } else ::SendMessage(hwnd,BFFM_SETSELECTION, TRUE, (LPARAM)lpszPath); ::SetWindowText(::GetDlgItem(hwnd, IDC_NEW_EDIT_PATH), lpszPath); } break; case BFFM_SELCHANGED: { char szSelection[MAX_PATH]; // if (!::SHGetPathFromIDList((LPITEMIDLIST)lParam, szSelection) || szSelection[1]!=':') { if (!::SHGetPathFromIDList((LPITEMIDLIST)lParam, szSelection)) { szSelection[0] = NULL; ::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 szDiaplayName[MAX_PATH]; m_bi.lpfn = BrowseCallbackProc; m_bi.lParam = (LPARAM)this; m_bi.pszDisplayName = szDiaplayName; LPITEMIDLIST pidl; LPMALLOC pmalloc; int nRet = -1; if (SUCCEEDED(SHGetMalloc(&pmalloc))) { m_bSuccess = FALSE; pidl = SHBrowseForFolder(&m_bi); if (pidl) pmalloc->Free(pidl); if (m_bSuccess) nRet = IDOK; pmalloc->Release(); } return nRet; } BOOL CPathDialog::IsValidFileName(LPCTSTR pszFileName) { if (pszFileName == NULL) return FALSE; int nLen = (int)_tcslen(pszFileName); if (nLen <= 0) return FALSE; //check first char switch (pszFileName[0]) { case _T('.'): case _T(' '): case _T('\t'): return FALSE; } //check last char switch (pszFileName[nLen-1]) { case _T('.'): case _T(' '): case _T('\t'): return FALSE; } //check all int i = 0; while (pszFileName[i] != 0) { switch (pszFileName[i]) { case _T('\\'): case _T('/'): case _T(':'): case _T('*'): case _T('?'): case _T('\"'): case _T('<'): case _T('>'): case _T('|'): return FALSE; } i++; } return TRUE; } const TCHAR c_FolderDoesNotPermission[] = _T( "Æú´õ : \n" "%s\n\n" "¿¡ Á¢±ÙÇÒ ¼ö ¾ø½À´Ï´Ù. ´Ù¸¥ À§Ä¡¸¦ ¼±ÅÃÇϽʽÿÀ." ); const TCHAR c_FolderDoesNotExist[] = _T( "Æú´õ : \n" "%s\n\n" "°¡ Á¸ÀçÇϽà ¾Ê½À´Ï´Ù. Æú´õ¸¦ »ý¼ºÇϽðڽÀ´Ï±î?" ); const TCHAR c_szErrInvalidPath[] = _T( "Æú´õ : \n" "%s\n\n" "°¡ À߸øµÇ¾ú½À´Ï´Ù. ´Ù½Ã ÀÔ·ÂÇϽʽÿÀ." ); const TCHAR c_szErrCreatePath[] = _T( "Æú´õ : \n" "%s\n\n" "¸¦ ¸¸µé ¼ö ¾ø½À´Ï´Ù. Æú´õÀ̸§À» È®ÀÎÇϽʽÿÀ." ); //return -1: user break; //return 0: no error //return 1: lpPath is invalid //return 2: can not create lpPath int CPathDialog::MakeSurePathExists(LPCTSTR pszPath) { int nRet; CString sMessage; try { //validate path nRet = Touch(pszPath, TRUE); if (nRet != 0) throw nRet; if (_access(pszPath, 06) == 0) { if (pszPath[0] == '\\' && pszPath[1] == '\\') { char szFile[MAX_PATH]; if (GetTempFileName(pszPath, "she", 0, szFile) == 0) { sMessage.Format(c_FolderDoesNotPermission, pszPath); AfxMessageBox(sMessage, MB_ICONWARNING); return -1; } DeleteFile(szFile); } return 0; } if (errno == ENOENT) { sMessage.Format(c_FolderDoesNotExist, pszPath); if (AfxMessageBox(sMessage, MB_YESNO | MB_ICONQUESTION) != IDYES) return -1; //create path nRet = Touch(pszPath, FALSE); if (nRet != 0) throw nRet; } else if (errno == EACCES) { char szFile[MAX_PATH]; if (!GetTempFileName(pszPath, "she", 0, szFile)) { sMessage.Format(c_FolderDoesNotPermission, pszPath); AfxMessageBox(sMessage, MB_ICONWARNING); return -1; } DeleteFile(szFile); } return 0; } catch (int nErrCode) { switch (nErrCode) { case 1: sMessage.Format(c_szErrInvalidPath, pszPath); break; case 2: default: sMessage.Format(c_szErrCreatePath, pszPath); break; } AfxMessageBox(sMessage, MB_OK | MB_ICONEXCLAMATION); } return nRet; } //return 0: no error //return 1: lpPath is invalid //return 2: lpPath can not be created(bValidate == FALSE) int CPathDialog::Touch(LPCTSTR pszPath, BOOL bValidate) { if (pszPath == NULL) return 1; TCHAR szPath[MAX_PATH]; _tcscpy(szPath, pszPath); int nLen = (int)_tcslen(szPath); //path must be "x:\..." /* if ((nLen < 3) || ((szPath[0] < _T('A') || _T('Z') < szPath[0]) && (szPath[0] < _T('a') || _T('z') < szPath[0]) || (szPath[1] != _T(':')) || (szPath[2] != _T('\\')))) */ if (nLen == 3) { if (!bValidate) { if (_access(szPath, 0)!=0) { return 2; } } return 0; } int 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( !IsValidFileName(lpCurrentName) ) { return 1; } 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; int nLen = (int)_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; }