ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 9

Глава 8. Объекты приложения
Первое требование к приложению ObjectWindows состоит в определении объекта приложения, который был бы производным от абстрактного типа TApplication. Объект приложения будет обладать следующими характеристиками приложения ObjectWindows:
- Создание и отображение головного окна приложения.
- Инициализация каждого экземпляра приложения, например, для загрузки таблицы акселераторов. (Вы можете одновременно запустить несколько экземпляров одного приложения ObjectWindows.)
- Инициализация первого экземпляра приложения для любой задачи,   которая будет обслуживать все экземпляры приложения, например,   конфигурирование коммуникационного порта.
- Обработка принимаемых приложением сообщений Windows.
- Закрытие приложения.
Кроме определения типа, происходящего от TApplication, вы должна добавить ему способность конструировать объект головного окна. У вас также имеется возможность усовершенствовать поведение по умолчанию объектов инициализации, закрытие приложения и обработ
ку сообщений Windows.
Управление потоком приложений
Приведем минимальный текст головной программы ObjectWindows:
program MinimalApp;
uses WObjects;
var
 MyApp: TApplication;
begin
 MyApp.Init('TestApp');
 MyApp.Run;
 MyApp.Done;
end.
Данная программа, MinimalApp, является абсолютно минимальным приложением ObjectWindows, и не требует определений новых типов объектов. Однако, вы будете определять новые типы объектов по крайней мере для приложения и головного окна.
Объект приложения конструируется в головной программе приложения ObjectWindows. К нему может быть осуществлен доступ из других частей программы ObjectWindows через ссылку на глобальную переменную, Application, в которой он также хранится.
Головная программа вашего приложения ObjectWindows обычно состоит лишь из трех операторов.
Первый оператор конструирует объект приложения путем вызова его конструктора Init. Init также инициализирует поля данных объекта приложения, затем вызывает InitApplication и InitInstance, которые соответственно выполняют инициализацию первого и остальных
 экземпляров. Для создания головного окна вызывается InitMainWindow. На этом работа Init заканчивается и на экране появляется головное окно вашего приложения. В большинстве случаев вам нужно переопределить только InitMainWindow (см.Рис.8.1). 
Следующий оператор вызывает метод приложения Run, который запускает выполнение приложения путем вызова MessageLoop для начала обработки поступающих сообщений Windows, которые руководят действиями приложения. MessageLoop вызывает методы, которые обрабатыв
ают конкретные поступающие сообщения. MessageLoop это действительно цикл сообщений, который продолжает свою работу до закрытия приложения.
Done это деструктор объектов приложения, который высвобождает память объектов приложения до прекращения его работы.
    ЪДДДДї    ЪДДДДДДДДДДДДДДДї
    іInitГДВДДґInitApplicationі
    АДДДДЩ і  АДДДДДДДДДДДДДДДЩ
           і
           і  ЪДДДДДДДДДДДДДДДї        ЪДДДДДДДДДДДДДДї
           АДДґInitInstance   ГДДДДДДДДґInitMainWindowі
              АДДДДДДДДДДДДДДДЩ        АДДДДДДДДДДДДДДЩ
    ЪДДДДї    ЪДДДДДДДДДДДДДДДї
    іRun ГДДДДґMessageLoop    і
    АДДДДЩ    АДДДДДДДДДДДДДДДЩ
    ЪДДДДї
    іDoneі
    АДДДДЩ
Рис.8.1. Вызовы методов, которые управляют выполнением приложения
Инициализация приложений
Последовательность вызовов методов, которые инициализируют выполнение приложения, позволяют вам настроить многие части этого процесса путем переопределения методов. Обязательно требуется написать метод InitMainWindow. Можно переопределить метод InitInsta
nce для инициализации каждого исполняемого экземпляра приложения, и InitApplication для инициализации первого исполняемого экземпляра приложения ObjectWindows.
Инициализация головного окна
Приведем минимальное определение типа объекта приложения:
type
 MyApplication=object(TApplication)
  procedure InitMainWindow; virtual;
 end;
Вы обязательно должны определить метод InitMainWindow, который конструирует и инициализирует объект головного окна и записывает его в поле MainWindow объекта приложения. Приведем пример метода InitMainWindow:
procedure MyApplication.InitMainWindow;
begin
 MainWindow:=New(PWindow, Init(nil, 'The Main Window'));
