Урок 47 Несколько полезных кусков кода(продолжение) No title

July 20, 2007
в колонках играет Shakira - Ready for the good times



Если в предыдущем уроке я собрал наиболее интересные куски кода, то этот направлен исключительно на работу с дисками, директориями и файлами. Для работы подготовьте новый проект и киньте на форму TButton, OpenDialog. Ну и Label для отображения инфы о дисках.

Начнем с простого, и узнаем какой обьем у наших разделов и сколько осталось(и осталось ли вообще) мегабайт на них:

__int64 Size = DiskSize(3);// диску А соответствует 1, диску В - 2, и т. д., 0 - текущий диск. Код определит размер диска С в байтах.

А вот сколько пространства осталось:

__int64 FreeSpace = DiskFree(3);

Не правда ли просто?

Теперь самая информативная часть урока. Она посвящена работе с директориями и файлами. Т.е. копирование и удаление. Как известно можно удалить в корзину, а можно и в никуда. И тогда хер восстановишь.

Чтобы удалить в корзину нам понадобится OpenDialog(давно мы его не юзали, а сегодня научимся модифицировать) и Button. В OnClick пишем:

if(OpenDialog1->Execute())
{
AnsiString DialogTitle = "Удаление в корзину";
SHFILEOPSTRUCT FileOpStruct;
ZeroMemory(&FileOpStruct, sizeof(SHFILEOPSTRUCT));
FileOpStruct.pFrom = (OpenDialog1->FileName + '').c_str();
FileOpStruct.wFunc = FO_DELETE;
FileOpStruct.fFlags = FOF_ALLOWUNDO;
FileOpStruct.lpszProgressTitle = DialogTitle.c_str();
SHFileOperation(&FileOpStruct);
}

Ну и удаление файла насовсем:

#include <stdio.h>//подключаем библиотеку
String FileName="c:\1.txt";
remove(FileName.c_str());

А если вам охота переместить весь Program Files прямиком в c:\temp, то пишем:

int MoveFiles( AnsiString slSourceDir, AnsiString slTargetDir, bool toCopy = true )
{
SHFILEOPSTRUCT sh;
sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_FILESONLY;
sh.wFunc = toCopy ? FO_COPY : FO_MOVE;
sh.pFrom = slSourceDir.c_str();
sh.pTo = slTargetDir.c_str();
sh.hNameMappings = NULL;
sh.lpszProgressTitle = NULL;
return SHFileOperation ( &sh );
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
if(!MoveFiles("c:\program files\*.*", "c:\temp"))//Первая директория - откуда, вторая - куда копировать.
ShowMessage("Ok");
else ShowMessage("No");
}


Вобщем лучше поэкспериментировать на чем-нить безобидном=).

Сначала найдем винду:

char WindowsDirectory[MAX_PATH];
GetWindowsDirectory(WindowsDirectory, MAX_PATH);

А теперь удаляем папку (Если Windows пуста=):

SHFILEOPSTRUCT sh;
sh.hwnd=Form1->Handle;
sh.wFunc = FO_DELETE;
sh.pFrom = "c:\windows"; //удаляемая директория
sh.pTo = NULL;
sh.fFlags = FOF_NOCONFIRMATION | FOF_SILENT;
sh.hNameMappings = 0;
sh.lpszProgressTitle = NULL;
SHFileOperation(&sh);

Естественно, она вряд ли удалится. А вот следущий код нах*й снесет всё что угодно(я им висту удалял с жесткого диска):

bool DeleteDir(AnsiString DirName)
{
TSearchRec sr;
if (DirName.Length())
{
if (!FindFirst(DirName+"\*.*",faAnyFile,sr))
do
{
if (!(sr.Name=="." || sr.Name==".."))// это удалять не надо
if (((sr.Attr & faDirectory) == faDirectory ) ||
(sr.Attr == faDirectory))// найдена папка
{
FileSetAttr(DirName+"\"+sr.Name, faDirectory );// сброс read-only
DeleteDir(DirName+"\"+sr.Name);//рекурсивно удаляем содержимое
RemoveDir(DirName + "\"+sr.Name);// удаляем теперь уже пустую папку
}
else// иначе найден файл
{
FileSetAttr(DirName+"\"+sr.Name, 0);// сброс read-only
DeleteFile(DirName+"\"+sr.Name);// удаляем файл
}
}
while (!FindNext(sr));// ищем опять, пока не найдем все
FindClose(sr);
}
RemoveDir(DirName);
return true;
}


Как этот код использовать решать вам. DirName меняем на Windows и вперед!(Большего обьяснять не буду, интуиция подскажет=)).

А теперь найдем что-нибудь хорошее. С помощью следущего кода(А что для этого понадобится надеюсь сами догадаетесь):

void ListFiles(AnsiString path, TStrings* List)
{
// Эта процедура выводит список файлов и вызывает
// саму себя для всех каталогов
TSearchRec sr;
if (FindFirst(path+"*.*", faAnyFile, sr) == 0)
{
do
{
if (sr.Attr & faDirectory)
{
if (sr.Name!=".")
if (sr.Name!="..")
{
ListFiles(path+sr.Name+"\",List);// Рекурсивный вызов
}
}
else
{
AnsiString Ext=ExtractFileExt(sr.Name).UpperCase();
if (Ext==".CPP")
List->Add(path+sr.Name);
}
}
while (FindNext(sr) == 0);
FindClose(sr);
}
Application->ProcessMessages();
}

void __fastcall TForm1::Button1Click(TObject *Sender)
{
ListFiles("c:\",Memo1->Lines);
}

 


Материал подготовил - [ArtuR]  2007
www.builderhelper.org
builder.helper@rambler.ru