Пятница - 23.04.2021 - 08:14:01
5692
0
   В уроке 4 был показан пример, как передать данные с одной программы в другую с помощью сообщений и атомов, и заодно был создан «Индикатор удаления файлов». Сегодня мы сделаем такой же индикатор, но уже с помощью потока и в одном приложении. Среда программирования C++Builder 6.
Код написал мой друг и помощник Литвин Владимир.

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

   Необходимо две формы, которые показаны на рисунках.

    

 

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

//****************************************************************************
//Шаг 1 - создать главную форму 
//-----файл .срр -------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
#include "UDelThread.h"
#include "UIndicatorProcess.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "PFolderDialog"
#pragma resource "*.dfm"
TForm1 *Form1;
String deldir;//папка, которую удалем
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
 //вызываем диалог выбора папки
 if(PFolderDialog1->Execute(0))
 {deldir=PFolderDialog1->FolderName;
  Label4->Caption=PFolderDialog1->FolderName;}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
 //нажимаем кнопку "Удалить" и открываем форму индикатора удаления файлов
 FormHideCreatePross=new TFormHideCreatePross(0);
 FormHideCreatePross->Show();
 FormHideCreatePross->deleteDir(deldir);
}
//---------------------------------------------------------------------------

//****************************************************************************
//Шаг 2 - форму индикатора удаления файлов 
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "UIndicatorProcess.h"
#include "UDelThread.h"
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TFormHideCreatePross *FormHideCreatePross;
TDelThread *tdh;  //объявляем класс потока
//---------------------------------------------------------------------------
__fastcall TFormHideCreatePross::TFormHideCreatePross(TComponent* Owner)
		: TForm(Owner)
{
  tdh=0;
}
//---------------------------------------------------------------------------
void __fastcall TFormHideCreatePross::FormClose(TObject *Sender,
	  TCloseAction &Action)
{
 //при закрытии формы индикатора удаления, уничтожаем в памяти форму 
 //и обнуляем форму - обнулить указатель очень важный момент, без которого 
 //у меня уходил не один час на отладку и поиск ошибки.
 //Вообще заведите себе за правило -
 // «после удаления указателя, его сразу же его и обнулять!»
  
 Action=caFree;
 FormHideCreatePross=NULL;
}
//---------------------------------------------------------------------------
void __fastcall TFormHideCreatePross::FormCreate(TObject *Sender)
{
 //помещаем форму поверх главной формы
 SetWindowPos(Handle,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
}
//---------------------------------------------------------------------------
void TFormHideCreatePross::deleteDir(String dir)
{
 //создаем класс потока
 if(tdh)return;
 tdh=new TDelThread(true);
 tdh->directory=dir;
 tdh->Resume();
}
//---------------------------------------------------------------------------
void __fastcall TFormHideCreatePross::Button1Click(TObject *Sender)
{
 //рекция программы на нажитие кнопки "Пауза"
 if(!tdh)return;
 if(tdh->Suspended)
 {
   Button1->Caption="Пауза";
   tdh->Resume();
 }
 else
 {
   Button1->Caption="Продолжить";
   tdh->Suspend();
 }
}
//---------------------------------------------------------------------------
void __fastcall TFormHideCreatePross::Button2Click(TObject *Sender)
{
 //рекция программы на нажитие кнопки "Стоп"
 if(!tdh)return;
 tdh->Terminate();
}
//---------------------------------------------------------------------------

//****************************************************************************
//Шаг 3 - создать файл потока 
//---------------- файл .h--------------------------------------------------
#ifndef UDelThreadH
#define UDelThreadH
//---------------------------------------------------------------------------
#include <Classes.hpp>
//---------------------------------------------------------------------------
class TDelThread :
{
private:
protected:
        String dfile; TStringList *lst;
        void __fastcall Execute();
        void viewDirs(String dir);
        void __fastcall refreshDel();
        bool __fastcall DeleteDir(String DirName);
        String delFileDir;
        void __fastcall LabMess1();
public:
        __fastcall TDelThread(bool CreateSuspended);
        String directory;
};
//---------------------------------------------------------------------------
#endif 
 
//--------------- файл .cpp -------------------------------------------------
#include <vcl.h>
#pragma hdrstop

#include "UDelThread.h"
#include "UIndicatorProcess.h"
#pragma package(smart_init)

//---------------------------------------------------------------------------
__fastcall TDelThread::TDelThread(bool CreateSuspended)
        : TThread(CreateSuspended)
{
 FreeOnTerminate=1;
 lst=new TStringList;
 delFileDir=ExtractFilePath(Application->ExeName)+"deleteFile\\";
}

//---------------------------------------------------------------------------
void __fastcall TDelThread::Execute()
{
 //передаем сообщение в главную форму "Поиск файлов" 
 Synchronize(LabMess1);
 //функция поиска файлов 
 viewDirs(directory);
 
 //задаем размер прогресс бара по колличеству файлов  
 FormHideCreatePross->ProgressBar1->Max=lst->Count-1;
 //в цикле перемещаем заданную папку 
 for(int i=0; i<lst->Count && !Terminated; i++)
 {
   dfile=lst->Strings[i];
   int fAttr=(int)lst->Objects[i];
   String sub=dfile,
          newfile=delFileDir+sub.Delete(1,ExtractFilePath(directory).Length());
   if(fAttr & faDirectory)
   {
     ForceDirectories(newfile);
     FileSetAttr(dfile,faDirectory);
     RemoveDir(dfile);
   }
   else
   {
     ForceDirectories(ExtractFileDir(newfile));
     if(FileExists(newfile))DeleteFile(newfile);
     MoveFile(dfile.c_str(),newfile.c_str());
   }
   
   //отображаем ход процесса удаления в главной форме 
   Synchronize(refreshDel);
 }
 delete lst;
 FormHideCreateProse();
 FMain->dee=1;
}
---------- Функция поиска файлов -----------------------------------
void TDelThread::viewDirs(String dir)
{
 TSearchRec sr;
 String path=IncludeTrailingPathDelimiter(dir),
        mask=path+"*.*";
 if(!FindFirst(mask,faAnyFile,sr))
   do
   {
     if(sr.Name=="." || sr.Name=="..")continue;
     dfile=path+sr.Name;
     if(sr.Attr & faDirectory)
     {
       viewDirs(dfile);
     }
     else
       lst->AddObject(dfile,(TObject*)sr.Attr);
   }while(!FindNext(sr) && !Terminated);
 lst->AddObject(dir,(TObject*)faDirectory);
 FindClose(sr);
}
//---------------- Функция отображения процесса удаления 1 -----------------
void __fastcall TDelThread::LabMess1()
{
 FormHideCreatePross->Label1->Caption="Поиск файлов";
}
//------------------ Функция отображения процесса удаления 2 ---------------
void __fastcall TDelThread::refreshDel()
{
 String sub=dfile.SubString(dfile.LastDelimiter("\\")+1,MAX_PATH);
 FormHideCreatePross->Label2->Caption=sub;
 FormHideCreatePross->Label1->Caption="Процесс удаления";
 FormHideCreatePross->ProgressBar1->StepIt();
}
//****************************************************************************