При разработке приложения ObjectWindows вам нужно сначала определить объект приложения, производный от типа ObjectWindows TApplication. Этот объект инкапсулирует следующее поведение приложения ObjectWindows:
    Кроме определения объекта приложения вы должны добавить к нему возможность построения объекта основного окна. Вы имеете также возможность переопределения используемого по умолчанию поведения инициализированных экземпляров, закрытия приложения и обработки сообщений Windows.
    Чтобы ваше программа ObjectWindows стала рабочим приложением
Windows, она должна в своем основном блоке begin..end делать
следующее:
    Используемый по умолчанию объект выполняет эти задачи путем
вызова трех его методов: Init, Run и Done. Основной блок любой
программы ObjectWindows содержит обычно эти три метода. Чтобы
изменить поведение по умолчанию, методы нужно переопределить.
    Когда программа выполняется, ObjectWindows поддерживает
глобальную переменную Application - указатель на объект приложения.
Этот указатель позволяет подпрограммам вне объекта приложения
обращаться к его полям и методам. По умолчанию Application
устанавливается в @Self конструктором объекта приложения и в nil
деструктором объекта.
    Приведем пример минимального приложения ObjectWindows:
    MinApp - это абсолютный минимум приложения ObjectWindows.
Эта программа не требует определения других объектов. Обычно вы
определяете новый объектные типы как минимум для приложения и
основного окна.
    Так как в основном блоке программы ObjectWindows каждый раз
используются одни и те же операторы, вы должны понимать, что
делает каждый из них.
    Первый оператор - это вызов конструктора Init приложения.
Этот вызов делает следующее:
    Когда Init завершает работу, основное окно вашего приложения
находится на экране. В большинстве случаев вам нужно только
переопределить InitMainWindow.
    Второй оператор вызывает метод Run приложения, который
реализует работу приложения, вызывая MessageLoop. MessageLoop
обрабатывает сообщения от Windows и выполняет инструкции, которые
управляют работой приложения. MessageLoop - это цикл, который
продолжает работу до закрытия приложения.
    MessageLoop вызывает несколько методов, обрабатывающих
конкретные поступающие сообщения (см. далее).
    Done - это деструктор объекта приложения. Перед завершением
работы приложения он освобождает память объекта приложения.
    Выполнение методов, инициализирующих объект приложения,
позволяет вам настроить части процесса путем переопределения
отдельных методов. Один из методов, требующий переопределения, чтобы
приложения получило конкретный смысл - это InitMainWindow. Вы
моете также переопределить InitInstance и InitApplication.
    Вы должны определить метод InitMainWindow, который строит и
инициализирует объект основного окна и сохраняет его в поле
MainWindow объекта приложения. Ниже показан пример описания
объекта приложения и метода InitMainWindow.
    Данный метод создает новый экземпляр типа TWindow
ObjectWindows (PWindow - это указатель на тип TWindow). Обычно
ваша программа будет определять для своего основного окна новый
оконный тип, а InuitMainWindow будет использовать этот тип
вместо TWindow.
    Примечание: Объекты окон подробно описываются в Главе
10.
    Следующее простое приложение ObjectWindows объединяет в себе
новый тип TMyApplication и старое приложение MinApp. Оно
отличается от MinApp только тем, что основное окно имеет заголовок:
    Программа TestApp выводит окно с заголовком 'Основное окно'.
Вы можете легко перемещать это окно и изменять его размер,
минимизировать его, восстанавливать или максимизировать. Закрытие
окна завершает приложение. Короче, TestApp - это
полнофункциональный "скелет" приложения, оснащенный только простейшим основным
окном.
    Начальный вывод основного окна управляется переменной
CmdShow модуля System. CmdShow содержит одну из констант sw_ и
передается в качестве параметра функции API Windows ShowWindow,
когда приложение создает свое основное окно.
    С помощью CmdShow вы легко можете вывести основное окно в
нормальном виде (по умолчанию), распахнутым до размеров полного
экрана, минимизированным в пиктограмму или скрытым. Лучшим местом
присваивания значения CmdShow является конструктор объекта
основного окна. Это обеспечивает передачу выбранного значения при
создании элемента экрана.
    Если пользователь запускает приложение в отсутствии уже
работающих других экземпляров этого приложения, вы можете
определить для такого первоначального запуска некоторую обработку. Эта
обработка называется инициализацией первого экземпляра. Если
пользователь начинает и завершает ваше приложение, затем
запускает его снова и т.д., каждый экземпляр будет первым экземпляром
(поскольку другие экземпляры в этот момент не выполняются).
    Если текущим экземпляром является первый экземпляр, то
