Смекни!
smekni.com

Системное программирование для операционных систем (стр. 4 из 5)

~TVerDirectory(void); //-деструктор

void __fastcall Clear(void); //-очистка отчета

void __fastcallFill(void); //-главная функция для подготовки отчета

bool __fastcall WorkFile(int PathNum,AnsiString Name); //-проверка файла

bool __fastcall WorkDir(AnsiString Path); //-проверка каталога

// (с рекурсивными вызовами для подкаталогов)

void __fastcallSetNameList(TStrings * DestList); //-для передачи в оконный компонент списка одноименных файлов

void __fastcallSetExNames(TStrings * DestList); //-для передачи в оконный компонент списка исключений

void __fastcallSetDirList(intNameNum,TStrings * DestList);//-для передачи в оконный компонент списка путей расположения

// выбранного файла (с номером NameNum в списке NameList)

void __fastcallSetDirListEx(intNameNum,TStrings * DestList);//-для передачи в оконный компонент списка путей расположения

// выбранного файла (с номером NameNum в списке ExNames)

bool __fastcall SetEx(int Index); //передатьфайлиз NameList в ExNames

bool __fastcall ResetEx(int Index); //передать файл из ExNames в NameList

};

//---------------------------------------------------------------------------

//тип - форма главного окна

class TFForm : public TForm

{

__published: // IDE-managed Components

TButton *Button1;

TPopupMenu *PopupMenu1;

TMenuItem *N1;

TMenuItem *N2;

TPanel *Panel1;

TLabel *Label1;

TListBox *NameBox;

TLabel *Label2;

TListBox *DirBox;

TPanel *Panel2;

TLabel *Label3;

TButton *AddDirButton;

TTimer *Timer1;

TLabel *Label5;

TListBox *ExBox;

TLabel *Label4;

TSpeedButton *SetExButton;

TSpeedButton *ResetExButton;

TTimer *Timer2;

void __fastcall NameBoxClick(TObject *Sender);

void __fastcall FormActivate(TObject *Sender);

void __fastcall N1Click(TObject *Sender);

void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

void __fastcall N2Click(TObject *Sender);

void __fastcall Button1Click(TObject *Sender);

void __fastcall Timer1Timer(TObject *Sender);

void __fastcall ExBoxClick(TObject *Sender);

void __fastcall AddDirButtonClick(TObject *Sender);

void __fastcall SetExButtonClick(TObject *Sender);

void __fastcall ResetExButtonClick(TObject *Sender);

private: // User declarations

void __fastcall WMShellMess(TMessage &Message); //обработчик WM_SHELLMESS

void __fastcall ShowMyWin(TMessage &Message); //обработчик WM_SHOWMYWIN

public: // User declarations

TVerDirectory *Report; //подготовленный отчет по одноименным файлам

TDirThread *DirThr; //поток проверки каталогов

TNotifyThread *NotifyThr; //поток автоматического контроля каталогов

TNotifyIconDataNotifyData; //структура для регистрации значка в SystemTray

boolAppClose; //признак выхода из программы

__fastcallTFForm(TComponent* Owner);//конструктор

void __fastcallCallThreads(void); //создание и запуск потоков контроля и проверки каталогов

void __fastcallStopThreads(void); //завершение и удаление потоков контроля и проверки каталогов

BEGIN_MESSAGE_MAP

MESSAGE_HANDLER(WM_SHELLMESS, TMessage, WMShellMess)

MESSAGE_HANDLER(WM_SHOWMYWIN, TMessage, ShowMyWin)

END_MESSAGE_MAP(TForm)

};

//---------------------------------------------------------------------------

extern PACKAGE TFForm *FForm;

//---------------------------------------------------------------------------

//---------------------------------------------------------------------------

#endif

Файл FMain.cpp

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "FMain.h"

#include "FSelectDirForm.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TFForm *FForm;

boolDirectoryNever; //признак необходимости перезапуска проверки каталогов

void *NeverMutex, //мъютекс для синхронизации доступа к DirectoryNever (для записи)

*NeverEvent; //событие для синхронизации потоков проверки файлов и контроля файлов

//---------------------------------------------------------------------------

//------------------------TGlobalList,TNameList---------------------------------

int __fastcall TGlobalList::At(int Index) {return (int)Objects[Index];}

TIntArray * __fastcall TNameList::At(int Index) {return (TIntArray *)Objects[Index];}

//---------------------------------------------------------------------------

//------------------------TVerDirectory----------------------------------------

TVerDirectory::TVerDirectory(TStrings * fExNames, AnsiString fPath, TDirThread * aOwner)

{

Path=fPath;

Owner=aOwner;

DirList= new TStringList();

GlobalList = new TGlobalList(); GlobalList->Sorted=true;

NameList = new TNameList(); NameList->Sorted=true;

ExNames = new TNameList(); ExNames->Sorted=true;

ExNames->AddStrings(fExNames);

}

//---------------------------------------------------------------------------

TVerDirectory::~TVerDirectory(void)

{

Clear();

delete DirList;

delete GlobalList;

delete NameList;

delete ExNames;

}

//---------------------------------------------------------------------------

void __fastcall TVerDirectory::Clear(void)

{

for(int i=0; i<NameList->Count;i++) delete NameList->At(i);

for(int i=0; i<ExNames->Count;i++)

if (ExNames->At(i) != NULL)

{

delete ExNames->At(i);

ExNames->Objects[i]=NULL;

}

NameList->Clear();

GlobalList->Clear();

DirList->Clear();

}

//---------------------------------------------------------------------------

//главная функция для проверки каталогов и подготовки отчета

//если проверка была прервана в связи с изменением состава файлов (взведен DirectoryNever)-

//проверка начинается сначала.

//если проверка была прервана в связи с завершением родительского потока - выход из функции

void __fastcall TVerDirectory::Fill(void)

{

bool cc=true;

while (!Owner->Term() && cc)

{

//проверка

cc=!WorkDir(Path);

if(cc)

{

Clear();

WaitForSingleObject( NeverMutex,INFINITE);

DirectoryNever=false;

ReleaseMutex(NeverMutex);

}

}

}

//---------------------------------------------------------------------------

//проверка-регистрация в отчете файла (по имени и номеру подкаталога)

//при изменении состава файлов(взведен DirectoryNever) или при завершении

//родительского потока - досрочный выход с результатом - false

bool __fastcall TVerDirectory::WorkFile(int PathNum,AnsiString Name)

{

//выход при необходимости

if (DirectoryNever || Owner->Term() ) return false;

int i, j,k;

TIntArray *T;

j=ExNames->IndexOf(Name);

if(j>=0)//имя в списке исключений

{

if(ExNames->At(j) == NULL) {//создать массив

T = new TIntArray(3);

ExNames->Objects[j]=(TObject *)T;

}

(ExNames->At(j))->Add(PathNum);//добавить номер каталога

}

else

{

i=GlobalList->IndexOf(Name);

if(i>=0)//такой файл уже есть

{

j = NameList->IndexOf(Name);

if(j>=0) (NameList->At(j))->Add(PathNum);//добавить номер каталога в массив

else { //создать и заполнить массив номеров каталогов

T = new TIntArray(3);

T->Add(GlobalList->At(i));

T->Add(PathNum);

//включить файл в список одинаковых

NameList->AddObject(Name,(TObject *)T);

}

}

else GlobalList->AddObject(Name,(TObject *)PathNum);//включить файл в общий список

}

//выход

returntrue;

}

//---------------------------------------------------------------------------

//проверка-регистрация в отчете каталога (а также его содержимого, для подкаталогов - рекурсивные вызовы)

//при изменении состава файлов(взведен DirectoryNever) или при завершении

//родительского потока - досрочный выход с результатом - false

bool __fastcall TVerDirectory::WorkDir(AnsiString Path)

{

//выход при необходимости

if (DirectoryNever || Owner->Term() ) return false;

TSearchRec SRec;

bool Result=true;

TStringList *FList = new TStringList(),*DList= new TStringList();

FList->Sorted=true;

DList->Sorted=true;

//заполнить списки файлов и каталогов

if(FindFirst(Path+"*.*",faAnyFile,SRec)==0)

do{

if(SRec.Name!="." && SRec.Name!="..")

{

if (SRec.Attr & faDirectory) DList->Add(SRec.Name);

else FList->Add(SRec.Name);

}

}while(FindNext(SRec)==0);

FindClose(SRec);

//обработка себя самого

DirList->Add(Path);

//обработка файлов

for(int i=0;i<FList->Count;i++)

if(!WorkFile(DirList->Count-1,FList->Strings[i])) {Result=false;break;}

delete FList;

//обработка подкаталогов

if(Result)

for(int i=0;i<DList->Count;i++)

if (!WorkDir(Path+DList->Strings[i]+"&bsol;")) {Result=false;break;};

delete DList;

//выход

return Result;

}

//---------------------------------------------------------------------------

void __fastcall TVerDirectory::SetNameList(TStrings * DestList)

{

DestList->Clear();

for(int i=0;i<NameList->Count;i++) DestList->Add(NameList->Strings[i]);

}

//---------------------------------------------------------------------------

void __fastcall TVerDirectory::SetExNames(TStrings * DestList)

{

DestList->Clear();

for(int i=0;i<ExNames->Count;i++) DestList->Add(ExNames->Strings[i]);

}

//---------------------------------------------------------------------------

void __fastcall TVerDirectory::SetDirList(int NameNum,TStrings * DestList)

{

DestList->Clear();

for(int i=0;i<NameList->At(NameNum)->Count;i++)

DestList->Add(DirList->Strings[NameList->At(NameNum)->Items[i]] );

}

//---------------------------------------------------------------------------

void __fastcall TVerDirectory::SetDirListEx(int NameNum,TStrings * DestList)

{

DestList->Clear();

if (ExNames->At(NameNum) == NULL) DestList->Add("ФАЙЛ ОТСУТСТВУЕТ"); else

for(int i=0;i<ExNames->At(NameNum)->Count;i++)

DestList->Add(DirList->Strings[ExNames->At(NameNum)->Items[i]] );

}

//---------------------------------------------------------------------------

bool __fastcall TVerDirectory::SetEx(int Index)

{

if(Index>=0 && Index<NameList->Count)

{

ExNames->AddObject(NameList->Strings[Index],NameList->Objects[Index]);

NameList->Delete(Index);

return true;

} else return false;

}

//---------------------------------------------------------------------------

bool __fastcall TVerDirectory::ResetEx(int Index)

{

if(Index>=0 && Index<ExNames->Count)

{

if(ExNames->At(Index)==NULL)

{

if(Application->MessageBoxA(((AnsiString)"Выбранный файл отсутствует в контролируемом каталоге.&bsol;n"+

"Удалить его из списка исключений?").c_str(),"Предупреждение",MB_YESNO | MB_ICONWARNING)==IDYES)

{

ExNames->Delete(Index);

return true;

}

} else

if(ExNames->At(Index)->Count==1)

{

if(Application->MessageBoxA(((AnsiString)"Выбранный файл в контролируемом каталоге присутствует в единственном числе.&bsol;n"+

"Удалить его из списка исключений?").c_str(),"Предупреждение",MB_YESNO | MB_ICONWARNING)==IDYES)

{

delete ExNames->At(Index);

ExNames->Delete(Index);

return true;

}

} else {

NameList->AddObject(ExNames->Strings[Index],ExNames->Objects[Index]);

ExNames->Delete(Index);

return true;

}

}

returnfalse;

}

//---------------------------------------------------------------------------

//------------------------------TDirThread--------------------------------------

//включает мигание надписи "Запущена проверка"

void __fastcall TDirThread::CheckStep(void)

{

FForm->Timer1->Enabled=true;

FForm->Label5->Visible=true;

}

//---------------------------------------------------------------------------

//передает подготовленный отчет главному окну программы

//(с открытием и активизацией главного окна)

void __fastcall TDirThread::SetLists(void)

{

//отключить мигание надписи "Запущена проверка"

FForm->Timer1->Enabled=false;

FForm->Label5->Visible=false;

TVerDirectory *OldReport=FForm->Report;

bool First=(OldReport == NULL);//First=true при подготовке потоком первого отчета

FForm->Report=Report; //передача нового отчета

//настройка оконных компонентов под новый отчет

FForm->Report->SetNameList(FForm->NameBox->Items);

FForm->ExBox->ItemIndex=-1;

FForm->DirBox->Clear();

FForm->SetExButton->Enabled=false;

FForm->ResetExButton->Enabled=false;

if(Report->NameList->Count>0)

FForm->Panel2->Caption="Обнаружены одноименные файлы!";

else FForm->Panel2->Caption="Одноименные файлы отсутствуют.";

//открытие и активизация главного окна приложения

if(!First && (Report->NameList->Count>0 || OldReport->NameList->Count>0))

if(FForm->Visible) {

//Второй запуск самого себя - только такой путь, чтобы вытащить окно на передний

//план (SetForegroundWindow из другого процесса)

WinExec(ParamStr(0).c_str(),SW_SHOWNORMAL);

}

else {//открыть окно

ShowWindow(Application->Handle, SW_SHOW);

FForm->Show();

}

if(!First) delete OldReport; //удалить старый отчет

//при подг-ке первого отчета (одноименных файлов нет) - скрыть окно через 2 сек.

else if (Report->NameList->Count==0) FForm->Timer2->Enabled=true;

}

//---------------------------------------------------------------------------

//главная функция потока проверки файлов

//первую проверку выполняет безусловно, последующие проверки - по взводу