Страница 13 из 42 Объект Application TApplication = class(TComponent) На уровне методов и свойств этого компонента осуществляется управление выполняемым приложением. Он отсутствует в Палитре компонентов, и все его свойства должны изменяться из программы. Поводов для обращения к TApplication может быть два. Во-первых, это получение информации о приложении, общей для всех ее форм. Во-вторых, это управление процессом выполнения приложения и входящими в него формами. Эти методы тесно связаны с Windows, и работа с многими из них требует определенного опыта. К информационным могут быть отнесены следующие свойства: property Title: string; | Имя приложения. Под этим именем оно отображается в TaskManager, TaskBar и т. п. По умолчанию равно имени проекта. | (Ro) property ExeName: string; | Имя файла с расширением .ЕХЕ, содержащего приложение (то же самое имя возвращает функция ParamStr(0)). | property Icon: TIcon; | Значок приложения. Первоначально, при запуске, значок загружается из ресурса с именем MAINICON в файле ресурсов проекта. | Теперь рассмотрим методы и свойства в последовательности, соответствующей "жизненному циклу" приложения. При запуске на выполнение Application сначала создает и инициализирует формы приложения при помощи метода: procedure CreateForm(FormClass: TFormClass; var Reference); Параметр Reference будет указывать на созданный экземпляр формы класса FormClass. С обращений к этому методу начинается код, содержащийся в файле с расширением .DPR; при этом в нем создаются только те формы, которые содержатся в списке Auto-Create Forms в опциях проекта. Метод работает таким образом, что в случае, если указатель на главную форму равен nil, то созданная форма становится главной. Из этого следует, что главной всегда будет первая из создаваемых форм. Указатель на нее описан в свойстве: (Ro) property MainForm: TForm; Здесь нужно сделать специальную оговорку. Помимо главной и других форм у приложения есть еще одно — невидимое — окно. Именно оно является по-настоящему главным и именно в нем обрабатываются все сообщения Windows, управляющие состоянием приложения. Его дескриптор доступен в свойстве: property Handle: HWnd; После создания всех форм метод procedure Run; запускает цикл обработки сообщений главной формы приложения. Его код очень прост и выглядит следующим образом: procedure TApplication.Runt-begin AddExitProc(DoneApplication); if FMainForm о nil then begin FMainForm.Visible := True; repeat HandleMessage until Terminated; end; end; Вызываемый в нем метод procedure HandleMessage; извлекает следующее сообщение из очереди и передает его на обработку следующим образом: procedure TApplication.HandleMessage; begin if not ProcessMessage then Idle; end; Метод ProcessMessage ищет нужный обработчик сообщения и передает ему управление. Назначение метода Idle поясняется ниже. О поступлении сообщения оповещает вызов обработчика события: property OnMessage: TMessageEvent; TMessageEvent = procedure (var Msg: TMsg; var Handled: Boolean) of object; Используя обработку OnMessage, программист может переопределить обработку любого (или любых) сообщений (кроме WM_QUIT и сообщений системы оперативной подсказки). Для этого, выполнив внутри метода необходимые действия, в параметре Handled нужно вернуть True. Тогда сообщение не поступит в функцию окна приложения. Необходимо быть крайне осторожным, подменяя системные обработчики сообщений. Существует другой способ перехвата сообщений. Для этого нужно написать метод, имеющий следующий rim TWindowHook = function (var Message: TMessage): Boolean of object; и зарегистрировать его в качестве перехватчика сообщений приложения с помощью метода: procedure HookMainWindowfHook: TWindowHook); Если одна из процедур-перехватчиков типа TWindowHook в цепочке вернет True, это будет означать, что сообщение обработано. Когда необходимость в перехвате сообщений отпадет, созданный вами метод нужно исключить из списка при помощи вызова метода: procedure UnhookMainWindow(Hook: TWindowHook); Если сообщений в очереди нет, то может быть выполнена "фоновая" работа, предусмотренная программистом. Для этого нужен обработчик события, которое генерируется в этой ситуации внутри метода Idle в HandleMessage: property Onldle: TIdleEvent; TIdleEvent = procedure (Sender: TObject; var Done: Boolean) of object; Обработчик должен вернуть признак потребности в последующих событиях Onldle в булевом параметре Done. Если "все сделано" и он присваивает Done значение True, то приложение переходит в режим ожидания сообщения и обработчик не вызывается до возникновения следующей ситуации отсутствия сообщений в очереди. Если возвращается значение False, метод будет вызываться все время при отсутствии сообщений. Пример обработки сообщений OnMessage и Onldle имеется на дискете (название проекта MOVLINES). Их использует программа сохранения экрана, которая вызывается системой по истечении некоторого времени, в обработчике Onldle она рисует на экране линии и прекращает работу, когда обработчик OnMessage получает сообщение от мыши или клавиатуры. Как видно из приведенного кода метода Run, сообщения обрабатываются вплоть до установки флага: (Ro) property Terminated: Boolean; Такой флаг устанавливается при получении собщения WM_QUIT. Используя его, можно вставить свои действия на завершающем этапе (после окончания обработки сообщений перед вызовом деструктора Application). Свойство это доступно только для чтения, поэтому завершить приложение можно, вызвав метод procedure Terminate; который и посылает сообщение WM_QUIT. Для обработки сообщений предназначен также метод procedure ProcessMessages; который возвращает управление тогда, когда обработаны все сообщения в очереди. Пример: procedure TApplication.ProcessMessages; begin while ProcessMessage do; end; Одна или более форм приложения могут иметь статус fsStayOnTop, то есть постоянно находятся поверх других форм (не имеющих этого статуса). Для того, чтобы на время отключить его действие, применяется пара методов: procedure Normal!zeTopMosts; — отключает статус; procedure RestoreTopMosts; — восстанавливает его. Эти методы могут быть полезными, когда необходимо вывести информацию поверх формы со статусом fsStayOnTop. В самом объекте Application они вызываются соответственно при деактивизации/актнвизации приложения, сво-рачивании/разворачивании главной формы. |