конструктор Init вызывает InitApplication. TApplication определяет
заместитель метода InitApplication, который вы можете для
выполнения специальной инициализации первого экземпляра
переопределить.
    Например, вы можете модифицировать TestApp таким образом,
чтобы о первом экземпляре сообщалось в заголовке основного окна.
Для этого добавьте в тип приложения TMyApplication булевское поле
с именем FirstApp, затем переопределите метод InitApplication,
чтобы он устанавливал FirstApp в True. Наконец, модифицируйте
InitMainWindow для проверки FirstApp и вывода в основном окне
приложения соответствующего заголовка (см. Рис. 8.2).
    Пользователь может одновременно выполнять несколько
экземпляров ObjectWindows. Метод InitInstance инициализирует каждый
экземпляр приложения. Он должен инициализировать только само
приложение, а не его основное окно. Основное окно инициализируйте в
InitMaionWindow.
    InitInstance вызывает InitMainWindow, а затем создает и
выводит основное окно. Для модификации стандартной инициализации
приложения (например, для загрузки таблицы оперативных клавиш)
вам нужно только переопределить InitInstance. Если вы
переопределяете для своего приложения InitInstance, убедитесь сначала, что
он вызывает метод InitInstance, наследуемый из TApplication.
    Приведем метод InitInstance, который перед выполнением
приложения загружает метод InitInstance. 'MeHotKeys' - это
идентификатор ресурса таблицы оперативных клавиш, определенный в файле
ресурса:
    Вы можете также использовать InitInstance для регистрации
экземпляра приложения с внешней DLL (типа Paradox Engine).
    Метод Run вашего приложения вызывает метод MessageLoop,
который вызывает цикл обработки сообщений вашей программы. Во время
выполнения вашей программы в цикле обработки сообщений
обрабатываются поступающие от Windows сообщения. Программы ObjectWindows
наследуют цикл MessageLoop, который работает автоматически.
Дополняйте цикл обработки сообщений только специальными диалогами,
оперативными клавишами или обработкой MDI.
    Метод MessageLoop для обработки сообщений Windows вызывает
три метода. ProcessDlgMsg работает с безрежимными диалоговыми
окнами, ProcessAccels - обрабатывает оперативные клавиши, а
ProcessMDIAccels - оперативные клавиши для приложений MDI. Для
приложений, не использующих командные клавиши или безрежимные
диалоговые окна или не являющихся приложениями MDI MessageLoop
можно несколько упростить. См. методы TApplication в Главе 21.Минимальные требования
Поиск объекта приложения
Минимальное приложение
program MinApp;
uses OWindows;
var
MyApp: TApplication;
begin
MyApp.Init('TtstApp');
MyApp.Run;
MyApp.Done;
end;
Методы Init, Run и Done
Конструктор Init
Метод Run
Деструктор Done
Рис. 8.1 Вызовы методов, управляющие работой приложения.Инициализация приложения
Инициализация основного окна
program TestApp;
uses OWindows;
type
TMyApplication = object(TApplication)
procedure InitMainWindow; virtual;
end;
procedure TMyApplication.InitMainWindow;
begin
MainWindow := New(PWindow, Init(nil, 'Основное окно'));
end;
var
MyApp: TApplication;
begin
MyApp.Init('TestApp');
MyApp.Run;
MyApp.Done;
end;
Специальный вывод основного окна
Инициализация первого экземпляра
Рис. 8.2 Новая инициализация приложения.
program TestApp;
uses OWindows;
type
TMyApplication = object(TApplication)
FirstApp: Boolean;
procedure InitMainWindow; virtual;
procedure InitApplication; virtual;
end;
procedure TMyApplication.InitMainWindow;
begin
if FirstApp then
MainWindow := New(PWindow, Init(nil,
'Первый экземпляр'))
else MainWindow := New(PWindow, Init(nil,
'Дополнительный экземпляр'));
end;
procedure TMyApplication.InitApplication;
begin
FirstApp := True;
end;
var MyApp; TMyApplication;
begin
MyApp.Init('TestApp');
MyApp.Run;
MyApp.Done;
end.
Инициализация каждого экземпляра
procedure TEditApplication.InitInstance;
begin
inherited InitInstance;
HAccTable := LoadAccelerators(HInstance, 'MyHotKeys');
end;
Выполнение приложений