end;
Этот метод создает новый объект ObjectWindows типа TWindow (PWindow это указатель на тип TWindow). Обычно ваши программы будут определять новый тип окна для его головного окна, и ваша InitMainWindow будет использовать этот новый тип вместо TWindow.
Данное простое приложение ObjectWindows состоит из головной программы и определения типа приложения, которое определяет единственный метод, InitMainWindow. Приведем исходный код этой программы, который будет отличаться от MinimalApp только тем, что его г
оловное окно имеет заголовок:
program TestApp;
uses WObjects;
type
 MyApplication=object(TApplication)
  procedure InitMainWindow; virtual;
 end;
procedure MyApplication.InitMainWindow;
begin
 MainWindow:=New(PWindow, Init(nil, 'The Main Window'));
end;
var
 MyApp: MyApplication;
begin
 MyApp.Init('TestApp');
 MyApp.Run;
 MyApp.Done;
end.
TestApp это минимальное приложение, которое просто отображает окно с заголовком 'The Main Window', как это показано на Рис.8.2. Это окно можно сдвигать и изменять его размеры. Его можно минимизировать до пиктограммы, выбрав пиктограмму со стрелкой вниз в
 правом верхнем углу. Для его восстановления нужно проделать двойное нажатие, указав курсором на пиктограмму. Выбор пиктограммы со стрелкой вверх увеличивает размер окна до размеров всего экрана. Можно закрыть окно и прекратить выполнение приложения, про
делав двойное нажатие в блоке меню управления в верхнем левом углу. TestApp это полнофункциональное приложение, реализующее только простейшее головное окно.
Рис.8.2. Головное окно
Инициализация каждого экземпляра приложения
Пользователь может одновременно исполнять несколько экземпляров одного приложения ObjectWindows. Метод InitInstance инициализирует каждый экземпляр приложения. Он должен только инициализировать каждый экземпляр приложения. Инициализация головного окна пр
оизводится в в InitMainWindow. TApplication определяет метод InitInstance, который вызывает InitMainWindow и отображает головное окно по вызову его метода Show. Вам нужно только переопределить метод InitInstance для изменения стандартной инициализации, н
апример, для загрузки таблицы акселераторов, деятельности, ориентированной на приложение. Если вы переопределяете InitInstance для вашего типа приложения, нужно не забыть первым делом вызвать TApplication.InitInstance.
Приведем метод InitInstance, который будет загружать таблицу акселераторов до начала действительной работы приложения. 100 это постоянный идентификатор таблицы акселераторов, определенной в файле ресурса.
procedure TEditApplication.InitInstance;
begin
 TApplication.InitInstance;
 HAccTable:=LoadAccelerators(HInstance, PChar(100));
end;
Инициализация первого экземпляра приложения
Если пользователь запускает свое приложение несколько раз одновременно (без завершения работы), то вы можете определить некоторую обработку при его первом запуске. Мы будем называть эту обработку инициализацией первого экземпляра. Обратите внимание на то
, что если пользователь запускает свое приложение и прекращает его, а затем запускает снова и т.д., то каждый экземпляр рассматривается как первый.
Если текущий экземпляр будет первым, то будет вызываться его метод InitApplication. TApplication определяет метод InitApplication, который может быть переопределен для выполнения специальной инициализации первого экземпляра.
Например, вы можете изменить TestApp таким образом, чтобы в заголовке головного окна было показано, является ли данный экземпляр первым. Для этого добавим поле булевского объекта FirstApp к типу приложения MyApplication. Затем определим метод InitApplica
tion, который установит FirstApp значение True. Только первый экземпляр приложения будет иметь значение True для FirstApp. И, наконец, модифицируем InitMainWindow для проверки FirstApp и вывода соответствующего заголовка в головном окне приложения, как э
то показано на Рис.8.3.
Рис.8.3. Усовершенствование инициализации приложения
program TestApp;
uses WObjects;
type
MyApplication=object(TApplication)
 FirstApp: Boolean;
 procedure InitMainWindow; virtual;
 procedure InitApplication; virtual;
end;
procedure MyApplication.InitMainWindow;
begin
 if FirstApp then
 MainWindow:=New(PWindow, Init(nil, 'First Instance'))
 else MainWindow:=New(PWindow, Init(nil, 'Additional Instance'));
