- •Разработка интегрированных прикладных программ
- •Введение
- •Интерфейсы в Delphi
- •Присоединение интерфейсов к формам
- •Объекты com
- •Контроллер позднего связывания (Delphi)
- •Контроллер на основе библиотеки типов (Delphi)
- •Контоллер на vba
- •Управление офисными приложениями
- •Ms Excel и компоненты библиотеки vcl
- •Работа с ячейками таблицы
- •Серверы ms Office и позднее связывание
- •Работа с серверами из Delphi (позднее связывание)
- •Элементы управления ActiveX
- •Создание ActiveX на основе компонентов vcl
- •Тестирование ActiveX
- •Тестирование с использованием vba
- •Создание активных форм
- •Добавление свойств и методов
- •Динамическое создание элементов управления ActiveX
- •Компонент oleContainer
- •Создание и сохранение нового объекта (внедрение)
- •Создание связанного объекта
- •Работа с сервером
- •Библиографический список
- •Оглавление
Динамическое создание элементов управления ActiveX
Наверное, работая в C++ Builder или Delphi с компонентом ActiveX, естественно поместить его сначала на палитру компонентов, а затем на форму. Однако иногда удобно создавать компоненты динамически, то есть в процессе выполнения программы.
Для примера создадим Windows-приложение и на его форме (Form1) разместим две кнопки (Button1 и Button2) и текстовую метку (Label1). Для размещения управляющего элемента требуется контейнер: экземпляр класса TOleControl. Для доступа к этому классу в код следует вставить строку #include <OleCtrls.hpp> , а затем определить класс-наследник:
class TConX: public ToleControl { protected: TControlData FControlData; virtual void __fastcall InitControlData(void); public: __fastcall TConX(TComponent* AOwner, TWinControl* AParent, TRect Rect); };
В данном классе определен конструктор, метод InitControlData, который требуется переопределить, и область TСontrolData, в которую будут помещены данные о содержимом контейнера. В модуле формы определим указатель на экземпляр класса: TConX *tXObj; Конструктор созданного класса может выглядеть так:
__fastcall TConX::TConX(TComponent* AOwner, TWinControl* AParent,TRect Rect): TOleControl(AOwner) { this->Parent=AParent; this->Visible=True; this->Left=Rect.Left; this->Top=Rect.Top; this->Width=Rect.Right-Rect.Left; this->Height=Rect.Bottom-Rect.Top; }
Метод InitControlData вызывается из конструктора класса-предка (TOleControl), свойство ControlData запоминает адрес структуры с данными (GUID элемента управления ActiveX, ссылки на интерфейсы клиента и т.д.):
void __fastcall TConX::InitControlData(void) { TGUID AD= {0x12DAB429, 0x9BA1, 0x40A4, {0x9A, 0xB8, 0x45,0x51, 0xE9, 0x51,0x9B, 0xFE}}; FControlData.ClassID=AD; FControlData.EventCount=0; FControlData.EventDispIDs=NULL; FControlData.LicenseKey=NULL; FControlData.Flags=0x00000000; ControlData=&FControlData; }
Для примера взят GUID элемента управления, созданного нами ранее на основе активной формы (его CLSID можно найти в файле <имя проекта>_TLB.h).
Обработчик кнопки Button1 отвечает за создание элемента управления:
void __fastcall TForm1::Button1Click(TObject *Sender) { TRect r; r.left=0; r.top=0; r.bottom=200; r.right=400; tXObj=new TConX(this,this,r); }
Результат работы приложения представлен на рис. 6. После инициализации можно обращаться к ActiveX, используя для этого свойство OleObject контейнера. Например, в Button2 получить имя (Caption) элемента управления:
{ if (tXObj!=NULL) { Label1->Caption = "Имя ActiveX: " + tXObj ->OleObject.OlePropertyGet("Caption");}}
Рис. 6
Компонент oleContainer
Технология OLE (Object Linking and Embedding – объектное связывание и встраивание) позволяет создавать сложные составные документы, в которых содержатся разнотипные объекты, созданные различными приложениями. На странице System палитры VCL-компонент есть специальный компонент, предназначенный для внедрения и связывания объектов из других приложений – OLEContainer.
Свойство State позволяет определить состояние объекта и его сервера (osEmpty – контейнер не содержит объекта, osLoaded – объект в контейнере, сервер не выполняется, osRunning – сервер запущен, osOpen – OLE-объект открыт в отдельном окне сервера, osInPlaceActive – объект активизирован «на месте», но меню еще не изменено, osUIActive – объект активизирован «на месте», меню изменено).
Следующий код позволяет определить имя объекта, загруженного в контейнер (свойство OleClassName), способ работы с объектом (Linked = true – связывание), а также получить имя связанного документа:
if (OleContainer1 -> State != osEmpty) { Label1 -> Caption = OleContainer1 -> OleClassName; Label2 -> Caption = OleContainer1 -> State; if ( OleContainer1 -> Linked) Label3 -> Caption = OleContainer1 -> SourceDoc;}
Свойство AllowInPlace определяет возможность редактировать внедренный объект «на месте». Если AllowInPlace = true и Iconic = false, то такое редактирование разрешено.
Свойство AutoActivate имеет три возможных значения: aaManual, aaGetFocus, aaDoubleClick и определяет способы активизации загруженного в контейнер объекта.
По умолчанию AutoActivate = aaDoubleClick, т.е. объект становится активным при двойном щелчке (aaGetFocus – активизация при получении фокуса ввода, aaManual – за активизацию объекта отвечает программист).