Выбрать главу

07 return app.exec();

08 }

09 return app.exec();

10 }

В функции main() мы проверяем, в каком качестве работает приложение: как автономное приложение или как сервер. Опция командной строки —activex распознается объектом QApplication и обеспечивает работу приложения в качестве сервера. Если приложение не является сервером, мы создаем главный виджет и выводим его на экран, как мы обычно делаем для любого автономного приложения Qt.

Кроме опции —activex серверы ActiveX «понимают» следующие опции командной строки:

—regserver — регистрация сервера в системном реестре;

—unregserver — отмена регистрации сервера в системном реестре;

—dumpidl файл — записывает описание сервера на языке IDL (Interface Description Language — язык описания интерфейсов) в указанный файл.

Когда приложение выполняет функции сервера, нам необходимо экспортировать классы AddressBook и ABItem как компоненты СОМ:

QAXFACTORY_BEGIN("{2b2b6f3e-86cf-4c49-9df5-80483b47f17b}",

"{8e827b25-148b-4307-ba7d-23f275244818}")

QAXCLASS(AddressBook)

QAXTYPE(ABItem)

QAXFACTORY_END()

Приведенные выше макросы экспортируют фабрику классов для создания объектов СОМ. Поскольку мы собираемся экспортировать два типа объектов СОМ, мы не можем просто использовать макрос QAXFACTORY_DEFAULT(), как мы делали в предыдущем примере.

Первым аргументом макроса QAXFACTORY_BEGIN() является идентификатор библиотеки типов; второй аргумент представляет собой идентификатор приложения. Между макросами QAXFACTORY_BEGIN() и QAXFACTORY_END() мы указываем все классы, которые могут быть инстанцированы, и все типы данных, доступные как объекты СОМ.

Ниже приводится файл .pro для внепроцессного сервера ActiveX:

TEMPLATE = app

CONFIG += qaxserver

HEADERS = abitem.h \

addressbook.h \

editdialog.h

SOURCES = abitem.cpp \

addressbook.cpp \

editdialog.cpp \

main.cpp

FORMS = editdialog.ui

RC_FILE = qaxserver.rc

Файл qaxserver.rc, на который имеется ссылка в файле .pro, является стандартным файлом, который может быть скопирован из каталога Qt src\activeqt\control.

Вы можете посмотреть в каталоге примеров vb проект Visual Basic, который использует сервер Address Book.

Этим мы завершаем наш обзор рабочей среды ActiveQt. Дистрибутив Qt включает дополнительные примеры, и в документации содержится информация о способах построения модулей QAxContainer и QAxServer и решения обычных вопросов взаимодействия.

Управление сеансами в системе X11

Когда мы выходим из системы X11, некоторые оконные менеджеры спрашивают нас о необходимости сохранения сеанса. Если мы отвечаем утвердительно, то при следующем входе в систему работа приложений будет автоматически возобновлена с того же экрана и, в идеальном случае, с того же состояния, которое было во время выхода из системы.

Компонент системы X11, который обеспечивает сохранение и восстановление сеанса, называется менеджером сеансов (session manager). Для того чтобы приложение Qt/X11 «осознавало» присутствие менеджера сеансов, мы должны переопределить функцию QApplication::saveState() и сохранить там состояние приложения.

Рис. 20.7. Выход из системы KDE.

Windows 2000 и XP, а также некоторые системы Unix предлагают другой механизм, который носит название «спящих процессов» (hibernation). Когда пользователь останавливает компьютер, операционная система просто выгружает оперативную память компьютера на диск и загружает ее обратно, когда компьютер «просыпается». Приложениям ничего не надо делать, и они даже могут ничего не знать об этом.

Когда пользователь инициирует завершение работы, мы можем перехватить управление непосредственно перед завершением путем переопределения функции QApplication::commitData(). Это позволяет нам сохранять измененные данные и при необходимости вступать в диалог с пользователем. Эта часть схемы управления сеансом поддерживается как в системе X11, так и в Windows.

Мы рассмотрим управление сеансом через программный код приложения Tic-Tac-Toe (крестики-нолики), которое работает под управлением менеджера сеансов. Во-первых, давайте рассмотрим функцию main():

01 int main(int argc, char *argv[])

02 {

03 Application app(argc, argv);

04 TicTacToe toe;

05 toe.setObjectName("toe");

06 app.setTicTacToe(&toe);