📄 fsfolder.cpp
字号:
}
STDMETHODIMP CFSFolder::BindToFolder(UInt32 index, IFolderFolder **resultFolder)
{
*resultFolder = 0;
const CDirItem &fileInfo = *_refs[index];
if (!fileInfo.IsDir())
return E_INVALIDARG;
return BindToFolderSpec(GetRelPath(fileInfo), resultFolder);
}
STDMETHODIMP CFSFolder::BindToFolder(const wchar_t *name, IFolderFolder **resultFolder)
{
return BindToFolderSpec(name, resultFolder);
}
STDMETHODIMP CFSFolder::BindToParentFolder(IFolderFolder **resultFolder)
{
*resultFolder = 0;
if (_parentFolder)
{
CMyComPtr<IFolderFolder> parentFolder = _parentFolder;
*resultFolder = parentFolder.Detach();
return S_OK;
}
if (_path.IsEmpty())
return E_INVALIDARG;
int pos = _path.ReverseFind(WCHAR_PATH_SEPARATOR);
if (pos < 0 || pos != _path.Length() - 1)
return E_FAIL;
UString parentPath = _path.Left(pos);
pos = parentPath.ReverseFind(WCHAR_PATH_SEPARATOR);
if (pos < 0)
{
parentPath.Empty();
CFSDrives *drivesFolderSpec = new CFSDrives;
CMyComPtr<IFolderFolder> drivesFolder = drivesFolderSpec;
drivesFolderSpec->Init();
*resultFolder = drivesFolder.Detach();
return S_OK;
}
UString parentPathReduced = parentPath.Left(pos);
parentPath = parentPath.Left(pos + 1);
pos = parentPathReduced.ReverseFind(WCHAR_PATH_SEPARATOR);
if (pos == 1)
{
if (parentPath[0] != WCHAR_PATH_SEPARATOR)
return E_FAIL;
CNetFolder *netFolderSpec = new CNetFolder;
CMyComPtr<IFolderFolder> netFolder = netFolderSpec;
netFolderSpec->Init(parentPath);
*resultFolder = netFolder.Detach();
return S_OK;
}
CFSFolder *parentFolderSpec = new CFSFolder;
CMyComPtr<IFolderFolder> parentFolder = parentFolderSpec;
RINOK(parentFolderSpec->Init(parentPath, 0));
*resultFolder = parentFolder.Detach();
return S_OK;
}
STDMETHODIMP CFSFolder::GetNumberOfProperties(UInt32 *numProperties)
{
*numProperties = sizeof(kProperties) / sizeof(kProperties[0]);
if (!_flatMode)
(*numProperties)--;
return S_OK;
}
STDMETHODIMP CFSFolder::GetPropertyInfo(UInt32 index,
BSTR *name, PROPID *propID, VARTYPE *varType)
{
if (index >= sizeof(kProperties) / sizeof(kProperties[0]))
return E_INVALIDARG;
const STATPROPSTG &prop = kProperties[index];
*propID = prop.propid;
*varType = prop.vt;
*name = 0;
return S_OK;
}
STDMETHODIMP CFSFolder::GetFolderProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
switch(propID)
{
case kpidType: prop = L"FSFolder"; break;
case kpidPath: prop = _path; break;
}
prop.Detach(value);
return S_OK;
COM_TRY_END
}
STDMETHODIMP CFSFolder::WasChanged(INT32 *wasChanged)
{
bool wasChangedMain = false;
for (;;)
{
if (!_findChangeNotification.IsHandleAllocated())
{
*wasChanged = BoolToInt(false);
return S_OK;
}
DWORD waitResult = ::WaitForSingleObject(_findChangeNotification, 0);
bool wasChangedLoc = (waitResult == WAIT_OBJECT_0);
if (wasChangedLoc)
{
_findChangeNotification.FindNext();
wasChangedMain = true;
}
else
break;
}
*wasChanged = BoolToInt(wasChangedMain);
return S_OK;
}
STDMETHODIMP CFSFolder::Clone(IFolderFolder **resultFolder)
{
CFSFolder *fsFolderSpec = new CFSFolder;
CMyComPtr<IFolderFolder> folderNew = fsFolderSpec;
fsFolderSpec->Init(_path, 0);
*resultFolder = folderNew.Detach();
return S_OK;
}
HRESULT CFSFolder::GetItemsFullSize(const UInt32 *indices, UInt32 numItems,
UInt64 &numFolders, UInt64 &numFiles, UInt64 &size, IProgress *progress)
{
numFiles = numFolders = size = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
int index = indices[i];
if (index >= _refs.Size())
return E_INVALIDARG;
const CDirItem &fileInfo = *_refs[index];
if (fileInfo.IsDir())
{
UInt64 subFolders, subFiles, subSize;
RINOK(GetFolderSize(_path + GetRelPath(fileInfo), subFolders, subFiles, subSize, progress));
numFolders += subFolders;
numFolders++;
numFiles += subFiles;
size += subSize;
}
else
{
numFiles++;
size += fileInfo.Size;
}
}
return S_OK;
}
HRESULT CFSFolder::GetItemFullSize(int index, UInt64 &size, IProgress *progress)
{
const CDirItem &fileInfo = *_refs[index];
if (fileInfo.IsDir())
{
/*
CMyComPtr<IFolderFolder> subFolder;
RINOK(BindToFolder(index, &subFolder));
CMyComPtr<IFolderReload> aFolderReload;
subFolder.QueryInterface(&aFolderReload);
aFolderReload->Reload();
UInt32 numItems;
RINOK(subFolder->GetNumberOfItems(&numItems));
CMyComPtr<IFolderGetItemFullSize> aGetItemFullSize;
subFolder.QueryInterface(&aGetItemFullSize);
for (UInt32 i = 0; i < numItems; i++)
{
UInt64 size;
RINOK(aGetItemFullSize->GetItemFullSize(i, &size));
*totalSize += size;
}
*/
UInt64 numFolders, numFiles;
return GetFolderSize(_path + GetRelPath(fileInfo), numFolders, numFiles, size, progress);
}
size = fileInfo.Size;
return S_OK;
}
STDMETHODIMP CFSFolder::GetItemFullSize(UInt32 index, PROPVARIANT *value, IProgress *progress)
{
NCOM::CPropVariant prop;
if (index >= (UInt32)_refs.Size())
return E_INVALIDARG;
UInt64 size = 0;
HRESULT result = GetItemFullSize(index, size, progress);
prop = size;
prop.Detach(value);
return result;
}
HRESULT CFSFolder::GetComplexName(const wchar_t *name, UString &resultPath)
{
UString newName = name;
resultPath = _path + newName;
if (newName.Length() < 1)
return S_OK;
if (newName[0] == WCHAR_PATH_SEPARATOR)
{
resultPath = newName;
return S_OK;
}
if (newName.Length() < 2)
return S_OK;
if (newName[1] == L':')
resultPath = newName;
return S_OK;
}
STDMETHODIMP CFSFolder::CreateFolder(const wchar_t *name, IProgress * /* progress */)
{
UString processedName;
RINOK(GetComplexName(name, processedName));
if(NDirectory::MyCreateDirectory(processedName))
return S_OK;
if(::GetLastError() == ERROR_ALREADY_EXISTS)
return ::GetLastError();
if (!NDirectory::CreateComplexDirectory(processedName))
return ::GetLastError();
return S_OK;
}
STDMETHODIMP CFSFolder::CreateFile(const wchar_t *name, IProgress * /* progress */)
{
UString processedName;
RINOK(GetComplexName(name, processedName));
NIO::COutFile outFile;
if (!outFile.Create(processedName, false))
return ::GetLastError();
return S_OK;
}
STDMETHODIMP CFSFolder::Rename(UInt32 index, const wchar_t *newName, IProgress * /* progress */)
{
const CDirItem &fileInfo = *_refs[index];
const UString fullPrefix = _path + GetPrefix(fileInfo);
if (!NDirectory::MyMoveFile(fullPrefix + fileInfo.Name, fullPrefix + newName))
return GetLastError();
return S_OK;
}
STDMETHODIMP CFSFolder::Delete(const UInt32 *indices, UInt32 numItems,IProgress *progress)
{
RINOK(progress->SetTotal(numItems));
for (UInt32 i = 0; i < numItems; i++)
{
const CDirItem &fileInfo = *_refs[indices[i]];
const UString fullPath = _path + GetRelPath(fileInfo);
bool result;
if (fileInfo.IsDir())
result = NDirectory::RemoveDirectoryWithSubItems(fullPath);
else
result = NDirectory::DeleteFileAlways(fullPath);
if (!result)
return GetLastError();
UInt64 completed = i;
RINOK(progress->SetCompleted(&completed));
}
return S_OK;
}
STDMETHODIMP CFSFolder::SetProperty(UInt32 index, PROPID propID,
const PROPVARIANT *value, IProgress * /* progress */)
{
if (index >= (UInt32)_refs.Size())
return E_INVALIDARG;
CDirItem &fileInfo = *_refs[index];
if (fileInfo.Parent->Parent != 0)
return E_NOTIMPL;
switch(propID)
{
case kpidComment:
{
UString filename = fileInfo.Name;
filename.Trim();
if (value->vt == VT_EMPTY)
_comments.DeletePair(filename);
else if (value->vt == VT_BSTR)
{
CTextPair pair;
pair.ID = filename;
pair.ID.Trim();
pair.Value = value->bstrVal;
pair.Value.Trim();
if (pair.Value.IsEmpty())
_comments.DeletePair(filename);
else
_comments.AddPair(pair);
}
else
return E_INVALIDARG;
SaveComments();
break;
}
default:
return E_NOTIMPL;
}
return S_OK;
}
STDMETHODIMP CFSFolder::GetSystemIconIndex(UInt32 index, INT32 *iconIndex)
{
if (index >= (UInt32)_refs.Size())
return E_INVALIDARG;
const CDirItem &fileInfo = *_refs[index];
*iconIndex = 0;
int iconIndexTemp;
if (GetRealIconIndex(_path + GetRelPath(fileInfo), fileInfo.Attrib, iconIndexTemp) != 0)
{
*iconIndex = iconIndexTemp;
return S_OK;
}
return GetLastError();
}
STDMETHODIMP CFSFolder::SetFlatMode(Int32 flatMode)
{
_flatMode = IntToBool(flatMode);
return S_OK;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -