МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
«ВОРОНЕЖСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
(ФГБОУ ВПО «ВГТУ»)
Информационных технологий и компьютерной безопасности (факультет)
Кафедра
систем информационной безопасности
КУРСОВАЯ РАБОТА
по дисциплине «Безопасность сетей ЭВМ»
Тема:
«Расширение свойств элементов управления ActiveX средствами ATL»
Воронеж
Введение
Общая характеристика работы
Актуальность
Одна из главных целей СОМ обеспечить производство компонентных программ, т.е приложений, которые собираются из готовых элементов. Создавать работоспособные компоненты можно, используя лишь базовые соглашения, определенные СОМ. Все, что нужно, определить и реализовать интерфейсы, соответствующие назначению данного компонента.
Определение стандартов для программных компонентов и является актуальной задачей спецификации управляющих элементов ActiveX (ActiveX Controls). Путем установления стандартных интерфейсов, способных поддерживать СОМ-объекты для выполнения определенных действий, спецификация управляющих элементов ActiveX предоставляет общую схему построения мощных компонентов. А так как компонентам нужен способ эффективного взаимодействия с использующим их кодом, то спецификация управляющих элементов ActiveX определяет и правила создания контейнеров управляющих элементов (control containers) клиентских программ, знающих как работать с этими элементами.
Так как управляющие элементы ActiveX используются практически во всем программном обеспечении, то изучение и расширение свойств этих элементов становится очень актуальной задачей.
Цель и задачи
Цель данной работы заключает в расширении свойств элементов управления ActiveX средствами ATL.
В достижении поставленной цели нужно решить некоторые задачи:
Изучить управляющие элементы ActiveX;
Изучить технологию ATL;
Создать элемент управления ActiveX средствами ATL;
Расширить свойства созданного элемента ActiveX.
1. Технология ActiveX
Технология ActiveX базируется на технологии Microsoft COM (Component Object Model - модель компонентных объектов), позволяющей создавать и использовать программные компоненты, предоставляющие различные сервисы другим приложениям, компонентам и операционной системе. COM представляет собой одну из реализаций концепции распределенных вычислений, базирующейся в общем случае на предоставлении возможности приложениям использовать для расширения своей функциональности готовые компоненты и объекты (иногда они называются сервисами). Технология COM позволяет использовать объектно-ориентированный подход не в рамках одного приложения, а в рамках операционной системы, но, в отличие от стандартных классов, определенных в исходном тексте и реализуемых как объекты в адресном пространстве одного процесса, эти компоненты могут в общем случае располагаться в адресных пространствах разных процессов и даже на разных компьютерах.
Использование COM, и, в частности, технологии ActiveX, позволяет обеспечить создание приложений, собираемых из готовых компонентов - элементов управления ActiveX, отличающееся от привычной пользователям C++Builder или Delphi разработки приложений с помощью VCL-компонентов тем, что такая "сборка" не зависит от того, на каком языке написаны как готовые компоненты, так и использующее их приложение - лишь бы средство разработки поддерживало возможность использования таких компонентов в разрабатываемом приложении (такое приложение обычно называется контейнером).
Элементы управления ActiveX представляют собой библиотеки, содержащие исполняемый код. Как было сказано выше, эти библиотеки могут быть использованы в различных приложениях как встроенные элементы управления, поэтому они обладают свойствами, событиями и методами, доступными посредством автоматизации. Современные средства разработки, как правило, позволяют включать такие элементы в создаваемые с их помощью приложения. Помимо этого, элементы управления ActiveX нередко используются в качестве расширений web-браузеров с целью придания им дополнительной функциональности, например, для отображения документов, отличных от поддерживаемых данным браузером.
Как любой COM-сервер, элемент управления ActiveX обладает уникальным идентификатором GUID и должен быть зарегистрирован в реестре. На основании этой записи может быть осуществлен поиск местоположения файла с расширением *.ocx, содержащего его реализацию.
Таким образом, создав элемент управления
ActiveX, обладающий интересующей Вас функциональностью, Вы можете в дальнейшем
позволить его пользователям встраивать этот элемент в свои приложения
(например, написанные на Visual Basic, PowerBuilder, Delphi, C++Builder и др.),
отображать его в web-браузере в составе выгруженной с Вашего web-сервера
HTML-страницы, включать его в состав документов MS Office, при этом Вы не
обязаны предоставлять исходный текст этого компонента.
1.1 Технология
Active Template Library (ATL)
Библиотека активных шаблонов (ATL) представляет собой основу для создания небольших СОМ-компонентов. В ATL использованы новые возможности шаблонов, добавленные в C++. Исходные тексты этой библиотеки поставляются в составе системы разработки Visual C++. Кроме того, в эту систему разработки введено множество мастеров Visual C++, что облегчает начальный этап создания ATL-проектов.
Библиотека ATL обеспечивает реализацию ключевых возможностей СОМ компонентов. Выполнения многих рутинных процедур можно избежать за счет использования классов шаблонов ATL. Приведем некоторые функций ATL:
Утилита AppWizard, предназначенная для создания первичного ATL-проекта;
Мастер объектов, используемый для добавления в проект компонентов различных типов;
Поддержка по умолчанию основных интерфейсов COM, таких как IUnknown и IClassFactory;
Поддержка механизма транспортировки пользовательского интерфейса;
Поддержка базового механизма диспетчеризации (автоматизации) и двунаправленного интерфейса;
Существенная поддержка разработки небольших
элементов управления ActiveX.
1.2 Создание полнофункционального
элемента управления АсtivеХ средствами АTL и расширение свойств
Итак, мы узнали, что элемент управления АсtivеХ - это графический объект СОМ, который может иметь набор связанных с ним страниц свойств. Однако важно отметить, что некоторые элементы управления невидимы во время выполнения приложения. При этом они являются графическими "строительными" компонентами во время проектирования.
Элемент управления будет поддерживать точки соединения, свойства и методы, оконные элементы. Кроме того, мы познакомитесь с основами анимации, поскольку наш элемент будет способен прокручивать несколько изображений.
Подготовка рабочего пространства и ресурсов
Создадим новый внутрипроцессный сервер с именем
АхСаrServer с помощью мастера АТL АррWizard, оставив без изменения установки по
умолчанию.
Рисунок 1 - Создание проекта
Рисунок 2 - Свойства проекта
Вставим элемент Full Control, используя мастер
ATL Object Wizard.
Рисунок 3 - Вставка элемента Full Control
На вкладке Names введём АхСаr в поле Short name,
а остальные имена оставим как есть.
Рисунок 4 - Свойства элемента Full Control
На вкладке Miscellaneous отметим флажки
Insertable и Windowed Only (рис. 5). Эти опции позволяют элементу управления
поддерживать свое собственное окно и внедряться в контейнеры документов ОLЕ.
Рисунок 5 - Расширение свойств элемента Full
Control
Наш элемент управления будет демонстрировать анимацию путем отображения нескольких битовых массивов в зависимости от параметров состояния автомобиля.
Используя редактор ресурсов Visual Studio, вставим пять битовых массивов (Insert Resource). Чтобы это осуществить, щелкним на ресурсе битового массива в папке Вitmap панели ResourceView и выберите Рroperties.
Рисунок 6 - Тип ресурса
Рисунок 7 - Элемент анимации №1
Рисунок 8 - Элемент анимации №2
Рисунок 9 - Элемент анимации №3
Рисунок 10 - Элемент анимации №4

В завершении редактирования ресурсов можно
изменить битовый массив, содержащий изображение элемента управления для панели
инструментов, а так же вспомним, что IDE используют это изображение для
представления вашего элемента управления в панели инструментов на этапе
проектирования.
2. Проектирование пользовательского
интерфейса
Учитывая, что элементы управления АсtivеХ могут использоваться клиентами только через интерфейс диспетчеризации, наш элемент управления должен экспортировать все свои функциональные возможности через единственный [default]-интерфейс. Мы добавим в IАхСаr следующие методы: SpeedUp(), CreateCar () И AboutBox (), а также свойства: Animate, Speed, MaxSpeed и PetName.. Идентификаторы DISPID пользовательских элементов могут быть оставлены в своих значениях по умолчанию, однако не забудем установить предопределенное значение DISPID _ABOUTBOX для AboutBox (). Чтобы наиболее полно интегрироваться в контейнер на этапе проектирования, свойство Animate будет использовать специальное перечисление. Вот код IDL
// Специальное перечисление, используемое для анимации
//
[uuid(8FB31CFO-7490-11d3-B92E-0020781238D4), vl_enum]
typedef enum AnimVal
{
[helpstring("Animate")] Yes 1,
[helpstring("Don't Animate")] No 0
} ;
[object, uuid(65AOEEBF-745F-I1D3-B92E-0020781238D4), dual, ("IAxCar Interface"),pointer_default(unique) IAxCar: IDispatch
{
[id (1), helpstring ("Add 10 to current speed")] SpeedUp();
[id(2), helpstring("Set the name and max speed of the car")] CreateCar([in] BSTR petName, [in] short maxSp);
[propget, id(3), helpstring("Should I animate?")] Animate(rout, retval] AnimVal *newVal);
[proPPu1:, id(3), helpstring("Should I animate?")] Animate ([in] AnimVal newVal);
[propget, id(4), helpstring("The max speed")] MaxSpeed([out, retval] short *pVal);
[propput, id (4), helpstring ("The max speed")] MaxSpeed([in] short newVal);
[propget, id(S), helpstring("Car's pet name")] PetName([out, retval] BSTR *pVal);
[propput, id(5), helpstring("Car's pet name")] PetName([in] BSTR newVal);
[propget, id(6}, helpstring("Current speed")] Speed([out, retval] short *pVal};
[propput, id (6), helpstring ("Current speed")] Speed([in] short newVal);
[id(DISPID_ABOUTBOX), helpstring ("About AxCars")]
HRESULT AboutBox();
};
2.1 Реализация пользовательских
свойств
Класс САхСаг для реализации пользовательских свойств требует следующие переменные-члены. Добавим их в закрытый сектор и присвоим значения по умолчанию в конструкторе:
// Закрытые переменные-члены класса СAxCar
//
short rn_maxSpeed; m bstrPetName; m bAnirnate; m_currSpeed;
// Constructor
//()
{ _bWindowOnly = TRUE; _ maxSpeed = 0; _bstrPetName = L""; _currSpeed = 0; _bAnirnate = No;
}
Реализация методов СreateCar() и AboutBox()
Реализация метода CreateCar() также не составляет проблемы: присвоим внутренним переменным значения входящих параметров. Хотя мы демонстрируем каждую переменную как пользовательское свойство, данный метод позволяет клиенту установить состояние при создании элемента управления за один вызов:
// Устанавливаем параметры состояния
//CAxCar::CreateCar(BSTR petName, short rnaxSp)
{ _maxSpeed = rnaxSp; bstrPetName = petName;
return S_OK;
}
Что касается метода AboutBox (), то сначала создадим новый диалоговый ресурс. Мы используем для отображения диалога шаблон CSirnpleDialog<>.
Имея ресурс диалога, реализуем метод AboutBox ():
STDMETHODIMP CAxCar::AboutBox()
{ <IDD_ABOUTBOX> d; .DoModal(); S_OK;
}
Поскольку мы присвоили методу DISPID_ABOUTBOX, конечный пользователь может запустить AboutBox() из IDE.
Сборка [default, source]-интерфейса
Кокласс САхСаr способен генерировать два события для контейнера. Первое событие посылается, когда машина "собирается" взорваться. Второе событие отправляется, когда машина уже взрывается. Добавим нижеследующие методы к нашим [default, source] -интерфейсу диспетчеризации:
[uuid(65AOEECl-745F-IID3-B92E-0020781238D4), ("_IAxCarEvents Interface")] IAxCarEvents
{: :
[id(l), helpstring("rnethod BlewUp")] HRESULT BlewUp();
[id(2}, helpstring("rnethod AboutToBlow")] HRESULT AboutToBlow();
};
Теперь сформируем прокси-класс точек соединения с помощью мастера Inlplenlent Connection Point Wizard после того, как перекомпилируем свой IDL-файл.
BEGIN_CONNECTION_POINT_MAP(CAxCar) _POINT_ENTRY (IID_IPropertyNotifySink) _POINT_ENTRY (DIID__IAxCarEvents)
END_CONNECTION_POINT_MAP()
2.2 Добавление переменных для
управления анимацией
Теперь, когда мы сформировали базовую инфраструктуру СахСаг, сосредоточимся на командах, отвечающих за отображение битовых массивов в цикле анимации. Для начала добавим еще несколько переменных в закрытый сектор нашего класса и определим массив элементов типа HBITMAP для хранения битовых изображений, которые мы нарисовали в первом шаге работы. Также нам нужна переменная, идентифицирующая текущий кадр анимации. Мы собираемся прокручивать от трех до пяти изображений в одном цикле. Если скорость машины существенно ниже максимально допустимой, то отображаем три картинки. Если собираемся взорваться, то четыре. Если уже разлетелись на куски, то рисуем все пять. Определим еще несколько вспомогательных констант. Итак, добавим в заголовочный файл СахСаг следующее:
// Несколько вспомогательных констант
//int MAX IMAGES = 5;
const int MAX NORMAL = 3;int ABOUT TO BLOW = 4;
const int BLOWN UP = 5;
Вот также полный набор закрытых переменных для класса:m_maxSpeed; // Максимальная скорость машиныm bstrPetName; // Имя машиныm_currSpeed; // Текущая скорость машиныm_carlmage[MAX_lMAGES]; // Массив битовых изображений
AnimVal m bAnimate; // Флаг анимации (Yes или No)
short m_currlmage; // Текущее изображение в массивеm_currMaxFrames; // Число кадров в цикле анимации
Теперь заполним массив типов HBITMAP идентификаторами ресурсов битовых изображений. Для корректной работы цикла анимации очень важно, чтобы численные значения идентификаторов ресурсов битовых массивов шли по порядку.
// Файл <resource.h> должен нумеровать ресурсы по порядку
//
#define IDB_LEMON2 202
#define IDB_LEMON3 203
#define IDB_ ALMOSTBLOWNUP 204
#define IDB_ BLOWNUP 205
Переопределим метод FinalConstruct() в классе САхСаг и загрузим изображения с помощью вызова АРI LoadBitmap (). Первый параметр этой функции - HINSTANCE элемента управления, который может быть получен из глобальной переменной CComModule. Мы используем IDB_LEMON1 (идентификатор ресурса первого битового массива) в качестве точки отсчета:
// Загружаем все битовые массивы
//FinalConstruct()
{(int i = 0; i < MAX IGES; i++)
{ _carlmage[i] = LoadBitrnap(_Module.m_hInst, MAKEINTRESOURCE(IDB LEMONl + i));
} S OK;
}
Затем переопределим метод FinalRelease (), чтобы освобождать определители битовых массивов, используя DeleteObject():
// Освобождаем ресурсы
//FinalRelease()
{(int i = 0; i < MAX_IMAGES: i++)
DeleteObject(m_carlmage[i]);
}
Оставшиеся переменные-члены (m_currMaxFrames и m_currImage) могут быть установлены в конструкторе следующим образом:
// Устанавливаем новые параметры состояния
//
САхСаг()
{_bWindowOnly = TRUE;_ maxSpeed = 0;bstrPetName = L'll';_currSpeed = 0;bAnimate = No;_ currImage = 0;currMaxFrarnes MAX NORMAL;
}
2.3 Конфигурирование
таймера