__int64 FreeSpace,TotalSpace;
if(Sysutils::GetDiskFreeSpaceEx(ExtractFileDrive(dir).c_str(),NULL,TotalSpace,&FreeSpace))
StatusBar1->SimpleText=AnsiString("Объектов: ")+ListView1->Items->Count+" (Свободнонадиске "+ AnsiString(((FreeSpace*10)/1024/1024/1024)/c)+" ГБ)";
}
void TForm1::ViewProperty() //Отображение свойств файла папки диска
{
if(CurrentDir=="") return;
if(ListView1->ItemFocused==NULL)
{
if(TreeView1->Selected!=NULL)
{
if(TreeView1->Selected->Level==1)
FPropertyDrive->Prepare(*((AnsiString *)(TreeView1->Selected->Data)));
else if(TreeView1->Selected->Level>1)
FPropertyFile->Prepare(*((AnsiString *)(TreeView1->Selected->Data)));
}
}
else
{
if(ListView1->Selected!=NULL)
FPropertyFile->Prepare(*((AnsiString *)(ListView1->Selected->Data)));
else
{
if(ExtractFileDrive(CurrentDir).AnsiCompareIC(CurrentDir.SubString(1,CurrentDir.Length()-1))==0)
FPropertyDrive->Prepare(CurrentDir);
else
FPropertyFile->Prepare(CurrentDir);
}
}
UpdateAll(true);
}
void TForm1::PrepareBufForOperationInListView(char * &frombuf) //Подготовкабуфераданных
{ //надкоторымипроизводитсяопер
frombuf=new char[ListView1->SelCount*MAX_PATH+1];
if(ListView1->SelCount==1) //Есливыделенодинэлементтовсепросто
{ //заполняем frombuf именем
AnsiString sourcestr=*((AnsiString *)(ListView1->Selected->Data));
if((FileGetAttr(sourcestr) & faDirectory)!=0)
sourcestr.SetLength(sourcestr.Length()-1);
strcpy(frombuf,sourcestr.c_str());
finstr(frombuf);
}
else
{
char *temp=frombuf;
bool flag=false; //Если несколько последовательно заполняем именами
for(int i=0;i<ListView1->Items->Count;i++)
if(ListView1->Items->Item[i]->Selected)
{
AnsiString sourcestr=*((AnsiString *)(ListView1->Items->Item[i]->Data));
if((FileGetAttr(sourcestr) & faDirectory)!=0)
sourcestr.SetLength(sourcestr.Length()-1);
if(flag)
strcat0(temp,sourcestr.c_str());
else
{
strcpy(temp,sourcestr.c_str());
flag=true;
}
}
finstr(temp);
}
}
AnsiString TForm1::RenameFileOrFolder(AnsiString NewName)
{
char frombuf[MAX_PATH+1]={'\0'},tobuf[MAX_PATH+1]={'\0'};
if(ListView1->ItemFocused==NULL)
{
if(TreeView1->Selected!=NULL)
if(TreeView1->Selected->Level>1)
{
AnsiString temp;
AnsiString *sourcestr=((AnsiString *)(TreeView1->Selected->Data));
temp=*sourcestr; //Сохранение в темповой переменной старого пути
sourcestr->SetLength(sourcestr->Length()-1);
strcpy(frombuf,sourcestr->c_str()); //Построениеновогопути
*sourcestr=ExtractFilePath(*sourcestr)+NewName;
strcpy(tobuf,sourcestr->c_str());
if(FileAndFolderOperation(frombuf,tobuf,FO_RENAME)!=0) //Еслиоперациянеудалась
{
*sourcestr=temp; //Возвращаемназад
NewName=ExtractFileName(temp.SubString(1,temp.Length()));
}
else
*sourcestr=*sourcestr+"\"; //Если нормально меняем путь
return NewName;
}
}
else
if((ListView1->Selected)!=NULL)
{
bool dir=false;
AnsiString *sourcestr=((AnsiString *)(ListView1->Selected->Data));
AnsiString temp=*sourcestr;
if((FileGetAttr(*sourcestr) & faDirectory)!=0)
{
sourcestr->SetLength(sourcestr->Length()-1);
dir=true;
}
strcpy(frombuf,sourcestr->c_str());
*sourcestr=ExtractFilePath(*sourcestr)+NewName;
strcpy(tobuf,sourcestr->c_str());
if(FileAndFolderOperation(frombuf,tobuf,FO_RENAME)!=0)
{
*sourcestr=temp;
if(dir)
temp.SetLength(temp.Length()-1);
NewName=ExtractFileName(temp);
}
else
if(dir)
*sourcestr=*sourcestr+"\";
return NewName;
}
}
void TForm1::DeleteFileOrFolder()
{
if(ListView1->ItemFocused==NULL)
{
if(TreeView1->Selected!=NULL)
if(TreeView1->Selected->Level>1)
{
char frombuf[MAX_PATH]={'\0'};
AnsiString sourcestr=*((AnsiString *)(TreeView1->Selected->Data));
sourcestr.SetLength(sourcestr.Length()-1);
strcpy(frombuf,sourcestr.c_str());
FileAndFolderOperation(frombuf,NULL,FO_DELETE);
}
}
else
if((ListView1->Selected)!=NULL)
{
char *frombuf;
PrepareBufForOperationInListView(frombuf);
FileAndFolderOperation(frombuf,NULL,FO_DELETE);
}
UpdateAll(false);
}
void TForm1::ExpandTreeForFile(AnsiString FileName)
{ //Расширениеветвей tree дофайла
AnsiString Find="";
TTreeNode *p=TreeView1->Items->Item[0], *child;
child=p->getFirstChild();
bool flag=false;
do
{
flag=false;
int pos=FileName.Pos("\"); //Вычленениеизименифайлапапки
Find=Find+FileName.SubString(1,pos); //прибавлениек find
FileName.Delete(1,pos);
if(FileName.Pos("\")==0)
flag=true; //Критерийокончания
child=p->getFirstChild();
while(1)
{
if(child==NULL)
{
child=AddChildInNodeTree(p,Find); //Еслиузлавообщенеттосоздаемего
if(!p->Expanded) //и расширяем его отца
p->Expand(false);
}
if((*(AnsiString *)(child->Data)).AnsiCompareIC(Find)==0)
{
if (flag) //По окончании передаем выделение на этот узел
TreeView1->Selected=child;
else if(!child->Expanded) //еслиэтотоллькопромежуточнаяпапка
child->Expand(false); //расширяемветвь
p=child;
break;
}
child=p->GetNextChild(child);
}
}
while(!flag);
}
void TForm1::OpenFileOrFolder()
{ //Происходит открытие файла или папки выделенных в listview
if(ListView1->Selected==NULL) return; //проверканаличиявыделенного
AnsiString ww=*((AnsiString *)(ListView1->Selected->Data));
if((FileGetAttr(ww) & faDirectory)!=0) //Вслучаепапки
{
ViewFailAndFolderInListView(ww); //Вызываемотображениепапокифайлов
ExpandTreeForFile(ww); //Расширяем treeview доэтогофайла
}
else
{
ShellExecute(NULL,"open",ww.c_str(),NULL,NULL,SW_RESTORE); //Вслучаефайла
if(GetLastError()) //Выполняем его и проверяем ошибки
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf, 0, NULL);
// Display the string.
MessageBox( NULL, (char*)lpMsgBuf, "Ошибка", MB_OK|MB_ICONINFORMATION );
// Free the buffer.
LocalFree( lpMsgBuf );
}
}
}
void RecursDelData(TTreeNode *node) //Рекурсивнаяфункцияобходит
{ // дочерние узлы и удаляет данные по указателю data
delete node->Data;
TTreeNode *child;
for(child=node->getFirstChild();child!=NULL;child=node->GetNextChild(child))
RecursDelData(child);
}
void TForm1::RecursTree(TTreeNode *node,bool UpdateAllways)
{
AnsiString dir=*((AnsiString *)(node->Data));
TSearchRec sr;
TTreeNode *child;
int num=0;
if(((GetDriveType(dir.c_str())==DRIVE_REMOVABLE) || (GetDriveType(dir.c_str())==DRIVE_CDROM)) && !DiskIn.Contains(ExtractFileDrive(dir)[1]))
return; //Условие: просматривать дискету и диск если отмечено что они есть
if(!UpdateAllways)
{
if(FindFirst(dir+"*",faAnyFile,sr)==0)
do //и продолжить если найден файл
if((sr.Attr & faDirectory) && sr.Name!="." && sr.Name!="..")
num++; //Пересчитываем все папки в данной
while(FindNext(sr)==0);
FindClose(sr);
}
int count=node->Count;
if(UpdateAllways || num!=count) //Сравниваемсколичествомузловпотомков
{
if(UpdateAllways || num<count) //Если узлов потомков больше ищем отсутствующую папку
for(child=node->getFirstChild();child!=NULL;)
{
AnsiString t=*(AnsiString *)(child->Data);
if(GetFileAttributes(t.c_str())==-1)
{
TTreeNode *temp=node->GetNextChild(child);
if(child->Selected) node->Selected=true;
RecursDelData(child); //Удаляем данные несуществующей папки и ее потомков
TreeView1->Items->Delete(child); //удаляемузел
child=temp;
}
else
child=node->GetNextChild(child);
}
if(UpdateAllways || num>count) //Если какой-то папки не хватает
{
if(FindFirst(dir+"*",faAnyFile,sr)==0) //Перебираемпапки
do
if((sr.Attr & faDirectory) && sr.Name!="." && sr.Name!="..")
{ //Ищем для них узлы
for(child=node->getFirstChild();child!=NULL;child=node->GetNextChild(child))
if((*(AnsiString *)(child->Data)).AnsiCompareIC((dir+sr.Name+"\"))==0)
break;
if(child==NULL) //если соответствующего узла нет добавляем
AddChildInNodeTree(node,dir+sr.Name+"\");
}
while(FindNext(sr)==0);
FindClose(sr);
}
}
if(node->Expanded || CheckExpandedChild(node))
{
for(child=node->getFirstChild();child!=NULL;child=node->GetNextChild(child))
RecursTree(child,UpdateAllways);
}
}
void TForm1::UpdateTreeView(bool UpdateAllways) //Обновление treeview
{
TTreeNode *top=TreeView1->Items->Item[0];
TTreeNode *child;
if(top->Expanded)
for(child=top->getFirstChild();child!=NULL;child=top->GetNextChild(child))
RecursTree(child, UpdateAllways);
TreeView1->AlphaSort();
}
void TForm1::UpdateListView(bool UpdateAllways) //Обновлениесписка listview
{
if(CurrentDir=="") return; //Если ни один каталог не отображается
if(GetFileAttributes(CurrentDir.c_str())==-1)
{ //Если текущего каталога уже не существует
ViewFailAndFolderInListView(CurrentDir); //отображаем его ридительский каталог
return;
}
TSearchRec sr;
TListItem *item;
int num=0; //подсчет количества файлов в папке
if(!UpdateAllways)
{
if(FindFirst(CurrentDir+"*",faAnyFile,sr)==0)
do //и продолжить если найден файл
if(sr.Name!="." && sr.Name!="..")
num++; //Пересчитываем все папки в данной
while(FindNext(sr)==0);
FindClose(sr);
}
int count=ListView1->Items->Count;
if(UpdateAllways || num!=count) //Сравниваем с количеством узлов потомков
{
if(UpdateAllways || num<count) //Если записей больше чем файлов
for(int i=0;i<ListView1->Items->Count;i++) //ищем уже отсутствующие в действительности
{
AnsiString t=*(AnsiString *)(ListView1->Items->Item[i]->Data);
if(GetFileAttributes(t.c_str())==-1)
{
delete ListView1->Items->Item[i]->Data; //Удаляем вспомогательные данные для него
ListView1->Items->Delete(i); //удаляемузел
i--;
}
}
if(UpdateAllways || num>count) //Еслифайловнехватает
{
if(FindFirst(CurrentDir+"*",faAnyFile,sr)==0) //Перебираемфайлы
do
if(sr.Name!="." && sr.Name!="..")
{ //Ищем для них записи
inti;
for(i=0;i<ListView1->Items->Count;i++)
if((*(AnsiString *)(ListView1->Items->Item[i]->Data)).AnsiCompareIC(CurrentDir+sr.Name+((sr.Attr & faDirectory)?"\":""))==0)
break;
if(i==ListView1->Items->Count) //если соответствующего узла нет добавляем
AddItemInListView(sr,CurrentDir);
}
while(FindNext(sr)==0);
FindClose(sr);
}
}
}
voidTForm1::UpdateLabel() //Обновление меток диска
{
TTreeNode *child, *node=TreeView1->Items->Item[0];
for(child=node->getFirstChild();child!=NULL;child=node->GetNextChild(child))
{
AnsiString path=*((AnsiString *)child->Data);
AnsiString text=child->Text;
char inf[20];
unsigned int p=GetDriveType(path.c_str());
if(((p==DRIVE_REMOVABLE || p==DRIVE_CDROM) && (DiskIn.Contains(path[1]))) ||
(p!=DRIVE_REMOVABLE && p!=DRIVE_CDROM))
{
if(GetVolumeInformation(path.c_str(),inf,20,NULL,NULL,NULL,NULL,NULL))
{
text.Delete(1,text.Pos("(")-1);
FirstUpOtherDown(inf);
child->Text=AnsiString(inf)+" "+text;
}
else
{
text.Delete(1,text.Pos("(")-1);
child->Text=" "+text;
ViewFailAndFolderInListView(path);
}
}
else
{
text.Delete(1,text.Pos("(")-1);
child->Text=" "+text;
}
}
}
void TForm1::UpdateAll(bool UpdateAllways) //Обновлениевсего
{
UpdateTreeView(UpdateAllways); //Обновлениедеревапапок
UpdateListView(UpdateAllways); //Обновлениеспискафайлов
UpdateLabel();
double c=10.0;
if(CurrentDir!="")
{
__int64 FreeSpace,TotalSpace;
if(Sysutils::GetDiskFreeSpaceEx(ExtractFileDrive(CurrentDir).c_str(),NULL,TotalSpace,&FreeSpace))
StatusBar1->SimpleText=AnsiString("Объектов: ")+ListView1->Items->Count+" (Свободнонадиске "+ AnsiString(((FreeSpace*10)/1024/1024/1024)/c)+" ГБ)";
}
}
void TForm1::PasteFileFromClipboard() //Вставитьизбуфера
{
if(CurrentDir=="") return;
char *frombuf, *temp;
char tobuf[MAX_PATH+1]={'\0'};
int nCount,i; //Число копируемых объектов
PointerData;
char * lpDroppedFile;
OpenClipboard(NULL); //Открывает clipboard для текущего процесса
if (IsClipboardFormatAvailable(CF_HDROP))
{
Data=GetClipboardData(CF_HDROP); //Получение указателя на данные
if(Data==0) { CloseClipboard(); return; } //Нечегозабирать
nCount= DragQueryFile(Data, 0xFFFFFFFF, NULL, 0); //Получениеколичества
temp=frombuf=new char[MAX_PATH*nCount];
if (nCount > 0)
{
lpDroppedFile=(char *)AllocMem(MAX_PATH + 1); //Выделениепамятиподмассив
for (i= 0;i<nCount;i++) //с названиями копирумых объектов
{
DragQueryFile(Data, i, lpDroppedFile, MAX_PATH); //Собственно получение имен этих объектов
if(i!=0)
strcat0(temp,lpDroppedFile); //Добавлениек frombuf
else
strcpy(temp,lpDroppedFile);
}
finstr(temp);
free(lpDroppedFile); //Освобождение
strcpy(tobuf,CurrentDir.c_str());
}
long lngEffect;
long lngFormat = RegisterClipboardFormat(CFSTR_PREFERREDDROPEFFECT);
HANDLE hGlobal = GetClipboardData(lngFormat);