426 lines
8.9 KiB
C++
426 lines
8.9 KiB
C++
#include "stdafx.h"
|
|
#include "PathDialog.h"
|
|
|
|
#include <io.h>
|
|
#include <errno.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
|
|
#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;
|
|
}
|