Пора копнуть поглубже…
Для начала хорошая новость: хочется надеяться, что Borland всё-таки не окончательно "кинула" разработчиков на C++ Builder . Кажется, теперь Delphi и C++ Builder сольются, наконец, в экстазе.
Эта и несколько последующих статей ценны, в основном, большим количеством кода, который может пригодиться.
Приступаю к описанию системных компонентов с закладки "ASK Tools". В первой статье я агитировал за то, что обработка любых ошибок и нештатных ситуаций времени исполнения должна быть единообразной и должна использовать только механизм исключений (Exceptions). Все выгоды такой унификации описаны там же.
Исходим из предположения, что мы проделали большую работу по обёртке всех C и API-вызовов в свои классы с "исключительной" обработкой ошибок. Теперь программа не "валится" без объяснений в нештатной ситуации. Пришло время, наконец, снять сливки с наших трудов.
Как всегда, хочется большего: чтобы все проблемы, возникающие во время выполнения программы, протоколировались. Протокол должен быть содержательным в той мере, которая поможет разработчику устранить проблему. Ещё надо бы иметь средство визуализации протокола сбоев. Ну и, конечно, хотелось бы, чтобы для включения этой замечательной функциональности в каждом новом проекте, не пришлось напрягаться.
Общий план реализации таков. Компонент TAskExceptionHandler "бросается" на главную форму приложения. На этом, собственно, "ручное кодирование" заканчивается. Компонент перехватывает все исключения и "вываливает" их в лог-файл, после чего исключение обрабатывается стандартным образом. Если вам понадобится раскрыть более полно информацию об исключении особо хитрого типа, вы всегда сможете включить обработку этого типа в метод LogExceptionState.
В момент возникновения исключений делается "снимок состояния" системы, который также регистрируется в лог-файле вместе с событием. Лог-файл имеет структуру ini-файла и имя, сформированное по имени приложения.
Образец прилагается.
[12.11.2004 16:06:47] ExceptionType=EToFile ExceptionMess=Ошибка записи в файл ToFileFileName=A:\big_file.txt ToFileErrNo=28 ToFileDosErrNo=112 ToFileErrNoStr=Недостаточно места на устройстве ToFileDosErrNoStr= not enough space on the disk ClassName=FormOptions (TFormOptions) FormName=FormOptions (TFormOptions) ProgramVersion=1.0.0.0 TotalVirtMem=2047 AvailVirtMem=2000 TotalPageMem=1228 AvailPageMem=895 DiskC_Total=76316 DiskC_Free=41916
Компонент, естественно, использует классы из упоминавшейся библиотеки классов (IniFile, ToFile), а также некоторые компоненты, речь о которых пойдёт ниже. Также используются файлы текстовых ресурсов – для формирования сообщений на языке пользователя.
Пример использования. Функция CreateVeryBigFile создаёт ситуацию нехватки дискового пространства. Файловая ошибка (спасибо нашему классу-обёртке) преобразуется в исключение, которое перехватывается компонентом, выводится в лог-файл, и далее обрабатывается стандартным образом.
void CreateVeryBigFile() {
ToFile w("w", "A:\\big_file.txt");
while(1) w.fprintf("Очень-очень большой файл…\n");
}
Результат работы "перехватчика исключений" можно рассмотреть с помощью стандартной . Библиотека форм общего назначения также является ресурсом и представляет собою отдельную DLL, которая будет описана в последующих статьях.
Как уже говорилось, благодаря такой организации обработки ошибок, программы не "валятся" без объяснений причин. Протокол работы помогает выявить и устранить многие проблемы времени выполнения. Более того, можно организовать отсылку протоколов разработчику – через e-mail или FTP – для удалённой диагностики проблем и выпусков патчей.
Кстати, перехват ошибок файловой системы весьма помогает при работе с устаревшими Windows 9x, в которых часто возникают сбои в FAT.
TAskExceptionHandler использует несколько компонентов с закладки "ASK SysInfo", на которую мы плавно переместимся. Знакомьтесь: TAskOS.
Не секрет, что в процессе разработки программ часто бывает необходимо определить версию Windows, под управлением которой выполняется программа. На разных форумах довольно много подобных вопросов от новичков. Свойства компонента:
Компонент TAskOS, как и все остальные с этой закладки, имеет метод Refresh(), который вызывается автоматически, если компонент лежит на форме. То есть, после создания формы все свойства компонента уже содержат правильные значения и готовы к использованию. А вот если компонент создаётся динамически в куче, следует вызвать этот метод вручную для инициализации свойств.
Также многие компоненты имеют свойство bRefresh. Если этому свойству во время проектирования присвоить значение "true", то будет вызван метод Refresh и значения свойств можно будет увидеть в инспекторе объектов.
Компонент TAskComputer инкапсулирует следующие свойства:
Компонент TAskProcessor имеет следующие полезные свойства:
Компонент TAskDisplay.
Компонент TAskKeyboard.
Именно с помощью этого компонента выставляются клавиатурные свойства у компонентов TAskEdit, TAskMaskEdit, TAskRxCalcEdit, TAskCurrencyEdit, TAskComboBox, TAskMemo из предыдущей статьи.
Компонент TAskPrinter. Я не настаиваю на общественной полезности этого компонента; просто в последующих статьях он будет упоминаться, поэтому он и описан здесь.
Основные функции.
Компонент TAskDisk предоставляет наиболее употребимую информацию о логических дисках.
Здесь используется файл строковых ресурсов, о котором говорилось в первой статье.
Компонент TAskListDisks содержит список всех логических дисков.
Компонент TAskCard – описание карты (платы).
Компонент TAskShutdown несколько выбивается из ряда компонентов, предоставляющих информацию о системе. Он предназначен для удобного "гашения" Windows и обладает следующими свойствами:
Ну, и на сладкое – компонент TAskSysInfo, являющийся контейнером компонентов: TAskOS * OS, TAskCPU * CPU, TAskListDisks * ListDisks, TAskComputer * Computer, TAskKeyboard * Keyboard, TAskDisplay * Display, TAskCard * NetworkCard, TAskCard * SoundCard, TAskCard * SCSICard.
Помимо этого, компонент обладает следующими свойствами:
Кроме того, у компонента TAskSysInfo есть 2 события:
Результат работы компонента во время проектирования представлен на рисунках , , , , , .
Результат работы компонента во время выполнения представлен на рисунке , которая также лежит в DLL форм общего назначения. Подключение этой и любых других DLL к любому проекту осуществляется двумя кликами мышки с помощью методов, описанных в грядущем продолжении цикла статей.
Скачать архив (35K)
1