end;
procedure MyApplication.InitApplication;
begin
 FirstApp:=True;
end;
var
 MyApp: MyApplication;
begin
 MyApp.Init('TestApp');
 MyApp.Run;
 MyApp.Done;
end.
Запуск приложений
Цикл обработки сообщений приложения вызывается при вызове метода Run объекта вашего приложения, который вызывает его метод MessageLoop. При работе вашей программы цикл сообщений обрабатывает поступающие сообщения Windows. Ваши программы ObjectWindows буд
ут наследовать метод MessageLoop, который работает автоматически. Цикл обработки сообщений следует усовершенствовать только для организации специального диалога, акселераторов или обработки MDI.
Метод MessageLoop для обработки сообщений вызывает три метода трансляции. ProcessDlgMsg обрабатывает немодальные диалоги, ProcessAccels обрабатывает акселераторы и ProcessMDIAccels обрабатывает акселераторы для приложений MDI. Для приложений, которые не 
используют акселераторы или немодальные блоки диалога, или которые не являются приложениями MDI вы можете использовать метод MessageLoop непосредственно. Содержание методов трансляции можно найти в разделе, рассматривающем TApplications Главы 5, "Справоч
ного руководства по Windows".
Завершение работы с приложениями
Вызов Done в головной программе вашего приложения уничтожает объект приложения. Однако, до этого ваша программа должна прервать выполнение цикла обработки сообщений. Это может случиться в результате попытки пользователя закрыть головное окно приложения. 
Мы говорим, что это "может" случиться т.к. ObjectWindows предоставляет механизм улучшения завершения работы приложения. Например, до закрытия можно проверить незаписанные файлы.
Когда пользователь пытается закрыть приложение двойным нажатием в блоке меню управления, происходит следующее:
1. Windows посылает сообщение wm_Close в головное окно приложения.
2. Объект головного окна реагирует вызовом метода CanClose объекта    приложения.
3. Метод объекта приложения CanClose вызывает метод CanClose его    головного окна.
4. Головное окно принимает решение о своем закрытии на основании    того, дают ли на это разрешение все дочерние окна. Если все методы CanClose дочерних окон возвращают значение True, то CanClose головного окна также возвращает True и приложение закрывае
тся.
Все объекты окна наследуют метод CanClose, который возвращает True по умолчанию, что является разрешением на закрытие. Поэтому предыдущий вариант TestApp закрывался без каких-либо колебаний. Вы можете переопределить метод CanClose приложения или типа гол
овного окна, придав ему некоторое иное поведение при закрытии. Обычно вы будете изменять поведение при закрытии типа объекта головного окна. Например, можно проверить, записаны ли все файлы.
Этот механизм можно сравнить с объявлением: "Есть ли кто-нибудь против закрытия этого приложения ? Говорите об этом сейчас или сами будете отвечать за последствия." Объекты приложения несут ответственность за санкционирование закрытия приложения. По умол
чанию до предоставления такой санкции проверяется головное окно. Последовательность вызовов соответствующих методов показана на Рис.8.4.
          3. CanClose ?            MS-Windows
     ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї і
     і                              і і
     і                              і і
     і    4. Yes или No             і і 1. wm_Close
     і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДїі і
     і і                           іі і
     і і                           іі і
     объект ДДДДДДДДДДДДДДДДДДДДДД объект головного
     приложения                    окна
        і                              і
        і                              і
        АДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
                    2. CanClose ?
Рис.8.4. Вызов методов при закрытии приложения
Методы CanClose являются булевскими функциями, которые ожидают возвращения значения True, если приложение может закрываться. Обычно усовершенствованный метод CanClose выполняет некоторые операции по расчистке, и если они успешны, то возвращает значение T
rue.
Тип приложения программ ObjectWindows наследует метод CanClose от TApplications, который просто вызывает метод CanClose его объекта головного окна. Если CanClose не переопределен, тип головного окна наследует CanClose от TWindowsObject, который возвращае
т значение True после вызовов методов CanClose его дочерних окон. Для модификации поведения при закрытии вашего головного окна. следует переопределить метод CanClose типа вашего головного окна. Он, например, может проверить открытые файлы, или проверить 
намерения пользователя закрыть окно.



Яндекс цитирования