|
||||||||||||
|
||||||||||||
|
|||||||||
МЕНЮ
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА - РЕФЕРАТЫ - Системное программирование для операционных системСистемное программирование для операционных системФедеральное агентство по образованию Государственное образовательное учреждение высшего профессионального образования «ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ» Кафедра «Информационная безопасность систем и технологий» УТВЕРЖДАЮ Зав. кафедрой ИБСТ ______________ С.Л. Зефиров ОТЧЕТ О КУРСОВОМ ПРОЕКТЕ «Системное программирование для операционных систем» Руководитель КП Н.А.Егорова Исполнитель КП П.А. Пивоваров Нормоконтролер Т.В. Щербакова Пенза, 2007 РефератПояснительная записка содержит 39 с., 5 рис., 2 источника, 2 приложения.Алгоритм, ДОКУМЕНТ, ПРИЛОЖЕНИЕ, ФАЙЛ, МАСТЕР, ОБЪЕКТ.Целью проекта является разработка резидентной программы, контролирующую наличие одинаковых файлов на диске (в выбранных каталогах). Требования к программе: - программа должна иметь значок в System Tray, при закрытии ее главного окна программа должна оставаться в оперативной памяти, но соответствующая кнопка из панели задач должна быть удалена; - при щелчке мышью на значке программы в System Tray должно вызываться всплывающее меню с командами для показа ее главного окна, и для ее закрытия (выгрузки из памяти); - программа должна иметь возможность смены контролируемого каталога; - программа должна иметь список имен файлов - исключений, а также средство для редактирования этого списка; - программа должна в фоновом режиме контролировать состав файлов в контролируемом каталоге, и информировать пользователя о наличии/появлении одноименных файлов (с подготовкой отчета по одноименным файлам). В процессе работы была разработана программа, осуществляющая поиск, анализ содержимого каталога, написанная на языке программирования С++. СодержаниеРефератНормативные ссылкиВведение1 Структура основной программы2 Программная реализация алгоритма3 Исходный текст программы приведен в приложении Б.3 Функциональные возможности программы4 Руководство по использованию программыЗаключениеСписок использованных источниковПриложение Б (ОБЯЗАТЕЛЬНОЕ) Листинги программыНормативные ссылкиВ настоящем отчете использованы ссылки на следующие стандарты:- ГОСТ 1.5 - 93 Государственная система стандартизации РФ. Общие требования к построению, изложению, оформлению и содержанию стандартов.- ГОСТ 2.105 - 95 Единая система конструкторской документации.- ГОСТ 2.301 - 68 ЕСКД Форматы.- ГОСТ 7.1 - 84 Система стандартов по информации, библиотечному и издательскому делу. Библиографическое описание документа. Общие требования и правила составления.- ГОСТ 7.32 - 2001 Система стандартов по информации, библиотечному, издательскому делу. Отчёт о научно - исследовательской работе.ВведениеВ настоящее время для подавляющего числа пользователей компьютер - это не роскошь, а средство работы с информацией, объем которой с каждым годом удваивается. Интернет, видео, музыка, документы гипертекста и так далее -- все это служит для представления информации в нужном нам виде, обеспечивая тем самым довольно быстрый и удобный доступ к ней. А для создания всего этого используются языки программирования различного уровня. Например, пакет Microsoft Visual Studio. NET поддерживает следующие языки программирования: Visual Basic, Visual C++, Visual С#, Visual J#. Работая с языком Visual C++, в ваших руках оказывается мощный, полезный и широко распространенный инструмент. При его помощи можно получить в распоряжение довольно сильную и удобную систему создания приложений для операционных систем семейства Windows. С его помощью созданы такие продукты, как Excel и Access. Этот язык также применяется при разработке управленческих информационных систем и систем целевого назначения, используемых для анализа деятельности предприятий и принятия решений в сфере управления бизнесом. И, конечно же, целые армии хакеров и не только хакеров используют C++ для создания инструментов, утилит, игр и шедевров мультимедиа. Знания языка C++, позволяют создавать не просто приложения, а приложения, работающие в разных операционных системах. Возможности этого языка практически не ограничены.Для создания удобного интерфейса программы под Windows, удобней использовать объектно-ориентированный язык программирования. Именно поэтому для реализации курсового проекта используется язык Microsoft Visual C++ 6.0. Автоматизированное создание приложений включено в компилятор Microsoft Visual C++ 6.0 и называется MFC AppWizard. MFC AppWizard создает тексты приложений только с использованием библиотеки классов MFC (Microsoft Foundation Class library). Таким образом, изучив язык C++ и библиотеку MFC, можно создавать свои приложения. Поэтому, используя средства автоматизированного создания приложений, можно сократить время написания довольно сложных программ. Так, при знании всех необходимых функций библиотеки MFC и WinAPI для написания программы по заданию курсового проекта потребуется не больше пары минут. При этом вручную придётся написать лишь несколько вызовов функций, а всё остальное сделает MFC AppWizard, используя возможности ClassWizard.Суть задачи, поставленная в данном курсовом проекте, состоит в написании программы, которая должна осуществлять поиск одинаковых документов (по имени, размеру).Пояснительная записка должна отражать следующие этапы работы: разработку алгоритмов программы, разработку пользовательского интерфейса, программную реализацию проекта, отладку и тестирование разработанной программы, описание работы с программой (руководство пользователя).1. Структура основной программыПри запуске программы на экран выводится диалоговое окно, на котором заданы поля для введения необходимых данных для поиска, поле для введения пути, кнопка «Скрыть окно», поля для вывода результата поиска. Описания функций модуля FMain:
Описанные (вручную) типы:
Программа осуществляет поиск одинаковых документов по имени и размеру. В программе предусмотрена защита от запуска второй копии приложения. При запуске второй копии приложения - она открывает и активизирует главное окно первой копии, и завершает работу. Необходимо отметить, что программа хранит свои параметры (путь к контролируемому каталогу и список исключений) в файле «FileNames.inf» (в каталоге с исполняемым модулем программы). При запуске программы - она считывает параметры из этого файла, при закрытии программы параметры будут сохранены в этот файл. Если при запуске программы этот файл отсутствует - в качестве контролируемого назначается каталог с исполняемым модулем программы, а список исключений пуст. Также нужно сказать о том, что при запуске программы, при условии что одноименных файлов нет - ее главное окно будет скрыто через две секунды после подготовки первого отчета. Это сделано для того, чтобы программу можно было включать в меню автозагрузки Windows, как любую другую фоновую программу (при запуске программы ее главное окно выступает в качестве заставки). 5. Руководство по использованию программыДля запуска курсового проекта необходимо запустить файл Filenames.exe. - Программа предназначена для контроля одноименных файлов на диске в выбранных каталогах. - Загрузочный модуль программы - FileNames.exe . - ОС Windows 9X, Windows NT/2000/XP , требования к машине (ПЭВМ) накладываются операционной системой. При загрузке программа регистрирует значок в System Tray (правый нижний угол экрана), и при закрытии ее главного окна программа остается в памяти. Для закрытия программы надо щелкнуть мышью на значке в в System Tray и во всплывающем меню выбрать «Закрыть программу». Для показа главного окна надо выбрать пункт всплывающего меню «Отчет, настройки программы» (см. рисунок 1). Наглядное изображение программы приведено на рисунке 1: Рисунок 1 - Вид окна программы Для смены контролируемого каталога нажмите кнопку под надписью «проверяемый каталог» (надпись на кнопке-путь к контролируемому каталогу). В появившемся окне (рисунок 2) выберите нужный каталог и нажмите «Ввод» Рисунок 2 - Выбор каталога При двойном щелчке на нужном каталоге окно выбора каталогов тоже закроется. После этого будет произведена проверка (перепроверка) файлов для выбранного каталога (включая его подкаталоги), с подготовкой отчета по одноименным файлам. При операциях добавления(копирования), удаления и переименования файлов в контролируемых каталогах - отчет по одноименным файлам обновляется автоматически, и если обнаруживаются одноименные файлы - будет выполнено оповещение пользователя (главное окно программы будет открыто и выведено на передний план). Надо иметь в виду, что операция проверки выбранного каталога (с подготовкой отчета) может занять некоторое время, и сопровождается миганием надписи «Запущена проверка» в главном окне программы. В главном окне программы также имеется список файлов-исключений, для которых оповещение пользователя не производится. Аналогично списку одноименных файлов, при выборе в списке исключений файла - в списке путей будут отображены пути расположения этого файла, или надпись «ФАЙЛ ОТСУТСТВУЕТ», если файл в контролируемом каталоге отсутствует. Для переноса файла из списка одноименных файлов в список исключений выделите нужную строку в списке одноименных файлов и нажмите кнопку «перенести в список исключений». Для переноса файла из списка исключений в список одноименных файлов выделите нужную строку в списке исключений и нажмите кнопку «перенести в список одноименных файлов». Если данный файл отсутствует в контролируемом каталоге, или присутствует в нем в единственном числе - в соответствующем сообщении вам будет предложено просто удалить данное имя из списка исключений. ЗаключениеВ результате проделанной работы была создана программа, осуществляющая поиск одинаковых документов (по имени, размеру, дате создания). Во время проведения работы были приобретены навыки работы с языком программирования высокого уровня Visual C++. Исходя из того, что программа полностью соответствует заданию курсового проекта, можно сделать вывод, что задание на курсовую работу выполнено в полном объеме.Список использованных источниковМайкл Хаймен, Боб Арнсон. Visual C++: Учеб. Пособие. - М.: Диалектика, 2002. - 289 с.: ил. А. Корера, С. Фрейзер, С. Маклин, Н. Кумар, С. Робинсон, П.Г. Саранг, С. Джентайл. Visual C++. Пособие для разработчиков. Изд-во «Лори», 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{//защита от повторного запускаHWND w=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//---------------------------------------------------------------------------#ifndef ArrayTemplateH#define ArrayTemplateH//---------------------------------------------------------------------------//шаблон на динамический массив со свойствами коллекции(списка элементов)template <class T> class TArray{private:int fCount,fLength; //кол-во элементов,размер массиваT *fItems; //указатель на массивprotected:T __fastcall Get(int Index); //чтение элемента массиваvoid __fastcall Put(int Index, T Item); //запись элемента массиваvoid __fastcall SetCount(int NewCount); //установка fCountpublic:TArray(int aLength); //конструктор~TArray(void); //деструкторvoid __fastcall Insert(int Index,T Item);//вставка элементаvoid __fastcall Delete(int Index); //удаление элементаvoid __fastcall Add(T Item); //добавление элементаvoid __fastcall Clear(void); //удаление всех элементовvoid __fastcall SetLength (int NewLen); //определить размер массиваT& operator[](int Index); //оператор []-доступ к элементу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) 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 template <class T> void __fastcall TArray<T>::SetLength (int NewLen)//динамические массивы (с элементами 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 ComponentsTButton *Button1;TButton *Button2;TDirectoryListBox *DirectoryListBox1;TDriveComboBox *DriveComboBox1;private: // User declarationspublic: // 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#define WM_SHOWMYWIN (WM_USER + 2) //от второй копии программы//тип-список строк для хранения имен файлов, а также номеров каталогов//(в списке каталогов) для каждого имениclass TGlobalList:public TStringList{public:int __fastcall At(int Index); //доступ к номеру каталога для выбранного файла};//тип-список строк для хранения имен файлов-дубликатов,а также указателей//на массивы номеров каталогов (TIntArray *) для каждого файла-дубликатаclass TNameList:public TStringList{public:TIntArray * __fastcall At(int Index); //доступ к массиву номеров для выбранного файла};//предварительное объявлениеclass TVerDirectory;//тип-поток для проверки каталогов и подготовки отчета по одноименным файламclass TDirThread:public TThread{protected:void __fastcall Execute(); //главная функция потокаpublic:TVerDirectory *Report; //подготавливаемый отчет__fastcall TDirThread(bool CreateSuspended):TThread(CreateSuspended) {} //конструкторvoid __fastcall SetLists(void); //передача отчета главному окну программыvoid __fastcall CheckStep(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; //поток-владелец отчета - только указательAnsiString Path;TStringList *DirList; //список подкаталогов проверяемого каталогаTGlobalList *GlobalList; //общий список имен файловTNameList *NameList; //список обнаруженных одноименных файловTNameList *ExNames; //проверяемые каталоги(пути) - только указательTVerDirectory(TStrings * fExNames, AnsiString fPath, TDirThread * aOwner);//-конструктор~TVerDirectory(void); //-деструкторvoid __fastcall Clear(void); //-очистка отчетаvoid __fastcall Fill(void); //-главная функция для подготовки отчетаbool __fastcall WorkFile(int PathNum,AnsiString Name); //-проверка файлаbool __fastcall WorkDir(AnsiString Path); //-проверка каталога// (с рекурсивными вызовами для подкаталогов)void __fastcall SetNameList(TStrings * DestList); //-для передачи в оконный компонент списка одноименных файловvoid __fastcall SetExNames(TStrings * DestList); //-для передачи в оконный компонент списка исключенийvoid __fastcall SetDirList(int NameNum,TStrings * DestList);//-для передачи в оконный компонент списка путей расположения// выбранного файла (с номером NameNum в списке NameList)void __fastcall SetDirListEx(int NameNum,TStrings * DestList);//-для передачи в оконный компонент списка путей расположения// выбранного файла (с номером NameNum в списке ExNames)bool __fastcall SetEx(int Index); //передать файл из NameList в ExNamesbool __fastcall ResetEx(int Index); //передать файл из ExNames в NameList};//---------------------------------------------------------------------------//тип - форма главного окнаclass TFForm : public TForm{__published: // IDE-managed ComponentsTButton *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 declarationsvoid __fastcall WMShellMess(TMessage &Message); //обработчик WM_SHELLMESSvoid __fastcall ShowMyWin(TMessage &Message); //обработчик WM_SHOWMYWINpublic: // User declarationsTVerDirectory *Report; //подготовленный отчет по одноименным файламTDirThread *DirThr; //поток проверки каталоговTNotifyThread *NotifyThr; //поток автоматического контроля каталоговTNotifyIconData NotifyData; //структура для регистрации значка в System Traybool AppClose; //признак выхода из программы__fastcall TFForm(TComponent* Owner);//конструкторvoid __fastcall CallThreads(void); //создание и запуск потоков контроля и проверки каталоговvoid __fastcall StopThreads(void); //завершение и удаление потоков контроля и проверки каталоговBEGIN_MESSAGE_MAPMESSAGE_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;bool DirectoryNever; //признак необходимости перезапуска проверки каталогов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) или при завершении//родительского потока - досрочный выход с результатом - falsebool __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);//включить файл в общий список}//выходreturn true;}//---------------------------------------------------------------------------//проверка-регистрация в отчете каталога (а также его содержимого, для подкаталогов - рекурсивные вызовы)//при изменении состава файлов(взведен DirectoryNever) или при завершении//родительского потока - досрочный выход с результатом - falsebool __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]+"\\")) {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("ФАЙЛ ОТСУТСТВУЕТ"); elsefor(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)"Выбранный файл отсутствует в контролируемом каталоге.\n"+"Удалить его из списка исключений?").c_str(),"Предупреждение",MB_YESNO | MB_ICONWARNING)==IDYES){ExNames->Delete(Index);return true;}} elseif(ExNames->At(Index)->Count==1){if(Application->MessageBoxA(((AnsiString)"Выбранный файл в контролируемом каталоге присутствует в единственном числе.\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;}}return false;}//---------------------------------------------------------------------------//------------------------------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;}//---------------------------------------------------------------------------//главная функция потока проверки файлов//первую проверку выполняет безусловно, последующие проверки - по взводу//события NeverEvent (от потока контроля)void __fastcall TDirThread::Execute(){while(!Terminated){//создать ReportReport=new TVerDirectory( FForm->ExBox->Items,FForm->AddDirButton->Caption ,this);//сбросить DirectoryNeverWaitForSingleObject( NeverMutex,INFINITE);DirectoryNever=false;ReleaseMutex(NeverMutex);//отметить начало проверкиSynchronize(CheckStep);//проверкаReport->Fill();if (!Terminated)//если поток не завершен{//передать отчет главному окнуSynchronize(SetLists);//ожидание взвода события NeverEventWaitForSingleObject(NeverEvent,INFINITE);}else delete Report;//удаление отчета при завершении потока}}//---------------------------------------------------------------------------//------------------------------TNotifyThread--------------------------------------//функция потока автоматического контроля файлов каталогов (переименование, добавление, удаление файлов)//работает через механизм FindFirstChangeNotification - FindNextChangeNotification.//предусмотрен механизм завершения потока - по взводу события NeverEventvoid __fastcall TNotifyThread::Execute(){THandleArray Handles=THandleArray(2);HANDLE Handle;int i;unsigned int Num;Handles.Add(NeverEvent);//поставить каталог на контроль, получить дескриптор ожиданияHandle=FindFirstChangeNotification( FForm->AddDirButton->Caption.c_str(),true,FILE_NOTIFY_CHANGE_FILE_NAME);if (Handle!=INVALID_HANDLE_VALUE) Handles.Add(Handle);while(!Terminated){//ожидание событий (NeverEvent или Handles[1..Handles.Count-1])Num=WaitForMultipleObjects(Handles.Count,&(Handles[0]),false,INFINITE);if(Num==WAIT_OBJECT_0)//взвод события NeverEvent - предполагается завершение потока{}elseif(Num>WAIT_OBJECT_0 && Num<WAIT_OBJECT_0+Handles.Count){ //взвод Handles[1..Handles.Count-1] - изменение файлов одного из каталоговNum-=WAIT_OBJECT_0;//номер сработавшего HANDLESleep(100);//подождать 100 мс//взвести DirectoryNever (для перезапуска проверки, если проверка (в другом потоке) еще не закончена)WaitForSingleObject( NeverMutex,INFINITE);DirectoryNever=true;ReleaseMutex(NeverMutex);//взвести-сбросить событие NeverEvent (для запуска проверки в потоке проверки файлов)PulseEvent(NeverEvent);//снова поставить сработавший каталог на контрольif(!FindNextChangeNotification(Handles[Num])){ //если на проверку не ставитсяFindCloseChangeNotification(Handles[Num]);Handles.Delete(Num);}}}//освободить дескрипторы ожиданияfor(i=1;i<Handles.Count;i++) FindCloseChangeNotification(Handles[i]);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------//---------------------------------------------------------------------------//---------------------------------------------------------------------------//-------------------------------TFForm--------------------------------------------//конструктор формы__fastcall TFForm::TFForm(TComponent* Owner): TForm(Owner){Report=NULL;AppClose=false;}//---------------------------------------------------------------------------//обновляет содержимое списка DirBox при выборе файла в списке NameBoxvoid __fastcall TFForm::NameBoxClick(TObject *Sender){if(Report && NameBox->ItemIndex>=0) Report->SetDirList(NameBox->ItemIndex,DirBox->Items);SetExButton->Enabled=(NameBox->Items->Count>0 && NameBox->ItemIndex>=0);ResetExButton->Enabled=(ExBox->Items->Count>0 && ExBox->ItemIndex>=0);}//---------------------------------------------------------------------------//обновляет содержимое списка DirBox при выборе файла в списке ExBoxvoid __fastcall TFForm::ExBoxClick(TObject *Sender){if(Report && ExBox->ItemIndex>=0) Report->SetDirListEx(ExBox->ItemIndex,DirBox->Items);SetExButton->Enabled=(NameBox->Items->Count>0 && NameBox->ItemIndex>=0);ResetExButton->Enabled=(ExBox->Items->Count>0 && ExBox->ItemIndex>=0);}//---------------------------------------------------------------------------//создание запуск потоков проверки и контроля файлов каталоговvoid __fastcall TFForm::CallThreads(void){DirectoryNever=false;DirThr=new TDirThread(false);NotifyThr=new TNotifyThread(false);}//---------------------------------------------------------------------------//остановка и удаление потоков проверки и контроля файлов каталоговvoid __fastcall TFForm::StopThreads(void){//взвести Terminated у обоих потоковNotifyThr->Terminate();DirThr->Terminate();//взвести-сбросить событие NeverEvent для завершения потоков (для выхода из функций ожидания)PulseEvent(NeverEvent);DirThr->WaitFor();//дождаться завершения потока DirThrdelete DirThr; //удалить DirThrNotifyThr->WaitFor();//дождаться завершения потока NotifyThrdelete NotifyThr; //удалить NotifyThr//отключить мигание надписи "Запущена проверка"Timer1->Enabled=false;Label5->Visible=false;}//---------------------------------------------------------------------------//обработчик OnActivate формы (работает только при запуске программы)//регистрирует значок в System Tray, инициализирует переменные, запускает потокиvoid __fastcall TFForm::FormActivate(TObject *Sender){NotifyData.cbSize=sizeof(NotifyData);NotifyData.hWnd=Handle;NotifyData.uID=0;NotifyData.uFlags=NIF_ICON | NIF_MESSAGE | NIF_TIP;NotifyData.uCallbackMessage=WM_SHELLMESS;NotifyData.hIcon=Application->Icon->Handle;strncpy(&(NotifyData.szTip[0]),"Контроль одноименных файлов",sizeof(NotifyData.szTip));Shell_NotifyIcon(NIM_ADD,&NotifyData);Application->Title="Контроль файлов";OnActivate=NULL;NeverMutex=CreateMutex( NULL,false,"");NeverEvent=CreateEvent( NULL,true,false,"");if( FileExists(ChangeFileExt(ParamStr(0),".inf")) )//если есть файл параметров{//прочитать файл параметровTStringList *S=new TStringList;S->LoadFromFile(ChangeFileExt(ParamStr(0),".inf"));AddDirButton->Caption=S->Strings[0]; //контролируемый каталогfor(int i=1;i<S->Count;i++) ExBox->Items->Add(S->Strings[i]);//список исключенийdelete S;}else AddDirButton->Caption=ExtractFilePath(ParamStr(0));SetExButton->Enabled=(NameBox->Items->Count>0 && NameBox->ItemIndex>=0);ResetExButton->Enabled=(ExBox->Items->Count>0 && ExBox->ItemIndex>=0);CallThreads();}//---------------------------------------------------------------------------/*Msg.LParam=512 - кнопки мыши не нажаты513, 514 - нажать, отпустить левую кнопку ..001,..010516, 517 - нажать, отпустить правую кнопку ..0100,..0101519, 520 - нажать, отпустить среднюю кнопку ..0111,..1000*///обработчик событий от значка в System Tray -//показывает всплывающее меню при щелчке мышью на значке в System Trayvoid __fastcall TFForm::WMShellMess(TMessage &Message){if(Message.WParam ==0)switch(Message.LParam){case 513:case 516:if(!SDForm->Visible) IsIconic(Application->Handle);PopupMenu1->Popup(tp.x,tp.y);PostMessage(Handle,WM_NULL,0,0);break;}}//---------------------------------------------------------------------------//обработчик сообщения от второй копии приложения - для открытия и показа главного окнаvoid __fastcall TFForm::ShowMyWin(TMessage &Message){ShowWindow(Application->Handle, SW_SHOWNORMAL);Show();}//---------------------------------------------------------------------------//обработчик пуккта всплывающего меню "Отчет, настройки программы"//открывает и показывает главное окноvoid __fastcall TFForm::N1Click(TObject *Sender){ShowWindow(Application->Handle, SW_SHOWNORMAL);Show();}//---------------------------------------------------------------------------//обработчик OnClose (при закрытии) формыvoid __fastcall TFForm::FormClose(TObject *Sender, TCloseAction &Action){Timer2->Enabled=false;if(AppClose) {//закрытие программы разрешено - выполняет деинициализирующие действияStopThreads();//остановка-удаление потоковif(Report) delete Report; //удаление отчетаCloseHandle(NeverMutex); //освобождение объектовCloseHandle(NeverEvent); //Shell_NotifyIcon(NIM_DELETE,&NotifyData); //удаление значка из System Tray//сохранение параметров в файл "FileNames.inf"TStringList *S = new TStringList();S->Add(AddDirButton->Caption);//контролируемый каталогfor(int i=0;i<ExBox->Items->Count;i++) S->Add(ExBox->Items->Strings[i]);//список исключенийS->SaveToFile(ChangeFileExt(ParamStr(0),".inf"));delete S;}else {//закрытие программы запрещено - только скрывает окноAction=caNone;Hide();ShowWindow(Application->Handle, SW_HIDE);}}//---------------------------------------------------------------------------//обработчик пуккта всплывающего меню "Закрыть программу"//взводит признак AppClose и закрывает главное окноvoid __fastcall TFForm::N2Click(TObject *Sender){if(!SDForm->Visible){AppClose=true;Close();}}//---------------------------------------------------------------------------//обработчик кнопки "Скрыть окно" - скрывает главное окноvoid __fastcall TFForm::Button1Click(TObject *Sender){Timer2->Enabled=false;Hide();ShowWindow(Application->Handle, SW_HIDE);}//---------------------------------------------------------------------------//обработчик таймера - осуществляет мигание надписи "Запущена проверка..."void __fastcall TFForm::Timer1Timer(TObject *Sender){Label5->Visible=!Label5->Visible;}//---------------------------------------------------------------------------//Обработчик кнопки AddDirButton -//открывает окно SDForm для смены контр-го каталога, и перезапускает потокиvoid __fastcall TFForm::AddDirButtonClick(TObject *Sender){AnsiString Dir=AddDirButton->Caption;if(Dir.Length() > 3) Dir.SetLength(Dir.Length()-1);SDForm->DriveComboBox1->Drive=Dir[1];SDForm->DirectoryListBox1->Directory=Dir;if(SDForm->ShowModal()==mrOk){Dir=SDForm->DirectoryListBox1->Directory;if(Dir.Length() > 3) Dir=Dir+'\\';StopThreads();AddDirButton->Caption=Dir;CallThreads();}}//---------------------------------------------------------------------------//Обработчик кнопки "Стрелка вниз" - передает файл из списка одноименных в список исключенийvoid __fastcall TFForm::SetExButtonClick(TObject *Sender){if(Report->SetEx(NameBox->ItemIndex)){Report->SetNameList(NameBox->Items);Report->SetExNames(ExBox->Items);DirBox->Items->Clear();SetExButton->Enabled=false;ResetExButton->Enabled=false;if(Report->NameList->Count>0) Panel2->Caption="Обнаружены одноименные файлы!";else Panel2->Caption="Одноименные файлы отсутствуют.";}}//---------------------------------------------------------------------------//Обработчик кнопки "Стрелка верх" - передает файл из списка исключений в список одноименных// или удаляет файл из списка исключенийvoid __fastcall TFForm::ResetExButtonClick(TObject *Sender){if(Report->ResetEx(ExBox->ItemIndex)){Report->SetNameList(NameBox->Items);Report->SetExNames(ExBox->Items);DirBox->Items->Clear();SetExButton->Enabled=false;ResetExButton->Enabled=false;if(Report->NameList->Count>0) Panel2->Caption="Обнаружены одноименные файлы!";else Panel2->Caption="Одноименные файлы отсутствуют.";}} |
РЕКЛАМА
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА | ||
© 2010 |