Федеральное агентство по образованию
Государственное образовательное учреждение высшегопрофессионального образования
«ПЕНЗЕНСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»
Кафедра «Информационная безопасность систем и технологий»
УТВЕРЖДАЮ
Зав. кафедрой ИБСТ
______________ С.Л.Зефиров
ОТЧЕТ
О КУРСОВОМ ПРОЕКТЕ
«Системное программирование для операционных систем»
Руководитель КП Н.А.Егорова
Исполнитель КП П.А.Пивоваров
Нормоконтролер Т.В.Щербакова
Пенза, 2007
/>/>/>/>/>/>Реферат
Пояснительная запискасодержит 39 с., 5 рис., 2 источника, 2 приложения.
Алгоритм, ДОКУМЕНТ, ПРИЛОЖЕНИЕ,ФАЙЛ, МАСТЕР, ОБЪЕКТ.
Целью проекта является разработка резидентнойпрограммы, контролирующую наличие одинаковых файлов на диске (в выбранныхкаталогах).
Требования к программе:
- программа должна иметь значок в SystemTray, при закрытии ее главного окна программа должна оставаться в оперативнойпамяти, но соответствующая кнопка из панели задач должна быть удалена;
- при щелчке мышью на значке программы в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 VisualC++ 6.0 и называется MFC AppWizard. MFC AppWizard создает тексты приложенийтолько с использованием библиотеки классов MFC (Microsoft Foundation Classlibrary). Таким образом, изучив язык C++ и библиотеку MFC, можно создавать своиприложения. Поэтому, используя средства автоматизированного созданияприложений, можно сократить время написания довольно сложных программ. Так, признании всех необходимых функций библиотеки MFC и WinAPI для написания программыпо заданию курсового проекта потребуется не больше пары минут. При этом вручнуюпридётся написать лишь несколько вызовов функций, а всё остальное сделает MFCAppWizard, используя возможности ClassWizard.
Сутьзадачи, поставленная в данном курсовом проекте, состоит в написании программы,которая должна осуществлять поиск одинаковых документов (по имени, размеру).
Пояснительнаязаписка должна отражать следующие этапы работы: разработку алгоритмовпрограммы, разработку пользовательского интерфейса, программную реализациюпроекта, отладку и тестирование разработанной программы, описание работы спрограммой (руководство пользователя).
1. Структура основнойпрограммы
При запуске программы на экран выводитсядиалоговое окно, на котором заданы поля для введения необходимых данных дляпоиска, поле для введения пути, кнопка «Скрыть окно», поля для выводарезультата поиска.
Описания функций модуля FMain:Имя процедуры
Определение, назначение, выполняемые функции,
используемые параметры TGlobalList::At
int __fastcall TGlobalList::At(int Index)
Это метод списка строк TGlobalList, осуществляет доступ к свойству-массиву Objects, интерпретируя его элементы как тип (int) TNameList::At
TIntArray * __fastcall TNameList::At(int Index)
Это метод списка строк TNameList, осуществляет доступ к свойству-массиву Objects, интерпретируя его элементы как тип (TIntArray *) TVerDirectory::TVerDirectory
TVerDirectory::TVerDirectory(TStrings * fExNames, AnsiString fPath, TDirThread * aOwner)
Это конструктор класса отчета. В качестве параметров принимает указатель на список строк-имен файлов исключений, путь к контролируемому каталогу, и указатель на родительский поток TVerDirectory::~TVerDirectory
TVerDirectory::~TVerDirectory(void)
Это деструктор класса отчета. Выполняет действия по удалению объектов-полей класса TVerDirectory::Clear
void __fastcall TVerDirectory::Clear(void)
Этот метод класса отчета предназначен для сброса отчета в исходное состояние – выполняется очищение всех подготовленных списков для отчета (для списка ExNames удаляются только прицепленные массивы номеров каталогов, но не сами строки) TVerDirectory::Fill
void __fastcall TVerDirectory::Fill(void)
Главный метод класса отчета для проверки контролируемых каталогов и подготовки отчета. Если проверка была прервана в связи с изменением состава файлов (взведен DirectoryNever) — проверка начинается сначала. Если проверка была прервана в связи с завершением родительского потока — выход из функции. TVerDirectory::WorkFile
bool __fastcall TVerDirectory::WorkFile(int PathNum,AnsiString Name)
Проверка-регистрация в отчете файла (по имени и номеру подкаталога). При изменении состава файлов(взведен DirectoryNever) или при завершении родительского потока — досрочный выход с результатом — false TVerDirectory::WorkDir
bool __fastcall TVerDirectory::WorkDir(AnsiString Path)
Проверка-регистрация в отчете каталога (а также его содержимого, для подкаталогов — рекурсивные вызовы). При изменении состава файлов(взведен DirectoryNever) или при завершении родительского потока — досрочный выход с результатом — false TVerDirectory::SetNameList
void __fastcall TVerDirectory::SetNameList(TStrings * DestList)
Метод класса отчета для формировки списка файлов-дубликатов в DestList TVerDirectory::SetExNames
void __fastcall TVerDirectory::SetExNames(TStrings * DestList)
Метод класса отчета для формировки списка файлов-исключений в DestList TVerDirectory::SetDirList
void __fastcall TVerDirectory::SetDirList(int NameNum,TStrings * DestList)
Метод класса отчета для формировки в DestList списка путей расположения файла номер NameNum (в списке одноименных файлов) TVerDirectory::SetDirListEx
void __fastcall TVerDirectory::SetDirListEx(int NameNum,TStrings * DestList)
Метод класса отчета для формировки в DestList списка путей расположения файла номер NameNum (в списке файлов- исключений) TVerDirectory::SetEx
bool __fastcall TVerDirectory::SetEx(int Index)
Метод класса отчета для переноса файла-дубликата из списка одноименных файлов в список файлов-исключений. Index – индекс файла-дубликата в списке одноименных файлов TVerDirectory::ResetEx
bool __fastcall TVerDirectory::ResetEx(int Index)
Метод класса отчета для переноса имени файла из списка файлов-исключений в список одноименных файлов. Если файл с данным именем отсутствует в контролируемом каталоге, или присутствует в нем в единственном числе – пользователю в соответствующем сообщении предлагается просто удалить это имя из списка исключений. Index – индекс файла в списке файлов-исключений. TDirThread::CheckStep
void __fastcall TDirThread::CheckStep(void)
Метод потока TDirThread для включения мигания надписи «Запущена проверка» TDirThread::SetLists
void __fastcall TDirThread::SetLists(void)
Этот метод потока TDirThread передает подготовленный отчет главному окну программы (с открытием и активизацией главного окна) TDirThread::Execute
void __fastcall TDirThread::Execute()
Это главная функция потока проверки файлов TDirThread. Первую проверку выполняет безусловно, последующие проверки — по взводу события NeverEvent (от потока контроля файлов TNotifyThread) TNotifyThread::Execute
void __fastcall TNotifyThread::Execute()
Это главная функция потока автоматического контроля файлов каталогов TNotifyThread (переименование, добавление, удаление файлов) работает через механизм FindFirstChangeNotification — FindNextChangeNotification. Предусмотрен механизм завершения потока — по взводу события NeverEvent. TFForm::TFForm
__fastcall TFForm::TFForm(TComponent* Owner)
Это конструктор формы TFForm TFForm::NameBoxClick
void __fastcall TFForm::NameBoxClick(TObject *Sender)
Это обработчик выбора элемента списка NameBox (одноименные файлы). Обновляет содержимое списка путей расположения выбранного файла. TFForm::ExBoxClick
void __fastcall TFForm::ExBoxClick(TObject *Sender)
Это обработчик выбора элемента списка ExBox (файлы-исключения). Обновляет содержимое списка путей расположения выбранного файла. TFForm::CallThreads
void __fastcall TFForm::CallThreads(void)
Это метод формы для создания и запуска потоков проверки и контроля файлов каталогов TFForm::StopThreads
void __fastcall TFForm::StopThreads(void)
Это метод формы для остановки и удаления потоков проверки и контроля файлов каталогов TFForm::FormActivate
void __fastcall TFForm::FormActivate(TObject *Sender)
Обработчик OnActivate формы (работает только при запуске программы). Регистрирует значок в System Tray, инициализирует переменные, загружает из файла «FileNames.inf» (если он есть) путь к контролируемому каталогу и список файлов-исключений, и запускает потоки контроля и проверки. TFForm::WMShellMess
void __fastcall TFForm::WMShellMess(TMessage &Message)
Обработчик сообщения WM_SHELLMESS от значка в System Tray — показывает всплывающее меню при щелчке мышью на значке в System Tray TFForm::ShowMyWin
void __fastcall TFForm::ShowMyWin(TMessage &Message)
Обработчик сообщения (WM_USER+2) от второй копии приложения — для открытия и показа главного окна TFForm::N1Click
void __fastcall TFForm::N1Click(TObject *Sender)
Обработчик пункта всплывающего меню «Отчет, настройки программы», открывает и показывает главное окно TFForm::FormClose
void __fastcall TFForm::FormClose(TObject *Sender, TCloseAction &Action)
Обработчик OnClose (при закрытии) формы. При попытке закратия главного окна пиктограммой – только скрывает окно, а при выходе из программы (AppClose=true) – перед закрытием выполняет действия по освобождению памяти и занятых ресурсов, а также сохраняет параметры (контролируемый каталог и список исключений) в файл «FileNames.inf». TFForm::N2Click
void __fastcall TFForm::N2Click(TObject *Sender)
Обработчик пуккта всплывающего меню «Закрыть программу», взводит признак AppClose и закрывает главное окно TFForm::Button1Click
void __fastcall TFForm::Button1Click(TObject *Sender)
Обработчик кнопки «Скрыть окно» — скрывает главное окно TFForm::Timer1Timer
void __fastcall TFForm::Timer1Timer(TObject *Sender)
Обработчик таймера — осуществляет мигание надписи «Запущена проверка...» TFForm::AddDirButtonClick
void __fastcall TFForm::AddDirButtonClick(TObject *Sender)
Обработчик кнопки AddDirButton — открывает окно SDForm для смены контролируемого каталога, и перезапускает потоки TFForm::SetExButtonClick
void __fastcall TFForm::SetExButtonClick(TObject *Sender)
Обработчик кнопки SetExButton (стрелка вниз) — передает файл из списка одноименных в список исключений TFForm::ResetExButtonClick
void __fastcall TFForm::ResetExButtonClick(TObject *Sender)
Обработчик кнопки ResetExButton (стрелка верх) — передает файл из списка исключений в список одноименных файлов или удаляет файл из списка исключений 2. Программнаяреализация алгоритма
При создании программы необходимо запустить средупрограммирования Microsoft Visual C++ 6.0.
Для использования MFC AppWizard необходимо выполнитьследующие действия: в главном меню выбирается пункт File и подпункт New. В появившемсядиалоговом окне нужно перейти на вкладку Project и выбрать MFCAppWizard. Затем в поле Project name нужно указать имяпроекта (в данном курсовом проекте имя Crazzyff) и нажать кнопку Ok. Далее появитсядиалоговое окно первого шага MFC AppWizard Step1. В нём нужно указатьтип создаваемого приложения Dialog based и нажать кнопку Next. На следующем шаге MFC AppWizard Step2 флажки на пунктах About box и 3D controls.В следующем окне MFC AppWizard Step3 требуется поставитьпереключатель на тип проекта MFC Standard и нажать кнопку Next. На четвёртом шаге можнопросмотреть создаваемые классы и нажать кнопку Finish. Далее в окне New ProjectInformation нужно нажать кнопку Ok. После этого проект будетсоздан и появится окно созданного проекта. В этом окне будут присутствоватьследующие элементы: кнопки Ok и Cancel и статический текст. С помощью мыши можноизменить размер окна. Также можно переместить статический текст на требуемуюпозицию.
Список модулей проекта:FileNames.cpp
Главный модуль программы.
В сгенерированный автоматически код добавлена защита от запуска второй копии приложения.
ArrayTemplate.h
ArrayTemplate.cpp Этот модуль реализует шаблон на динамические массивы со свойствами списка (коллекции).
FSelectDirForm.h
FSelectDirForm.cpp Реализация формы выбора каталога. (код сгенерирован автоматически).
FMain.h
FMain.cpp
Реализация формы главного окна приложения.
Основная часть кода находится здесь.
Описанные (вручную) типы:TArray шаблон на динамический массив со свойствами списка элементов (коллекции) TIntArray
динамический массив с элементами int
(на основе TArray) THandleArray
динамический массив с элементами HANDLE (void *)
(на основе TArray) TGlobalList тип-список строк для хранения имен файлов, а также номеров каталогов (в списке каталогов) для каждого имени TNameList тип-список строк для хранения имен файлов-дубликатов (файлов-исключений), а также указателей на массивы номеров каталогов (TIntArray *) для каждого файла-дубликата TDirThread тип-поток для проверки каталогов и подготовки отчета по одноименным файлам TNotifyThread тип-поток для автоматического контроля проверяемых каталогов — при переименовке, добавлении и удалении файлов в данных каталогах (или их подкаталогах) инициирует проверку каталогов с подготовкой отчета TVerDirectory тип-подготавливаемый отчет по одноименным файлам, с набором методов для подготовки отчета. 3. Исходныйтекст программы приведен в приложении Б4. Функциональныевозможности программы
Программа осуществляет поиск одинаковыхдокументов по имени и размеру. В программе предусмотрена защита от запускавторой копии приложения. При запуске второй копии приложения – она открывает иактивизирует главное окно первой копии, и завершает работу.
Необходимо отметить, что программа хранит своипараметры (путь к контролируемому каталогу и список исключений) в файле«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++. Исходя из того, что программаполностью соответствует заданию курсового проекта, можно сделать вывод, чтозадание на курсовую работу выполнено в полном объеме.
Список использованных источников
1. МайклХаймен, Боб Арнсон. Visual C++: Учеб. Пособие. – М.: Диалектика, 2002. – 289 с.: ил.
2. А.Корера, С. Фрейзер, С. Маклин, Н. Кумар, С. Робинсон, П.Г. Саранг, С. Джентайл.Visual C++. Пособие дляразработчиков. Изд-во «Лори», 2003. – 417 с.: ил.
Приложение А(ОБЯЗАТЕЛЬНОЕ)Основнойалгоритм программы/>
Рисунок А.1 – Основнойалгоритм программы
Вышеуказанный алгоритмосновной программы реализует защиту от запуска второй копии приложения. Есликопия приложения уже запущена (найдены ее окна) – программа активизирует своюпредыдущую копию и завершает работу, иначе – стандартное выполнение программы.
/>
Рисунок А.2 – Алгоритм проверки регистрации по имени иномеру подкаталога
Вышеуказанный алгоритм реализует проверку ирегистрацию файла в отчете. Этот метод отчета применяется к каждому найденномуфайлу в контролируемых каталогах.
/>
Рисунок А.3 – Главная функция для проверки каталогов иподготовки отчета
Вышеуказанный алгоритм реализует полный механизмпроверки контролируемых каталогов и подготовки отчета. В алгоритмепредусмотрены механизмы для досрочного завершения проверки по признакузавершения родительского потока, а также перезапуск проверки по признакуизменения файлов (от потока контроля файлов)
/>
Рисунок А.4 – Главная функция потока проверки файлов
Вышеуказанныйалгоритм реализует работу потока проверки файлов. Вызовы методов потокаCheckStep и SetLists синхронизируются с главным VCL-потоком программы. Проверкафайлов с передачей отчета главному окну программы инициируется взведениемсобытия NeverEvent — потоком контроля файлов по факту изменения состава файлов.Также предусмотрен механизм завершения потока – взведением свойства Terminatedи события NeverEvent.
Приложение Б(ОБЯЗАТЕЛЬНОЕ)Листингипрограммы
Файл проекта FileNames.cpp
//---------------------------------------------------------------------------
#include
#pragmahdrstop
//---------------------------------------------------------------------------
USEFORM(«FMain.cpp»,FForm);
USEFORM(«FSelectDirForm.cpp»,SDForm);
//---------------------------------------------------------------------------
WINAPIWinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
try
{
//защита от повторногозапуска
HWND w=FindWindow(«TFForm»,«Контрольодноименных файлов»),
w2=FindWindow(«TSDForm»,«Выборкаталога»);
if(w) {//при обнаружениизапущенной копии приложения — активизирует
//ее главное окно изавершает работу
if(IsWindowVisible(w)){
if(w2&& IsWindowVisible(w2)) SetForegroundWindow(w2);
elseSetForegroundWindow(w);
}
elsePostMessage(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
{
throwException("");
}
catch(Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------
ФайлArrayTemplate.h
//---------------------------------------------------------------------------
#ifndef ArrayTemplateH
#define ArrayTemplateH
//---------------------------------------------------------------------------
//шаблон на динамическиймассив со свойствами коллекции(списка элементов)
template class TArray
{
private:
int fCount,fLength; //кол-воэлементов, размер массива
T *fItems; //указатель на массив
protected:
T __fastcallGet(int Index); //чтение элемента массива
void__fastcall Put(int Index, T Item); //запись элемента массива
void__fastcall SetCount(int NewCount); //установка fCount
public:
TArray(intaLength); //конструктор
~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 TItems[int Index] = {read=Get, write=Put}; //свойство для доступа к элементу
__property intCount = {read=fCount, write=SetCount}; //свойство для доступа к кол-вуэлементов списка
__property intLength = {read=fLength, write=SetLength};//свойство для доступа к размерумассива
};
template TArray::TArray(int aLength)
{
fCount=0;
fLength=0;
SetLength(aLength);
}
template TArray::~TArray(void) { SetLength(0); }
template T& TArray::operator[](int Index) { returnfItems[Index];}
template void* TArray::operator&(void) {return fItems;}
template T __fastcall TArray::Get(int Index) { returnfItems[Index]; }
template void __fastcall TArray::Put(int Index, T Item) {fItems[Index]=Item; }
template void __fastcall TArray::Add(T Item){Insert(fCount,Item); }
template void __fastcall TArray::Clear(void) { fCount=0; }
template void __fastcall TArray::SetCount(int NewCount)
{
fCount=NewCount;
if(fCount
if(fCount>fLength)fCount=fLength;
}
template void __fastcall TArray::Insert(int Index,T Item)
{
if(IndexfCount) return;
if(fCount==fLength) SetLength(fLength+5);
if(Index
fItems[Index]=Item;
fCount++;
}
template void __fastcall TArray::Delete(int Index)
{
if(IndexfCount-1) return;
if(Index
fCount--;
//if(fCount==fLength-6) SetLength(fCount+1);
}
template void __fastcall TArray::SetLength (int NewLen)
{
if(NewLen
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
}
//динамические массивы (сэлементами int и HANDLE)
typedefTArray TIntArray;
typedefTArray THandleArray;
#endif
ФайлArrayTemplate.cpp
//---------------------------------------------------------------------------
#pragmahdrstop
#include
#include«ArrayTemplate.h»
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
Файл FSelectDirForm.h
//---------------------------------------------------------------------------
#ifndefFSelectDirFormH
#defineFSelectDirFormH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include
//---------------------------------------------------------------------------
class TSDForm: public TForm
{
__published: //IDE-managed Components
TButton*Button1;
TButton *Button2;
TDirectoryListBox*DirectoryListBox1;
TDriveComboBox*DriveComboBox1;
private: //User declarations
public: //User declarations
__fastcallTSDForm(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGETSDForm *SDForm;
//---------------------------------------------------------------------------
#endif
ФайлFSelectDirForm.cpp
//---------------------------------------------------------------------------
#include
#pragmahdrstop
#include«FSelectDirForm.h»
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragmaresource "*.dfm"
TSDForm*SDForm;
//---------------------------------------------------------------------------
__fastcallTSDForm::TSDForm(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
Файл FMain.h
//---------------------------------------------------------------------------
#ifndef FMainH
#define FMainH
//---------------------------------------------------------------------------
#include
#include
#include
#include
#include«ArrayTemplate.h»
#include
#include
#include
//---------------------------------------------------------------------------
//используемые кодысообщений
#defineWM_SHELLMESS (WM_USER + 1) //от значка в System Tray
#define WM_SHOWMYWIN (WM_USER + 2) //от второй копиипрограммы
//тип-список строк дляхранения имен файлов, а также номеров каталогов
//(в списке каталогов)для каждого имени
classTGlobalList:public TStringList
{
public:
int __fastcall At(int Index); //доступ к номерукаталога для выбранного файла
};
//тип-список строк дляхранения имен файлов-дубликатов, а также указателей
//на массивы номеровкаталогов (TIntArray *) для каждого файла-дубликата
classTNameList:public TStringList
{
public:
TIntArray * __fastcall At(int Index); //доступ к массивуномеров для выбранного файла
};
//предварительноеобъявление
class TVerDirectory;
//тип-поток для проверкикаталогов и подготовки отчета по одноименным файлам
classTDirThread:public TThread
{
protected:
void__fastcall Execute(); //главная функция потока
public:
TVerDirectory*Report; //подготавливаемый отчет
__fastcallTDirThread(bool CreateSuspended):TThread(CreateSuspended) {} //конструктор
void __fastcall SetLists(void); //передача отчетаглавному окну программы
void __fastcall CheckStep(void); //отмечает в главномокне начало проверки каталогов
boolTerm(void) {return Terminated;} //возвращает Terminated(protected — свойство)
};
//тип-поток дляавтоматического контроля проверяемых каталогов -
// при переименовке,добавлении и удалении файлов в данных каталогах (или их подкаталогах)
// инициирует проверкукаталогов с подготовкой отчета
classTNotifyThread:public TThread
{
protected:
void__fastcall Execute(); //главная функция потока
public:
__fastcallTNotifyThread(bool CreateSuspended):TThread(CreateSuspended) {}//конструктор
bool Term(void){return Terminated;} //возвращает Terminated(protected — свойство)
};
//тип-подготавливаемыйотчет
classTVerDirectory
{
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 в 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 __fastcallExBoxClick(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; //поток автоматическогоконтроля каталогов
TNotifyIconData NotifyData; //структура длярегистрации значка в System Tray
bool AppClose; //признак выхода изпрограммы
__fastcall TFForm(TComponent* Owner);//конструктор
void __fastcall CallThreads(void); //создание и запускпотоков контроля и проверки каталогов
void __fastcall StopThreads(void); //завершение иудаление потоков контроля и проверки каталогов
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(WM_SHELLMESS,TMessage, WMShellMess)
MESSAGE_HANDLER(WM_SHOWMYWIN,TMessage, ShowMyWin)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGETFForm *FForm;
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
#endif
Файл FMain.cpp
//---------------------------------------------------------------------------
#include
#pragmahdrstop
#include«FMain.h»
#include«FSelectDirForm.h»
//---------------------------------------------------------------------------
#pragmapackage(smart_init)
#pragmaresource "*.dfm"
TFForm *FForm;
bool DirectoryNever; //признак необходимостиперезапуска проверки каталогов
void *NeverMutex, //мъютекс длясинхронизации доступа к DirectoryNever (для записи)
*NeverEvent; //событие длясинхронизации потоков проверки файлов и контроля файлов
//---------------------------------------------------------------------------
//------------------------TGlobalList,TNameList---------------------------------
int __fastcallTGlobalList::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= newTStringList();
GlobalList =new TGlobalList(); GlobalList->Sorted=true;
NameList = newTNameList(); NameList->Sorted=true;
ExNames = newTNameList(); ExNames->Sorted=true;
ExNames->AddStrings(fExNames);
}
//---------------------------------------------------------------------------
TVerDirectory::~TVerDirectory(void)
{
Clear();
deleteDirList;
deleteGlobalList;
deleteNameList;
deleteExNames;
}
//---------------------------------------------------------------------------
void__fastcall TVerDirectory::Clear(void)
{
for(int i=0;iCount;i++) delete NameList->At(i);
for(int i=0;iCount;i++)
if(ExNames->At(i) != NULL)
{
deleteExNames->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 = newTIntArray(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 = newTIntArray(3);
T->Add(GlobalList->At(i));
T->Add(PathNum);
//включить файл в списокодинаковых
NameList->AddObject(Name,(TObject*)T);
}
}
elseGlobalList->AddObject(Name,(TObject *)PathNum);//включить файл в общийсписок
}
//выход
return true;
}
//---------------------------------------------------------------------------
//проверка-регистрация вотчете каталога (а также его содержимого, для подкаталогов — рекурсивныевызовы)
//при изменении составафайлов(взведен DirectoryNever) или при завершении
//родительского потока — досрочный выход с результатом — false
bool__fastcall TVerDirectory::WorkDir(AnsiString Path)
{
//выход принеобходимости
if(DirectoryNever || Owner->Term() ) return false;
TSearchRecSRec;
boolResult=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);
elseFList->Add(SRec.Name);
}
}while(FindNext(SRec)==0);
FindClose(SRec);
//обработка себя самого
DirList->Add(Path);
//обработкафайлов
for(inti=0;iCount;i++)
if(!WorkFile(DirList->Count-1,FList->Strings[i])){Result=false;break;}
delete FList;
//обработкаподкаталогов
if(Result)
for(inti=0;iCount;i++)
if(!WorkDir(Path+DList->Strings[i]+"\\")) {Result=false;break;};
delete DList;
//выход
return Result;
}
//---------------------------------------------------------------------------
void__fastcall TVerDirectory::SetNameList(TStrings * DestList)
{
DestList->Clear();
for(inti=0;iCount;i++) DestList->Add(NameList->Strings[i]);
}
//---------------------------------------------------------------------------
void__fastcall TVerDirectory::SetExNames(TStrings * DestList)
{
DestList->Clear();
for(inti=0;iCount;i++) DestList->Add(ExNames->Strings[i]);
}
//---------------------------------------------------------------------------
void__fastcall TVerDirectory::SetDirList(int NameNum,TStrings * DestList)
{
DestList->Clear();
for(inti=0;iAt(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(inti=0;iAt(NameNum)->Count;i++)
DestList->Add(DirList->Strings[ExNames->At(NameNum)->Items[i]]);
}
//---------------------------------------------------------------------------
bool__fastcall TVerDirectory::SetEx(int Index)
{
if(Index>=0&& IndexCount)
{
ExNames->AddObject(NameList->Strings[Index],NameList->Objects[Index]);
NameList->Delete(Index);
return true;
} else returnfalse;
}
//---------------------------------------------------------------------------
bool __fastcallTVerDirectory::ResetEx(int Index)
{
if(Index>=0&& IndexCount)
{
if(ExNames->At(Index)==NULL)
{
if(Application->MessageBoxA(((AnsiString)«Выбранныйфайл отсутствует в контролируемом каталоге.\n»+
«Удалить его изсписка исключений?»).c_str(),«Предупреждение»,MB_YESNO | MB_ICONWARNING)==IDYES)
{
ExNames->Delete(Index);
return true;
}
} else
if(ExNames->At(Index)->Count==1)
{
if(Application->MessageBoxA(((AnsiString)«Выбранный файл вконтролируемом каталоге присутствует в единственном числе.\n»+
«Удалить его изсписка исключений?»).c_str(),«Предупреждение»,MB_YESNO | MB_ICONWARNING)==IDYES)
{
deleteExNames->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;
boolFirst=(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=«Обнаруженыодноименные файлы!»;
elseFForm->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)
{
//создатьReport
Report=newTVerDirectory( FForm->ExBox->Items,FForm->AddDirButton->Caption,this);
//сброситьDirectoryNever
WaitForSingleObject(NeverMutex,INFINITE);
DirectoryNever=false;
ReleaseMutex(NeverMutex);
//отметитьначало проверки
Synchronize(CheckStep);
//проверка
Report->Fill();
if (!Terminated)//если поток не завершен
{
//передать отчет главномуокну
Synchronize(SetLists);
//ожиданиевзвода события NeverEvent
WaitForSingleObject(NeverEvent,INFINITE);
}
else delete Report;//удаление отчета призавершении потока
}
}
//---------------------------------------------------------------------------
//------------------------------TNotifyThread--------------------------------------
//функция потокаавтоматического контроля файлов каталогов (переименование, добавление, удалениефайлов)
//работаетчерез механизм FindFirstChangeNotification — FindNextChangeNotification.
//предусмотрен механизмзавершения потока — по взводу события NeverEvent
void__fastcall TNotifyThread::Execute()
{
THandleArrayHandles=THandleArray(2);
HANDLE Handle;
int i;
unsigned intNum;
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 — предполагаетсязавершение потока
{}else
if(Num>WAIT_OBJECT_0&& Num
{ //взвод Handles[1..Handles.Count-1] — изменение файловодного из каталогов
Num-=WAIT_OBJECT_0;//номер сработавшего HANDLE
Sleep(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
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//-------------------------------TFForm--------------------------------------------
//конструкторформы
__fastcallTFForm::TFForm(TComponent* Owner)
: TForm(Owner)
{
Report=NULL;
AppClose=false;
}
//---------------------------------------------------------------------------
//обновляет содержимоесписка DirBox при выборе файла в списке NameBox
void__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 при выборе файла в списке ExBox
void__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 __fastcallTFForm::CallThreads(void)
{
DirectoryNever=false;
DirThr=newTDirThread(false);
NotifyThr=new TNotifyThread(false);
}
//---------------------------------------------------------------------------
//остановка и удалениепотоков проверки и контроля файлов каталогов
void__fastcall TFForm::StopThreads(void)
{
//взвестиTerminated у обоих потоков
NotifyThr->Terminate();
DirThr->Terminate();
//взвести-сброситьсобытие NeverEvent для завершения потоков (для выхода из функций ожидания)
PulseEvent(NeverEvent);
DirThr->WaitFor();//дождаться завершенияпотока DirThr
delete DirThr; //удалить DirThr
NotifyThr->WaitFor();//дождаться завершенияпотока NotifyThr
delete 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(inti=1;iCount;i++) ExBox->Items->Add(S->Strings[i]);//списокисключений
delete S;
}
elseAddDirButton->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,..010
516, 517 — нажать,отпустить правую кнопку ..0100,..0101
519, 520 — нажать,отпустить среднюю кнопку ..0111,..1000
*/
//обработчик событий отзначка в System Tray -
//показывает всплывающееменю при щелчке мышью на значке в System Tray
void__fastcall TFForm::WMShellMess(TMessage &Message)
{
if(Message.WParam==0)
switch(Message.LParam)
{
case 513:
case516:if(!SDForm->Visible)
{
TPoint tp;
SetForegroundWindow(Handle);
GetCursorPos(&tp);
N1->Enabled=!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(inti=0;iItems->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)
{
AnsiStringDir=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=«Одноименные файлыотсутствуют.»;
}
}