📄 path.cpp
字号:
//////////////////////////////////////////////////////////////////////
// Implemented by Samuel Gonzalo
//
// You may freely use or modify this code
//////////////////////////////////////////////////////////////////////
//
// Path.cpp: implementation of the CJohnSplitPath class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Path.h"
#include "Shlwapi.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CJohnSplitPath::CJohnSplitPath()
{
_bIsRelative = FALSE;
}
CJohnSplitPath::CJohnSplitPath(LPCTSTR szPath, BOOL bIsFolderPath, BOOL bHasArguments)
{
SetPath(szPath, bIsFolderPath, bHasArguments);
}
CJohnSplitPath::CJohnSplitPath(DWORD dwSpecial)
{
SetPath(dwSpecial);
}
CJohnSplitPath::~CJohnSplitPath()
{
}
void CJohnSplitPath::SetPath(DWORD dwSpecial)
{
switch (dwSpecial)
{
case PATH_CMDLINE:
SetPath(GetCommandLine(), FALSE, TRUE);
break;
case PATH_MODULE:
{
char szPath[_MAX_PATH];
GetModuleFileName(0, szPath, _MAX_PATH);
SetPath(szPath);
}
break;
}
}
void CJohnSplitPath::SetPath(LPCTSTR szPath, BOOL bIsFolderPath, BOOL bHasArguments)
{
char szParamPath[_MAX_PATH];
char szDrive[_MAX_DRIVE], szDir[_MAX_DIR];
char szName[_MAX_FNAME], szExt[_MAX_EXT];
// Reset
_sOriginalPath.Empty();
_sDriveLabel.Empty();
_bIsRelative = FALSE;
_aDir.RemoveAll();
_sExtName.Empty();
_aArgs.RemoveAll();
// Original path
_sOriginalPath = szPath;
// Get args and remove them from path
szParamPath[0] = 0x0;
strcpy(szParamPath, szPath);
if (bHasArguments)
{
_sArgs = PathGetArgs(szParamPath);
PathRemoveArgs(szParamPath);
}
PathUnquoteSpaces(szParamPath);
if (szParamPath[0] == 0x0) return;
_splitpath(szParamPath, szDrive, szDir, szName, szExt);
// Drive
_sDrive = szDrive;
// Directory
_sDir = szDir;
_sDir.Replace('/', '\\');
if (!_sDir.IsEmpty()) _bIsRelative = (_sDir[0] != '\\');
// FileTitle
if (bIsFolderPath)
{
_sDir = CJohnSplitPath::AddBackSlash(_sDir);
_sDir += szName;
_sDir = CJohnSplitPath::AddBackSlash(_sDir);
}
else
{
_sFileTitle = szName;
}
// Get extension name (e.g.: "txt")
if (IsFilePath())
{
_sExtName = szExt;
_sExtName.Remove('.');
}
}
BOOL CJohnSplitPath::IsLocalPath()
{
return !_sDrive.IsEmpty() && !_bIsRelative;
}
BOOL CJohnSplitPath::IsRelativePath()
{
return _bIsRelative;
}
BOOL CJohnSplitPath::IsFilePath()
{
return !_sFileTitle.IsEmpty();
}
BOOL CJohnSplitPath::ExistFile()
{
if (!IsFilePath()) return FALSE;
return PathFileExists(GetPath());
}
BOOL CJohnSplitPath::ExistLocation()
{
return PathFileExists(GetLocation());
}
CString CJohnSplitPath::GetAbsolutePath(LPCTSTR szBaseFolder)
{
if (!IsRelativePath()) return sCEmptyString;
char szAbsolutePath[_MAX_PATH];
CString sFullPath(szBaseFolder);
if (sFullPath.IsEmpty()) return sCEmptyString;
sFullPath = CJohnSplitPath::AddBackSlash(sFullPath);
sFullPath += GetPath();
if (!PathCanonicalize(szAbsolutePath, sFullPath)) return sCEmptyString;
return szAbsolutePath;
}
CString CJohnSplitPath::GetRelativePath(LPCTSTR szBaseFolder)
{
if (IsRelativePath()) return sCEmptyString;
char szRelativePath[_MAX_PATH];
CString sRelPath;
PathRelativePathTo(szRelativePath, szBaseFolder, FILE_ATTRIBUTE_DIRECTORY,
GetPath(), IsFilePath() ? 0 : FILE_ATTRIBUTE_DIRECTORY);
sRelPath = szRelativePath;
if (sRelPath.GetLength() > 1)
{
// Remove ".\" from the beginning
if ((sRelPath[0] == '.') && (sRelPath[1] == '\\'))
sRelPath.Right(sRelPath.GetLength() - 2);
}
return sRelPath;
}
CString CJohnSplitPath::GetPath(BOOL bAppendArgs, BOOL bOriginal)
{
CString sPath;
if (bOriginal)
sPath = _sOriginalPath;
else
sPath = GetLocation() + GetFileName();
if (bAppendArgs) sPath += GetArgument();
return sPath;
}
CString CJohnSplitPath::GetShortPath()
{
char szShortPath[_MAX_PATH];
szShortPath[0] = 0x0;
GetShortPathName(GetPath(), szShortPath, _MAX_PATH);
return szShortPath;
}
CString CJohnSplitPath::GetLongPath()
{
char szLongPath[_MAX_PATH];
szLongPath[0] = 0x0;
GetLongPathName(GetPath(), szLongPath, _MAX_PATH);
return szLongPath;
}
CString CJohnSplitPath::GetDrive()
{
return _sDrive;
}
CString CJohnSplitPath::GetDriveLabel(BOOL bPCNameIfNetwork)
{
if (_sDriveLabel.IsEmpty() && !IsRelativePath())
{
if ((bPCNameIfNetwork) && (!IsLocalPath()))
_sDriveLabel = GetDir(0);
else
{
CString sRoot;
char szVolumeName[256];
szVolumeName[0] = '\0';
if (IsLocalPath())
{
sRoot = _sDrive + CString("\\");
}
else if (GetDirCount() > 1)
{
sRoot.Format("\\\\%s\\%s\\", GetDir(0), GetDir(1));
}
GetVolumeInformation(sRoot, szVolumeName, 255, NULL, NULL, NULL, NULL, 0);
_sDriveLabel = szVolumeName;
}
}
return _sDriveLabel;
}
int CJohnSplitPath::GetDirCount()
{
FillDirArray();
return _aDir.GetSize();
}
CString CJohnSplitPath::GetDir(int nIndex)
{
if (nIndex < 0)
return _sDir;
else if (nIndex < GetDirCount())
{
FillDirArray();
return _aDir[nIndex];
}
return sCEmptyString;
}
CString CJohnSplitPath::GetLocation()
{
return _sDrive + GetDir();
}
CString CJohnSplitPath::GetFileTitle()
{
return _sFileTitle;
}
CString CJohnSplitPath::GetFileName()
{
return _sFileTitle + GetExtension();
}
CString CJohnSplitPath::GetExtension()
{
if (_sExtName.IsEmpty()) return sCEmptyString;
return CString(".") + _sExtName;
}
CString CJohnSplitPath::GetExtName()
{
return _sExtName;
}
int CJohnSplitPath::GetArgCount()
{
FillArgArray();
return _aArgs.GetSize();
}
CString CJohnSplitPath::GetArgument(int nIndex, BOOL bGetFlag)
{
if (nIndex < 0)
{
if (_sArgs.IsEmpty())
{
for (int nItem = 0; nItem < _aArgs.GetSize(); nItem++)
_sArgs += _aArgs[nItem].GetString();
_sArgs.TrimLeft();
}
return _sArgs;
}
else if (nIndex < GetArgCount())
{
FillArgArray();
if (bGetFlag)
return _aArgs[nIndex].sFlag;
else
return _aArgs[nIndex].sValue;
}
return sCEmptyString;
}
void CJohnSplitPath::SetArguments(LPCTSTR szArgs)
{
_aArgs.RemoveAll();
_sArgs = szArgs;
}
void CJohnSplitPath::AddSetArgument(LPCTSTR szFlag, LPCTSTR szArgument)
{
int nIndex;
nIndex = FindArgument(szFlag);
if (nIndex != -1)
{
// An argument with the same flag already exists. Update it!
_aArgs[nIndex].sValue = szArgument;
}
else
{
CArgument arg;
arg.sValue = szArgument;
arg.SetFlag(szFlag);
_aArgs.Add(arg);
_sArgs.Empty();
}
}
void CJohnSplitPath::RemoveArgument(int nIndex)
{
if ((nIndex >= 0) && (nIndex < _aArgs.GetSize()))
{
_aArgs.RemoveAt(nIndex);
_sArgs.Empty();
}
}
int CJohnSplitPath::FindArgument(LPCTSTR szFlag)
{
bool bFound = false;
int nIndex;
CArgument arg;
FillArgArray();
arg.SetFlag(szFlag);
if (!arg.sFlag.IsEmpty())
{
for (nIndex = 0; nIndex < _aArgs.GetSize(); nIndex++)
{
bFound = (_aArgs[nIndex].sFlag.CompareNoCase(arg.sFlag) == 0);
if (bFound) break;
}
}
return (bFound ? nIndex : -1);
}
BOOL CJohnSplitPath::GetFileSize(__int64 &nSize)
{
BOOL bResult;
bResult = FillFileInfoStruct();
nSize = ((__int64)_fis.nFileSizeHigh * (__int64)MAXDWORD) + (__int64)_fis.nFileSizeLow;
return bResult;
}
BOOL CJohnSplitPath::GetFileTime(CTime &time, DWORD dwType)
{
BOOL bResult;
FILETIME *pTime = NULL;
bResult = FillFileInfoStruct();
switch (dwType)
{
case FILE_CREATION: pTime = &_fis.ftCreationTime; break;
case FILE_WRITE: pTime = &_fis.ftLastWriteTime; break;
case FILE_ACCESS:
default: pTime = &_fis.ftLastAccessTime; break;
}
if (pTime != NULL) time = CTime(*pTime);
return bResult;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Private methods
// This function must be called whenever _aDir array is needed, since this
// method is the one which parses _sDir and fill _aDir
void CJohnSplitPath::FillDirArray()
{
if (_sDir.IsEmpty() || (_aDir.GetSize() > 0)) return;
int nFrom, nTo;
// nFrom: 0 - relative / 1 - local / 2 - network
nFrom = IsLocalPath() ? 1 : (IsRelativePath() ? 0 : 2);
while ((nTo = _sDir.Find('\\', nFrom)) != -1)
{
_aDir.Add(_sDir.Mid(nFrom, nTo - nFrom));
nFrom = nTo + 1;
}
}
// This function must be called whenever _aArgs array is needed, since this
// method is the one which parses _sArgs and fill _aArgs
void CJohnSplitPath::FillArgArray()
{
if (_sArgs.IsEmpty() || (_aArgs.GetSize() > 0)) return;
CString sArgs(_sArgs);
int nFrom, nTo;
bool bQuotedArg = false;
CArgument arg;
sArgs.TrimLeft();
sArgs.TrimRight();
// add a blank space at the end of the string to include the last argument
sArgs += " ";
while ((nTo = sArgs.FindOneOf(" \"")) != -1)
{
bQuotedArg = (sArgs[nTo] == '\"');
if (bQuotedArg)
{
nFrom = nTo + 1;
if ((nTo = sArgs.Find('\"', nFrom)) == -1) break;
arg.sValue = sArgs.Mid(nFrom, nTo - nFrom);
}
else
{
CString *pStr;
if ((sArgs[0] == '/') || (sArgs[0] == '-'))
{
if (!arg.sFlag.IsEmpty())
{
arg.SetFlag(arg.sFlag);
_aArgs.Add(arg);
arg.sFlag.Empty();
arg.sValue.Empty();
}
pStr = &arg.sFlag;
}
else
pStr = &arg.sValue;
*pStr = sArgs.Left(nTo);
}
if (!arg.sValue.IsEmpty())
{
arg.SetFlag(arg.sFlag);
_aArgs.Add(arg);
arg.sFlag.Empty();
arg.sValue.Empty();
}
sArgs = sArgs.Right(sArgs.GetLength() - nTo - 1);
sArgs.TrimLeft();
}
// if the last argument is only a flag it hasn't been added yet
if (!arg.sFlag.IsEmpty())
{
arg.SetFlag(arg.sFlag);
_aArgs.Add(arg);
}
}
BOOL CJohnSplitPath::FillFileInfoStruct()
{
HANDLE hFile;
BOOL bResult;
::memset(&_fis, 0, sizeof(_fis));
hFile = CreateFile(GetPath(), GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM, NULL);
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
bResult = GetFileInformationByHandle(hFile, &_fis);
CloseHandle(hFile);
return bResult;
}
CString CJohnSplitPath::AddBackSlash(LPCTSTR szFolderPath, BOOL bInverted)
{
CString sResult(szFolderPath);
int nLastChar = sResult.GetLength() - 1;
if (nLastChar >= 0)
{
if ((sResult[nLastChar] != '\\') && (sResult[nLastChar] != '/'))
sResult += bInverted ? '/' : '\\';
}
return sResult;
}
CString CJohnSplitPath::RemoveBackSlash(LPCTSTR szFolderPath)
{
CString sResult(szFolderPath);
int nLastChar = sResult.GetLength() - 1;
if (nLastChar >= 0)
{
if ((sResult[nLastChar] == '\\') || (sResult[nLastChar] == '/'))
sResult = sResult.Left(nLastChar);
}
return sResult;
}
CJohnSplitPath::operator LPCTSTR ()
{
_sLPCTSTRPath = GetPath();
return _sLPCTSTRPath;
}
const CJohnSplitPath& CJohnSplitPath::operator = (LPCTSTR szPath)
{
SetPath(szPath);
return *this;
}
const CJohnSplitPath& CJohnSplitPath::operator = (CJohnSplitPath &ref)
{
_aArgs.RemoveAll();
_aArgs.Copy(ref._aArgs);
_aDir.RemoveAll();
_aDir.Copy(ref._aDir);
_bIsRelative = ref._bIsRelative;
_fis = ref._fis;
_sArgs = ref._sArgs;
_sDir = ref._sDir;
_sDrive = ref._sDrive;
_sDriveLabel = ref._sDriveLabel;
_sExtName = ref._sExtName;
_sFileTitle = ref._sFileTitle;
_sOriginalPath = ref._sOriginalPath;
return *this;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -