1. Майкл Хаймен, Боб Арнсон. VisualC++: Учеб. Пособие. – М.: Диалектика, 2002. – 289 с.: ил.
2. А. Корера, С. Фрейзер, С. Маклин, Н. Кумар, С. Робинсон, П.Г. Саранг, С. Джентайл. VisualC++. Пособие для разработчиков. Изд-во «Лори», 2003. – 417 с.: ил.
Рисунок А.1 – Основной алгоритм программы
Вышеуказанный алгоритм основной программы реализует защиту от запуска второй копии приложения. Если копия приложения уже запущена (найдены ее окна) – программа активизирует свою предыдущую копию и завершает работу, иначе – стандартное выполнение программы.
Рисунок А.2 – Алгоритм проверки регистрации по имени и номеру подкаталога
Вышеуказанный алгоритм реализует проверку и регистрацию файла в отчете. Этот метод отчета применяется к каждому найденному файлу в контролируемых каталогах.
Рисунок А.3 – Главная функция для проверки каталогов и подготовки отчета
Вышеуказанный алгоритм реализует полный механизм проверки контролируемых каталогов и подготовки отчета. В алгоритме предусмотрены механизмы для досрочного завершения проверки по признаку завершения родительского потока, а также перезапуск проверки по признаку изменения файлов (от потока контроля файлов)
Рисунок А.4 – Главная функция потока проверки файлов
Вышеуказанный алгоритм реализует работу потока проверки файлов. Вызовы методов потока CheckStep и SetLists синхронизируются с главным VCL-потоком программы. Проверка файлов с передачей отчета главному окну программы инициируется взведением события NeverEvent - потоком контроля файлов по факту изменения состава файлов. Также предусмотрен механизм завершения потока – взведением свойства Terminated и события NeverEvent.
Файл проекта FileNames.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
//---------------------------------------------------------------------------
USEFORM("FMain.cpp", FForm);
USEFORM("FSelectDirForm.cpp", SDForm);
//---------------------------------------------------------------------------
WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
//защита от повторного запуска
HWNDw=FindWindow("TFForm","Контроль одноименных файлов"),
w2=FindWindow("TSDForm","Выбор каталога");
if(w) {//при обнаружении запущенной копии приложения - активизирует
//ее главное окно и завершает работу
if(IsWindowVisible(w)) {
if(w2 && IsWindowVisible(w2)) SetForegroundWindow(w2);
else SetForegroundWindow(w);
}
else PostMessage(w,WM_USER+2,0,0);
}
else{ //иначе - стандартное выполнение программы
Application->Initialize();
Application->CreateForm(__classid(TFForm), &FForm);
Application->CreateForm(__classid(TSDForm), &SDForm);
Application->Run();
}
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
Файл ArrayTemplate.h
//---------------------------------------------------------------------------
#ifndefArrayTemplateH
#defineArrayTemplateH
//---------------------------------------------------------------------------
//шаблон на динамический массив со свойствами коллекции(списка элементов)
template <class T> class TArray
{
private:
intfCount,fLength; //кол-во элементов,размер массива
T *fItems; //указатель на массив
protected:
T __fastcall Get(int Index); //чтение элемента массива
void __fastcall Put(int Index, T Item); //запись элемента массива
void __fastcall SetCount(int NewCount); //установка fCount
public:
TArray(int aLength); //конструктор
~TArray(void); //деструктор
void __fastcall Insert(int Index,T Item);//вставка элемента
void __fastcall Delete(int Index); //удаление элемента
void __fastcall Add(T Item); //добавление элемента
void __fastcallClear(void); //удаление всех элементов
void __fastcallSetLength (intNewLen); //определить размер массива
T& operator[](intIndex); //оператор []-доступ к элементу
void* operator&(void); //оператор & - адрес массива
__property T Items[int Index] = {read=Get, write=Put}; //свойство для доступа к элементу
__property int Count = {read=fCount, write=SetCount}; //свойство для доступа к кол-ву элементов списка
__property int Length = {read=fLength, write=SetLength};//свойство для доступа к размеру массива
};
template <class T> TArray<T>::TArray(int aLength)
{
fCount=0;
fLength=0;
SetLength(aLength);
}
template <class T> TArray<T>::~TArray(void) { SetLength(0); }
template <class T> T& TArray<T>::operator[](int Index) { return fItems[Index];}
template <class T> void* TArray<T>::operator&(void) {return fItems;}
template <class T> T __fastcall TArray<T>::Get(int Index) { return fItems[Index]; }
template <class T> void __fastcall TArray<T>::Put(int Index, T Item) { fItems[Index]=Item; }
template <class T> void __fastcall TArray<T>::Add(T Item){ Insert(fCount,Item); }
template <class T> void __fastcall TArray<T>::Clear(void) { fCount=0; }
template <class T> void __fastcall TArray<T>::SetCount(int NewCount)
{
fCount=NewCount;
if(fCount<0) fCount=0;
if(fCount>fLength) fCount=fLength;
}
template <class T> void __fastcall TArray<T>::Insert(int Index,T Item)
{
if(Index<0 || Index>fCount) return;
if (fCount==fLength) SetLength(fLength+5);
if (Index<fCount) Move(&fItems[Index],&fItems[Index+1],(fCount-Index)*sizeof(T));
fItems[Index]=Item;
fCount++;
}
template <class T> void __fastcall TArray<T>::Delete(int Index)
{
if(Index<0 || Index>fCount-1) return;
if (Index<fCount-1) Move(&fItems[Index+1],&fItems[Index],(fCount-1-Index)*sizeof(T));
fCount--;
//if (fCount==fLength-6) SetLength(fCount+1);
}
template <class T> void __fastcall TArray<T>::SetLength (int NewLen)
{
if (NewLen<0 || fLength==0 && NewLen==0) return; else
if (fLength==0) fItems=(T *)SysGetMem(NewLen*sizeof(T));else
if (NewLen==0) SysFreeMem(fItems);else fItems=(T *)SysReallocMem(fItems,NewLen*sizeof(T));
fLength=NewLen;
if (fLength<fCount) fCount=fLength;
}
//динамические массивы (с элементами int и HANDLE)
typedef TArray<int> TIntArray;
typedef TArray<HANDLE> THandleArray;
#endif
Файл ArrayTemplate.cpp
//---------------------------------------------------------------------------
#pragma hdrstop
#include <System.hpp>
#include "ArrayTemplate.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
Файл FSelectDirForm.h
//---------------------------------------------------------------------------
#ifndef FSelectDirFormH
#define FSelectDirFormH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <FileCtrl.hpp>
//---------------------------------------------------------------------------
class TSDForm : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TButton *Button2;
TDirectoryListBox *DirectoryListBox1;
TDriveComboBox *DriveComboBox1;
private: // User declarations
public: // User declarations
__fastcall TSDForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TSDForm *SDForm;
//---------------------------------------------------------------------------
#endif
Файл FSelectDirForm.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "FSelectDirForm.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TSDForm *SDForm;
//---------------------------------------------------------------------------
__fastcall TSDForm::TSDForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
Файл FMain.h
//---------------------------------------------------------------------------
#ifndef FMainH
#define FMainH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include "ArrayTemplate.h"
#include <ExtCtrls.hpp>
#include <Menus.hpp>
#include <Buttons.hpp>
//---------------------------------------------------------------------------
//используемые коды сообщений
#define WM_SHELLMESS (WM_USER + 1) //от значка в System Tray
#defineWM_SHOWMYWIN (WM_USER + 2) //от второй копии программы
//тип-список строк для хранения имен файлов, а также номеров каталогов
//(в списке каталогов) для каждого имени
class TGlobalList:public TStringList
{
public:
int __fastcallAt(intIndex); //доступ к номеру каталога для выбранного файла
};
//тип-список строк для хранения имен файлов-дубликатов,а также указателей
//на массивы номеров каталогов (TIntArray *) для каждого файла-дубликата
class TNameList:public TStringList
{
public:
TIntArray * __fastcallAt(intIndex); //доступ к массиву номеров для выбранного файла
};
//предварительное объявление
classTVerDirectory;
//тип-поток для проверки каталогов и подготовки отчета по одноименным файлам
class TDirThread:public TThread
{
protected:
void __fastcall Execute(); //главная функция потока
public:
TVerDirectory *Report; //подготавливаемый отчет
__fastcall TDirThread(bool CreateSuspended):TThread(CreateSuspended) {} //конструктор
void __fastcallSetLists(void); //передача отчета главному окну программы
void __fastcallCheckStep(void); //отмечает в главном окне начало проверки каталогов
bool Term(void) {return Terminated;} //возвращает Terminated(protected - свойство)
};
//тип-поток для автоматического контроля проверяемых каталогов -
// при переименовке, добавлении и удалении файлов в данных каталогах (или их подкаталогах)
// инициирует проверку каталогов с подготовкой отчета
class TNotifyThread:public TThread
{
protected:
void __fastcall Execute(); //главная функция потока
public:
__fastcall TNotifyThread(bool CreateSuspended):TThread(CreateSuspended) {}//конструктор
bool Term(void) {return Terminated;} //возвращает Terminated(protected - свойство)
};
//тип-подготавливаемый отчет
class TVerDirectory
{
public:
TDirThread * Owner; //поток-владелец отчета - только указатель
AnsiStringPath;
TStringList *DirList; //список подкаталогов проверяемого каталога
TGlobalList *GlobalList; //общий список имен файлов
TNameList *NameList; //список обнаруженных одноименных файлов
TNameList *ExNames; //проверяемые каталоги(пути) - только указатель
TVerDirectory(TStrings * fExNames, AnsiString fPath, TDirThread * aOwner);//-конструктор