Пятница - 23.04.2021 - 08:45:19
2139
0

4. Индикатор удаления файлов (с помощью внешней программы)

   Сегодня будет показано как передать данные из одной программы в другую. Чтобы наш урок принес практическую пользу, мы напишем простой индикатор процесса удаления файлов. Мы будем передавать имена удаленных файлов из одной программы второй программе, которая будет их отображать. Среда программирования C++Builder 6.

Шаг 1


   Казалось бы, проще простого разрешить эту проблему. Создаешь в приложении еще одну форму, кидаешь на нее пару лабелов, прогрессбар, связываешь их с основной формой и готово. Вот тут то и кроется подвох. Сам процесс удаления заберет на себя все ресурсы программы, и ход отображения на экране вы не увидите. Необходимо, создавать новый процесс, т.е. новую программу и как-то связать ее с основной. Этим мы и займемся сегодня.

   Необходимо создать форму, которая показана на рисунке.    Все здесь, думаю, понятно, единственное кратко остановлюсь на на компоненте выбора папки. Своего родного подобного компонента в C++Buider 6, к сожалению, нет, поэтому пришлось поискать в интернете. Нашел хороший компонент PFolderDialog. Сайт автора компонента http://pelesh.in.ua/, если этот компонент не найдете, можно заменить любым другим или просто указать в коде путь к папке.
   Привожу код программы, в нем даны подробные комментарии. Программа удаляет файлы во временную папку, которую задаст пользователь. Меня этот прием выручал не один раз. Удалить безвозвратно - дело не хитрое, а если потом надо бы вернуться, как быть?
   Конечно, для профессианольного применения «Индикатора удаления файлов» необходимо доработать программу: использовать синхронизацию процессов, перед удалением сначала определить колличество и размер удаляемых файлов, чтобы в процессе удаления выводить эту информацию на экран, ввести отмену операции удаления файлов. В принципе это и все.

//---------------------------------------------------------------------------
#include 
#include "FileCtrl.hpp"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PFolderDialog"
#pragma resource "*.dfm"
TForm1 *Form1;
#define WM_MyPost WM_USER
String tempdir; //временная директория для храниения удаленн. файлов
String deldir;//папка, которую удалем
bool del; //флаг открытия и закрытия индикатора
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
 tempdir=Edit1->Text;
}
//---------------------------------------------------------------------------
bool __fastcall DeleteDir(AnsiString DirName,String DirDel)
{
 TSearchRec sr;
 String S,S2,S3;

if (DirName.Length())
 {
 if (!FindFirst(DirName+"\\*.*",faAnyFile,sr))
 do
 {
  if (!(sr.Name=="." || sr.Name==".."))// это удалять не надо
   if (((sr.Attr & faDirectory) == faDirectory )
   (sr.Attr == faDirectory))// найдена папка
   {S2=sr.Name+"
    FileSetAttr(DirName+"
    DeleteDir(DirName+"
    RemoveDir(DirName + "
   }
   else// иначе найден файл
   {FileSetAttr(DirName+"
    
    if(!DirectoryExists(DirDel))
    {ForceDirectories(DirDel);} //создать директорию, куда удаляем файл
    S=DirName+"
    S3=DirDel+S2+sr.Name;

   if(DirectoryExists(DirDel))
   {CopyFileA(S.c_str(),S3.c_str(),1);}

   //создаем глобальный атом и передаем в него имена удаленный файлов
   ATOM A1;
   A1=GlobalAddAtomA(ExtractFileName(S).c_str());
   //посылаем сообщение в наш индикатор процесса
   //"TFormHideCreatePross"-класс формы,"Indicator"-заголовок формы (Caption)
   SendMessageA(FindWindowA("TFormHideCreatePross","Indicator"),WM_MyPost,0,A1);
   //удаляем атом
   GlobalDeleteAtom(A1);
   DeleteFile(S);// удаляем файл
   S3="";
   }
 }
 while (!FindNext(sr));// ищем опять, пока не найдем все
 FindClose(sr);
 }
 RemoveDir(DirName);

 return true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 tempdir=Edit1->Text;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 if(PFolderDialog1->Execute(0))
 {deldir=PFolderDialog1->FolderName;
  Label4->Caption=PFolderDialog1->FolderName;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 //указывем путь и имя индикатора удаления файлов
 String sIP=ExtractFilePath(Application->ExeName)+"IndicatorProcess.exe";
 if(FileExists(sIP))
 {//запускаем наш индикатор удаления файлов
  ShellExecute(Handle,"open",sIP.c_str(),0,0,SW_RESTORE);}
  //удаляем папку
  DeleteDir(PFolderDialog1->FolderName ,tempdir);
  //определяем дескриптор индикатора удаления
  HWND H=FindWindowA("TFormHideCreatePross","Indicator");
  del=1;
  if(H)
  {//если индикатор запущен, закрываем, удаление папки завершено
   SendMessage(H,WM_CLOSE,0,0);
   del=0;
  }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
 if(del)
 {HWND H=FindWindowA("TFormHideCreatePross","Indicator");
  if(H)
  {SendMessage(H,WM_CLOSE,0,0);
   del=0;
 }
}
//---------------------------------------------------------------------------